Skip to content

Diagnostic hints emitted on unresolved method calls that suggest qualified associated function calls don't account for more complex self types #120379

Open
@fmease

Description

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>);
     |     ^^^^^^^^^^^^^^^^^^^
  

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions