Skip to content

Lifetimes on functions suppress helpful "different fn items have unique types, even if their signatures are the same" note #145558

@jieyouxu

Description

@jieyouxu

Code

struct A;

fn f1<'a>(_: &'a A) {}       // Case 1
fn f2<'a>(_: &'a A) {}       // Case 1
// fn f1(_: A) {}            // Case 2
// fn f2(_: A) {}            // Case 2

fn main() {
    let mut map = vec![];
    map.push(f1);
    map.push(f2);
}

Current output

error[E0308]: mismatched types
 --> foo.rs:9:14
  |
8 |     map.push(f1);
  |     ---      -- this argument has type `for<'a> fn(&'a A) {f1}`...
  |     |
  |     ... which causes `map` to have type `Vec<for<'a> fn(&'a A) {f1}>`
9 |     map.push(f2);
  |         ---- ^^ expected fn item, found a different fn item
  |         |
  |         arguments to this method are incorrect
  |
  = note: expected fn item `for<'a> fn(&'a A) {f1}`
             found fn item `for<'a> fn(&'a A) {f2}`
note: method defined here
 --> /rustc/425a9c0a0e365c0b8c6cfd00c2ded83a73bed9a0/library/alloc/src/vec/mod.rs:2571:12

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.

Desired output

error[E0308]: mismatched types
 --> foo.rs:9:14
  |
8 |     map.push(f1);
  |     ---      -- this argument has type `for<'a> fn(&'a A) {f1}`...
  |     |
  |     ... which causes `map` to have type `Vec<for<'a> fn(&'a A) {f1}>`
9 |     map.push(f2);
  |         ---- ^^ expected fn item, found a different fn item
  |         |
  |         arguments to this method are incorrect
  |
  = note: expected fn item `for<'a> fn(&'a A) {f1}`
             found fn item `for<'a> fn(&'a A) {f2}`
  = note: different fn items have unique types, even if their signatures are the same
note: method defined here
 --> /rustc/425a9c0a0e365c0b8c6cfd00c2ded83a73bed9a0/library/alloc/src/vec/mod.rs:2571:12

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.

Rationale and extra context

It's not immediately obviously why the seemingly identical types

     = note: expected fn item `for<'a> fn(&'a A) {f1}`
                found fn item `for<'a> fn(&'a A) {f2}`

would still lead to a type mismatch. When there are no lifetimes, i.e. with case 2, the helpful

  = note: different fn items have unique types, even if their signatures are the same

note is shown.

Other cases

Rust Version

rustc 1.91.0-nightly (425a9c0a0 2025-08-17)
binary: rustc
commit-hash: 425a9c0a0e365c0b8c6cfd00c2ded83a73bed9a0
commit-date: 2025-08-17
host: aarch64-apple-darwin
release: 1.91.0-nightly
LLVM version: 21.1.0

Anything else?

cf. discussions in https://users.rust-lang.org/t/hashmap-of-string-fn/25071/8

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.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