Diagnostic hints emitted on unresolved method calls that suggest qualified associated function calls don't account for more complex self types #120379
Open
Description
opened on Jan 26, 2024
Uplifted from #118911 (comment) and further noticed while reviewing #119957.
With “more complex self types” I mean self types like Box<Self>
, Rc<Self>
etc. & feature(arbitrary_self_types)
, basically anything other than Self
, &&...Self
and &mut &mut... Self
.
Given:
struct S;
trait TraitA { fn f(this: Box<Self>); }
trait TraitB { fn f(this: Box<Self>); }
impl TraitA for S { fn f(this: Box<Self>) {} }
impl TraitB for S { fn f(this: Box<Self>) {} }
fn main() {
Box::new(S).f(); //~ ERROR no method named `f` found for struct `Box<S>` in the current scope [E0599]
}
We currently output:
error[E0599]: no method named `f` found for struct `Box<S>` in the current scope
--> src/main.rs:10:17
|
10 | Box::new(S).f();
| ^ this is an associated function, not a method
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: candidate #1 is defined in the trait `TraitA`
--> src/main.rs:3:16
|
3 | trait TraitA { fn f(this: Box<Self>); }
| ^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `TraitB`
--> src/main.rs:4:16
|
4 | trait TraitB { fn f(this: Box<Self>); }
| ^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the associated function for candidate #1
|
10 | <Box<S> as TraitA>::f(Box::new(S));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the associated function for candidate #2
|
10 | <Box<S> as TraitB>::f(Box::new(S));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
However, <Box<S> as $Trait>::f(Box::new(S))
is not correct ($Trait
∊ {TraitA
, TraitB
}).
We should either suggest
help: disambiguate the associated function for candidate #1
|
- 10 | <Box<S> as TraitA>::f(Box::new(S));
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 10 | TraitA::f(Box::new(S));
+ | ~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the associated function for candidate #2
|
- 10 | <Box<S> as TraitB>::f(Box::new(S));
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 10 | TraitB::f(Box::new(S));
+ | ~~~~~~~~~~~~~~~~~~~~~~
or
help: disambiguate the associated function for candidate #1
|
- 10 | <Box<S> as TraitA>::f(Box::new(S));
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 10 | <S as TraitA>::f(Box::new(S));
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the associated function for candidate #2
|
- 10 | <Box<S> as TraitB>::f(Box::new(S));
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 10 | <S as TraitB>::f(Box::new(S));
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given:
struct A;
trait M {
fn f(_: Box<Self>);
}
impl M for A {
fn f(_: Box<Self>) {}
}
fn main() {
Box::new(A).f(); //~ ERROR no method named `f` found for struct `Box<A>` in the current scope [E0599]
}
We should output the following:
error[E0599]: no method named `f` found for struct `Box<A>` in the current scope
--> src/main.rs:12:17
|
12 | Box::new(A).f();
| ------------^--
| | |
| | this is an associated function, not a method
- | help: use associated function syntax instead: `Box<A>::f()`
+ | help: use associated function syntax instead: `A::f(Box::new(A))`
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `M`
--> src/main.rs:4:5
|
4 | fn f(_: Box<Self>);
| ^^^^^^^^^^^^^^^^^^^
Metadata
Assignees
Labels
Area: Associated items (types, constants & functions)Area: Messages for errors, warnings, and lintsArea: Suggestions generated by the compiler applied by `cargo fix`Diagnostics: A structured suggestion resulting in incorrect code.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity