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

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

Open
fmease opened this issue Jan 26, 2024 · 1 comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@fmease
Copy link
Member

fmease commented 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>);
     |     ^^^^^^^^^^^^^^^^^^^
  
@fmease fmease added A-diagnostics Area: Messages for errors, warnings, and lints A-associated-items Area: Associated items such as associated types and consts. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. labels Jan 26, 2024
@fmease
Copy link
Member Author

fmease commented Jan 26, 2024

cc @Young-Flash

@fmease fmease changed the title Diagnostics for E0599 suggesting qualified associated function calls don't account for more complex self types Diagnostic hints for E0599 suggesting qualified associated function calls don't account for more complex self types Jan 26, 2024
@fmease fmease added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. and removed D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. labels Jan 26, 2024
@fmease fmease changed the title Diagnostic hints for E0599 suggesting qualified associated function calls don't account for more complex self types Diagnostic hints emitted on unresolved method calls that suggest qualified associated function calls don't account for more complex self types Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. 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

1 participant