Skip to content

Missing field resolve error doesn't look at associated functions #149038

@estebank

Description

@estebank

Code

// https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=0cc9d5eab0906c2323994ad5fa4358e5

struct S;
impl S {
    fn foo() {}
    fn bar(&self) {
        self.foo();
        let f: fn() = self.foo;
    }
}

Current output

error[E0599]: no method named `foo` found for reference `&S` in the current scope
 --> src/lib.rs:5:14
  |
5 |         self.foo();
  |         -----^^^--
  |         |    |
  |         |    this is an associated function, not a method
  |         help: use associated function syntax instead: `S::foo()`
  |
  = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in an impl for the type `S`
 --> src/lib.rs:3:5
  |
3 |     fn foo() {}
  |     ^^^^^^^^

error[E0609]: no field `foo` on type `&S`
 --> src/lib.rs:6:28
  |
6 |         let f: fn() = self.foo;
  |                            ^^^ unknown field

Desired output

error[E0599]: no method named `foo` found for reference `&S` in the current scope
 --> src/lib.rs:5:14
  |
5 |         self.foo();
  |              ^^^ 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: the candidate is defined in an impl for the type `S`
 --> src/lib.rs:3:5
  |
3 |     fn foo() {}
  |     ^^^^^^^^
help: use associated function syntax instead
  --> src/lib.rs:5:14
  |
5 -         self.foo();
5 +         Self::foo();
  |

error[E0609]: no field `foo` on type `&S`
 --> src/lib.rs:6:28
  |
6 |         let f: fn() = self.foo;
  |                            ^^^ 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: the candidate is defined in an impl for the type `S`
 --> src/lib.rs:3:5
  |
3 |     fn foo() {}
  |     ^^^^^^^^
help: use associated function syntax instead
  --> src/lib.rs:5:14
  |
6 -         let f: fn() = self.foo;
6 +         let f: fn() = Self::foo;
  |

Rationale and extra context

The structured suggestion should be verbose instead of inline, to make it clearer what we want the user to write.

The second case doesn't look for associated functions, because the syntax is quite far from what it needs to be, so it never occurred to us that there are cases where it is appropriate to do so. Sadly, this happens during resolve, so we are limited in how much we can explore the expression's context to figure out if an fn pointer is desired to begin with. On the other hand, this can be a two-fold typo, where someone wanted Self::foo() instead of self.foo and forgot the parentheses. The mention of the associated function should be the last fallback for field access resolve error, as it is the least likely thing the user intended.

Other cases

Rust Version

Build using the Nightly version: 1.93.0-nightly

(2025-11-16 518b428304e0008859cb)

Anything else?

Noted by https://social.linux.pizza/@jamesthebard/115566259453362334

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-resolveArea: Name/path resolution done by `rustc_resolve` specificallyD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.P-lowLow priorityT-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