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

Multiple applicable items in scope suggests wrong code for references to trait objects #58988

Open
hcpl opened this issue Mar 7, 2019 · 1 comment
Labels
A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@hcpl
Copy link

hcpl commented Mar 7, 2019

Suggestions from E0034 prepend & to expressions as a string regardless of whether the result type-checks.

Example:

trait Foo { fn baz(&self) -> u8; }
trait Bar { fn baz(&self) -> u64; }
trait Quux: Foo + Bar {}

struct Spam;

impl Foo for Spam { fn baz(&self) -> u8 { 10 } }
impl Bar for Spam { fn baz(&self) -> u64 { 10000 } }
impl Quux for Spam {}

fn main() {
    let quux = &Spam as &dyn Quux;
    quux.baz();
    //Foo::baz(&quux); // what compiler suggests
    //Foo::baz(quux); // correct suggestion
    
    (&Spam as &dyn Quux).baz();
    //Foo::baz(&&Spam as &dyn Quux); // what compiler suggests
    //Foo::baz(&Spam as &dyn Quux); // correct suggestion
}

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=97c044b74af4a3798f01b223ca868bd8.

Errors
error[E0034]: multiple applicable items in scope
  --> src/main.rs:13:10
   |
13 |     quux.baz();
   |          ^^^ multiple `baz` found
   |
note: candidate #1 is defined in the trait `Foo`
  --> src/main.rs:1:13
   |
1  | trait Foo { fn baz(&self) -> u8; }
   |             ^^^^^^^^^^^^^^^^^^^^
   = help: to disambiguate the method call, write `Foo::baz(&quux)` instead
note: candidate #2 is defined in the trait `Bar`
  --> src/main.rs:2:13
   |
2  | trait Bar { fn baz(&self) -> u64; }
   |             ^^^^^^^^^^^^^^^^^^^^^
   = help: to disambiguate the method call, write `Bar::baz(&quux)` instead

error[E0034]: multiple applicable items in scope
  --> src/main.rs:17:26
   |
17 |     (&Spam as &dyn Quux).baz();
   |                          ^^^ multiple `baz` found
   |
note: candidate #1 is defined in the trait `Foo`
  --> src/main.rs:1:13
   |
1  | trait Foo { fn baz(&self) -> u8; }
   |             ^^^^^^^^^^^^^^^^^^^^
   = help: to disambiguate the method call, write `Foo::baz(&&Spam as &Quux)` instead
note: candidate #2 is defined in the trait `Bar`
  --> src/main.rs:2:13
   |
2  | trait Bar { fn baz(&self) -> u64; }
   |             ^^^^^^^^^^^^^^^^^^^^^
   = help: to disambiguate the method call, write `Bar::baz(&&Spam as &Quux)` instead

Notice how in the second case, the suggested code has &&Spam as &Quux instead of &(&Spam as &Quux) which is equivalent to the first case.

Applying suggestions from these errors will produce new errors:

Errors
error[E0277]: the trait bound `&dyn Quux: Foo` is not satisfied
  --> src/main.rs:14:5
   |
14 |     Foo::baz(&quux); // what compiler suggests
   |     ^^^^^^^^ the trait `Foo` is not implemented for `&dyn Quux`
   |
note: required by `Foo::baz`
  --> src/main.rs:1:13
   |
1  | trait Foo { fn baz(&self) -> u8; }
   |             ^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `&Spam: Quux` is not satisfied
  --> src/main.rs:18:14
   |
18 |     Foo::baz(&&Spam as &dyn Quux); // what compiler suggests
   |              --^^^^
   |              |
   |              the trait `Quux` is not implemented for `&Spam`
   |              help: consider removing 1 leading `&`-references
   |
   = help: the following implementations were found:
             <Spam as Quux>
   = note: required for the cast to the object type `dyn Quux`

The same thing happens for mutable references where &mut is prepended instead.

Reproducible on all stable Rust versions back to 1.16.0, beta and nightly.

@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. labels Mar 7, 2019
@haraldh
Copy link
Contributor

haraldh commented Aug 1, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. C-bug Category: This is a bug. 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

3 participants