Skip to content

Avoid 'not found' terminology when there is only one potentially applicable method. #76267

Closed
@Aaron1011

Description

@Aaron1011

The following code:

struct Foo<T>(T);
trait MyTrait {
    fn my_fn(&self) {}
}
impl<T: Copy> MyTrait for Foo<T> {}

fn main() {
    Foo(String::new()).my_fn();
}

gives the following error:

error[E0599]: no method named `my_fn` found for struct `Foo<std::string::String>` in the current scope
   --> src/main.rs:8:24
    |
1   |   struct Foo<T>(T);
    |   -----------------
    |   |
    |   method `my_fn` not found for this
    |   doesn't satisfy `Foo<std::string::String>: MyTrait`
...
8   |       Foo(String::new()).my_fn();
    |                          ^^^^^ method not found in `Foo<std::string::String>`
    |
    = note: the method `my_fn` exists but the following trait bounds were not satisfied:
            `std::string::String: std::marker::Copy`
            which is required by `Foo<std::string::String>: MyTrait`

If we change the call to my_fn() to call some completely nonexistent method (e.g. missing_method()), we get the following error.

   Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `missing_method` found for struct `Foo<std::string::String>` in the current scope
 --> src/main.rs:8:24
  |
1 | struct Foo<T>(T);
  | ----------------- method `missing_method` not found for this
...
8 |     Foo(String::new()).missing_method();
  |                        ^^^^^^^^^^^^^^ method not found in `Foo<std::string::String>`

These two error messages are quite similar - however, they really mean two completely different things. The first error is due to a trait bound error - there's only one in-scope method that the user could possibly be trying to call, but the receiver is not valid. The second error is caused by there being no methods that could even possibly apply - other than suggesting similarly-named methods or additional trait imports, there's really nothing else for the error message to say.

I think using the 'no method found' terminology is the first case is very misleading. It requires the user to read further into the error message to determine if the receiver is invalid, or if they made a typo/tried to call a method that was removed in a newer release of a crate.

I propose that we move the "method foo exists but ..." note to become the main error message. In the case of multiple possibilities, we could say something like "cannot call method foo on base type bar due to ...".

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions