Open
Description
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.