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

Elide generic arguments in "no method found" errors if they're irrelevant #81576

Closed
scottmcm opened this issue Jan 31, 2021 · 5 comments · Fixed by #84221
Closed

Elide generic arguments in "no method found" errors if they're irrelevant #81576

scottmcm opened this issue Jan 31, 2021 · 5 comments · Fixed by #84221
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-papercut Diagnostics: An error or lint that needs small tweaks. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@scottmcm
Copy link
Member

scottmcm commented Jan 31, 2021

Inspired by this question on discord:

no method named extend found for struct Map<std::iter::Chain<Map<Windows<'_, Point>, [closure@src\graphics\slider.rs:39:22: 47:18]>, std::iter::Once<Point>>, [closure@src\graphics\slider.rs:49:22: 49:60]> in the current scope

how does map not have .extend

Repro: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e270ca9a0ae009a8f34af6bc31c0ce90

fn main() {
    let v = vec![1_i32, 2, 3];
    v.iter().map(|x| x * x).extend(std::iter::once(100));
}

Error:

error[E0599]: no method named `extend` found for struct `Map<std::slice::Iter<'_, i32>, [closure@src/main.rs:3:18: 3:27]>` in the current scope
 --> src/main.rs:3:29
  |
3 |     v.iter().map(|x| x * x).extend(std::iter::once(100));
  |                             ^^^^^^ method not found in `Map<std::slice::Iter<'_, i32>, [closure@src/main.rs:3:18: 3:27]>`

It would be nice if rustc could notice that Map<T> never has extend for any T, and use that information to simplify the error message to just

error[E0599]: no method named `extend` found for struct `Map<_>` in the current scope

in order to focus the user better on the relevant part.

Can the name resolution engine do that? (It can for a generic parameter, of course, but then it's only looking at the known trait bounds, which is a little different.)

@henryboisdequin
Copy link
Contributor

@rustbot label +A-diagnostics +D-papercut +T-compiler

@rustbot rustbot added A-diagnostics Area: Messages for errors, warnings, and lints D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 31, 2021
@camelid
Copy link
Member

camelid commented Feb 1, 2021

Can the name resolution engine do that?

Not sure, but I bet it's hard. How can you know what traits are implemented before you've run trait-resolution/typeck/etc.?

@rustbot label: E-hard

@rustbot rustbot added the E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. label Feb 1, 2021
@Aaron1011
Copy link
Member

Aaron1011 commented Feb 1, 2021

Method resolution occurs during typecheck (and involves trait resolution), so this might not be that difficult.

@camelid
Copy link
Member

camelid commented Feb 3, 2021

Method resolution occurs during typecheck (and involves trait resolution), so this might not be that difficult.

Ah, I forget that methods have to be resolved during typeck. Yeah, might not be as hard as I thought: @rustbot label: +E-medium -E-hard

@rustbot rustbot added E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. and removed E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. labels Feb 3, 2021
@ABouttefeux
Copy link
Contributor

@rustbot claim

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 26, 2021
…estebank

E0599 suggestions and elision of generic argument if no canditate is found

fixes rust-lang#81576
changes: In error E0599 (method not found) generic argument are eluded if the method was not found anywhere. If the method was found in another inherent implementation suggest that it was found elsewhere.

Example
```rust

struct Wrapper<T>(T);

struct Wrapper2<T> {
    x: T,
}

impl Wrapper2<i8> {
    fn method(&self) {}
}

fn main() {
    let wrapper = Wrapper(i32);
    wrapper.method();
    let wrapper2 = Wrapper2{x: i32};
    wrapper2.method();
}
```

```
Error[E0599]: no method named `method` found for struct `Wrapper<_>` in the current scope
....
error[E0599]: no method named `method` found for struct `Wrapper2<i32>` in the current scope
...
   = note: The method was found for Wrapper2<i8>.

```
I am not very happy with the ```no method named `test` found for struct `Vec<_, _>` in the current scope```. I think it might be better to show only one generic argument `Vec<_>` if there is a default one. But I haven't yet found a way to do that,
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 27, 2021
…estebank

E0599 suggestions and elision of generic argument if no canditate is found

fixes rust-lang#81576
changes: In error E0599 (method not found) generic argument are eluded if the method was not found anywhere. If the method was found in another inherent implementation suggest that it was found elsewhere.

Example
```rust

struct Wrapper<T>(T);

struct Wrapper2<T> {
    x: T,
}

impl Wrapper2<i8> {
    fn method(&self) {}
}

fn main() {
    let wrapper = Wrapper(i32);
    wrapper.method();
    let wrapper2 = Wrapper2{x: i32};
    wrapper2.method();
}
```

```
Error[E0599]: no method named `method` found for struct `Wrapper<_>` in the current scope
....
error[E0599]: no method named `method` found for struct `Wrapper2<i32>` in the current scope
...
   = note: The method was found for Wrapper2<i8>.

```
I am not very happy with the ```no method named `test` found for struct `Vec<_, _>` in the current scope```. I think it might be better to show only one generic argument `Vec<_>` if there is a default one. But I haven't yet found a way to do that,
@bors bors closed this as completed in f2810d5 May 27, 2021
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 D-papercut Diagnostics: An error or lint that needs small tweaks. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. 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.

6 participants