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

Compiler doesn't suggest missing method that is implemented for different type parameter #51518

Open
hannobraun opened this issue Jun 12, 2018 · 2 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@hannobraun
Copy link

Consider the following API that allows us to control some piece of hardware, while providing some compile-time guarantees by tracking the hardware state as a type parameter:

pub struct Hardware<State>(State);

impl Hardware<Disabled> {
    pub fn new() -> Self {
        Hardware(Disabled)
    }

    pub fn enable(self) -> Hardware<Enabled> {
        Hardware(Enabled)
    }
}

impl Hardware<Enabled> {
    pub fn do_stuff(&mut self) {}
}


pub struct Enabled;
pub struct Disabled;

Hardware is created in the Disabled state and needs to be enabled before anything can be done with it.

The following piece of code tries to do_stuff without enableing first:

let hw = Hardware::new();
hw.do_stuff();

It fails with the following error message:

error[E0599]: no method named `do_stuff` found for type `Hardware<Disabled>` in the current scope
  --> src/main.rs:24:8
   |
1  | pub struct Hardware<State>(State);
   | ---------------------------------- method `do_stuff` not found for this
...
24 |     hw.do_stuff();
   |        ^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.

I think this error message is misleading, as the method does exist. It's just not available with this specific type parameter. This could be highly confusing to someone who isn't used to this kind of API.

I believe that the compiler should suggest the method, and note that it would be available, if the type parameter were different. Similarly to how it would suggest a trait method for a trait that isn't imported into the current scope. Ideally, I would like the compiler to suggest calling the enable method, as that would put the API into a state that would allow do_stuff to be called.

I'm aware that method suggestions like this were removed some time ago (issue, PR). Adding an attribute to mark function that should be suggested for state transitions like this has been suggested before (@zackmdavis seemed interested in working on this). From my perspective as an API author, such an attribute would be an excellent way to improve the user experience when using APIs like this.

cc @oli-obk (We talked about this at RustFest. Sorry for taking so long to open this issue.)

@estebank estebank added the A-diagnostics Area: Messages for errors, warnings, and lints label Jun 12, 2018
@zackmdavis
Copy link
Member

I'm aware that method suggestions like this were removed some time ago (issue, PR).

That was specifically about method suggestions for type mismatches; the argument for using a special (compiler internal) attribute for marking which methods were acceptable suggestions was that too many of the candidate suggestions were bogus. I don't think we need to be thinking about attributes to implement this.

@JohnTitor JohnTitor added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 10, 2019
@estebank
Copy link
Contributor

estebank commented Aug 3, 2023

Current output:

error[E0599]: no method named `do_stuff` found for struct `Hardware<Disabled>` in the current scope
  --> src/main.rs:25:8
   |
3  | pub struct Hardware<State>(State);
   | -------------------------- method `do_stuff` not found for this struct
...
25 |     hw.do_stuff();
   |        ^^^^^^^^ method not found in `Hardware<Disabled>`
   |
   = note: the method was found for
           - `Hardware<Enabled>`

I think that looking at "this method was found for this type" and seeing if there's any method that can get you that type, but the current output does give you a fighting chance to figure the problem out.

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 C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants