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 should offer suggestions from other implemented traits when methods aren't found #7643

Closed
chris-morgan opened this issue Jul 8, 2013 · 4 comments · Fixed by #21008
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.

Comments

@chris-morgan
Copy link
Member

Explanation of the problem

Here is some sample code:

struct Foo;

impl Foo {
    fn foo(&mut self, buf: &[u8]) {
        self.write(buf);
    }
}

impl std::rt::io::Writer for Foo {
    fn write(&mut self, buf: &[u8]) {
    }

    fn flush(&mut self) {
    }
}

fn main() {
}

Expected (by me) behaviour: code should compile happily.

Actual behaviour: well, here is the compiler's opinion of this code:

foo.rs:5:8: 5:24 error: type `&mut Foo` does not implement any method in scope named `write`
foo.rs:5         self.write(buf);
                 ^~~~~~~~~~~~~~~~
error: aborting due to previous error

First thought: huh? But I implemented that method just there, see?

If I add use std::rt::io::Writer; to the top of the file, it will work. This is, as I now realise, because only traits used in the current scope are searched for a matching method; this is a necessary evil, lest such things as conflicts arise, yet it need not be this evil, where it gives no real indication of the problem (sure, the "in scope" bit hints obliquely at the problem, but not at all clearly).

Now, what should be done

In such a case, where a method is not found in the current scope, the compiler should scan all impl blocks that it knows about for that type and see if it can find any that matches the description, and then suggest them (hopefully it).

For example, the error message might then read

error: type &mut Foo does not implement any method in scope named write; you probably want to use std::rt::io::Writer;

@thestinger
Copy link
Contributor

Triage bump, this still hasn't really been investigated as a way of improving the error messages.

@michaelsproul
Copy link
Contributor

I had a crack at implementing Chris' suggestions as my first journey into the compiler. I failed, but I'm fairly sure the current arguments to check_method_call don't contain enough information to allow suggestions to be made. Someone with better knowledge of the compiler might be able to suggest where we could find the inactive/unimported implementations?

@huonw huonw added A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system labels Jan 9, 2015
@nrc
Copy link
Member

nrc commented Jan 9, 2015

cc me

@nikomatsakis
Copy link
Contributor

yes I've been wanting to do this, I would be happy to mentor.

@nikomatsakis nikomatsakis added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Jan 11, 2015
@huonw huonw self-assigned this Jan 12, 2015
huonw added a commit to huonw/rust that referenced this issue Jan 14, 2015
For a call like `foo.bar()` where the method `bar` can't be resolved,
the compiler will search for traits that have methods with name `bar` to
give a more informative error, providing a list of possibilities.

Closes rust-lang#7643.
bors added a commit that referenced this issue Jan 16, 2015
For a call like `foo.bar()` where the method `bar` can't be resolved,
the compiler will search for traits that have methods with name `bar` to
give a more informative error, providing a list of possibilities.

Closes #7643.
flip1995 pushed a commit to flip1995/rust that referenced this issue Nov 23, 2021
…steffen

New lint `index_refutable_slice` to avoid slice indexing

A new lint to check for slices that could be deconstructed to avoid indexing. This lint should hopefully prevent some panics in other projects and ICEs for us. See rust-lang#7569 for an example

The implementation specifically checks for immutable bindings in `if let` statements to slices and arrays. Then it checks if these bindings are only used for value access using indices and that these indices are lower than the configured limit. I did my best to keep the implementation small, however the check was sadly quite complex. Now it's around 300 lines for the implementation and the rest are test.

---

Optional future improvements:
* Check for these instances also in `match` statements
* Check for mutable slice bindings that could also be destructed

---

changelog: New lint [`index_refutable_slice`]

I've already fixed a bunch of lint triggers in rust-lang#7638 to make this PR smaller

Closes: rust-lang#7569
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-trait-system Area: Trait system E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants