Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect add bounds suggestion when given type parameter like <T:> #95898

Closed
compiler-errors opened this issue Apr 10, 2022 · 7 comments · Fixed by #95991
Closed

Incorrect add bounds suggestion when given type parameter like <T:> #95898

compiler-errors opened this issue Apr 10, 2022 · 7 comments · Fixed by #95991
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@compiler-errors
Copy link
Member

compiler-errors commented Apr 10, 2022

Given the following code:

fn foo<T:>(t: T) {
    t.clone();
}

The current output is:

error[E0599]: no method named `clone` found for type parameter `T` in the current scope
 --> src/lib.rs:2:7
  |
2 |     t.clone();
  |       ^^^^^ method not found in `T`
  |
  = help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `clone`, perhaps you need to restrict type parameter `T` with it:
  |
1 | fn foo<T: Clone:>(t: T) {
  |        ~~~~~~~~

Ideally the output should look like:

error[E0599]: no method named `clone` found for type parameter `T` in the current scope
 --> src/lib.rs:2:7
  |
2 |     t.clone();
  |       ^^^^^ method not found in `T`
  |
  = help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `clone`, perhaps you need to restrict type parameter `T` with it:
  |
1 | fn foo<T: Clone>(t: T) {
  |          ++++++

Note: The T: bound is treated incorrectly.

@compiler-errors compiler-errors added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels Apr 10, 2022
@PoorlyDefinedBehaviour
Copy link

@rustbot claim

@PoorlyDefinedBehaviour
Copy link

Note: The T: bound is treated incorrectly.

You mean that suggest_traits_to_import does not handle T: correctly, right?

@compiler-errors
Copy link
Member Author

Correct, the suggestion reads T: Clone: which is not syntactical. The fix would be to detect this case and correctly suggest T: Clone

@PoorlyDefinedBehaviour
Copy link

PoorlyDefinedBehaviour commented Apr 12, 2022

It's my first time contributing and i was taking a look at suggest_traits_to_import and didn't find a way to detect T:.

So i ended up adding a flag to GenericParam, setting it in parse_ty_param and checking the flag in suggest_traits_to_import to handle the T: case.

Does that seem reasonable?

@compiler-errors
Copy link
Member Author

Adding a new flag to hir::GenericParam seems a bit heavy. I was thinking you could one of the methods on Span to detect if there is a colon following the generic param.

Also hmm... I think @WaffleLapkin was also looking at trying to solve this... I opened up this issue before he said that he was trying to fix this issue, though I'm not sure if in general or just a specific case in something he was working on (i.e. another suggestion). Perhaps he could comment to see if he's already solved this, in order to deduplicate work?

@WaffleLapkin
Copy link
Member

WaffleLapkin commented Apr 12, 2022

So. I was fixing the same problem in rustc_middle::ty::suggest_constraining_type_params and I just got a working fix!

My solution is to use SourceMap in order to find the span of :. It may be hacky, but I think it's good enough for diagnostics.

It seems like my fix doesn't fix this issue, because this suggestion is created using different API (suggest_traits_to_import), but it should be easy to extend it to this case too. For example suggest_traits_to_import could use suggest_constraining_type_params internally (suggest_constraining_type_params produces better suggestions anyway :D).

I'll try to clean my fix & create a PR today.

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Apr 12, 2022
…s, r=compiler-errors

Fix suggestions in case of `T:` bounds

This PR fixes a corner case in `suggest_constraining_type_params` that was causing incorrect suggestions.

For the following functions:
```rust
fn a<T:>(t: T) { [t, t]; }
fn b<T>(t: T) where T: { [t, t]; }
```

We previously suggested the following:
```text
...
help: consider restricting type parameter `T`
  |
1 | fn a<T: Copy:>(t: T) { [t, t]; }
  |       ++++++
...
help: consider further restricting this bound
  |
2 | fn b<T>(t: T) where T: + Copy { [t, t]; }
  |                        ++++++
```

Note that neither `T: Copy:` not `where T: + Copy` is a correct bound.

With this commit the suggestions are correct:
```text
...
help: consider restricting type parameter `T`
  |
1 | fn a<T: Copy>(t: T) { [t, t]; }
  |         ++++
...
help: consider further restricting this bound
  |
2 | fn b<T>(t: T) where T: Copy { [t, t]; }
  |                        ++++
```

r? `@compiler-errors`

I've tried fixing rust-lang#95898 here too, but got too confused with how `suggest_traits_to_import` works and what it does 😅
@PoorlyDefinedBehaviour
Copy link

PoorlyDefinedBehaviour commented Apr 12, 2022

So. I was fixing the same problem in rustc_middle::ty::suggest_constraining_type_params and I just got a working fix!

My solution is to use SourceMap in order to find the span of :. It may be hacky, but I think it's good enough for diagnostics.

It seems like my fix doesn't fix this issue, because this suggestion is created using different API (suggest_traits_to_import), but it should be easy to extend it to this case too. For example suggest_traits_to_import could use suggest_constraining_type_params internally (suggest_constraining_type_params produces better suggestions anyway :D).

I'll try to clean my fix & create a PR today.

I took a look at your PR, that's way better than my solution.

I will use the method you added to GenericParam to fix this issue if you aren't working on it as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants