From 98a157aec8b08729249aa9ca78f9703aa3a4f279 Mon Sep 17 00:00:00 2001 From: zakrad <49591476+zakrad@users.noreply.github.com> Date: Mon, 31 Aug 2026 13:21:07 +0330 Subject: [PATCH 1/2] Add test for the fn item uniqueness note with late bound lifetimes --- .../fn/fn-item-type-note-late-bound-145558.rs | 19 ++++++++++++++++++ ...fn-item-type-note-late-bound-145558.stderr | 20 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/ui/fn/fn-item-type-note-late-bound-145558.rs create mode 100644 tests/ui/fn/fn-item-type-note-late-bound-145558.stderr diff --git a/tests/ui/fn/fn-item-type-note-late-bound-145558.rs b/tests/ui/fn/fn-item-type-note-late-bound-145558.rs new file mode 100644 index 0000000000000..2463e2ba70675 --- /dev/null +++ b/tests/ui/fn/fn-item-type-note-late-bound-145558.rs @@ -0,0 +1,19 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/145558 +//! +//! The note explaining that distinct fn items have distinct types was suppressed when the +//! signatures contained a late-bound lifetime, because the two binders name their bound +//! region differently. + +//@ dont-require-annotations: NOTE + +struct A; + +fn f1<'a>(_: &'a A) {} +fn f2<'a>(_: &'a A) {} + +fn main() { + let mut map = vec![]; + map.push(f1); + map.push(f2); + //~^ ERROR mismatched types +} diff --git a/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr b/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr new file mode 100644 index 0000000000000..31d773c7e4a79 --- /dev/null +++ b/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/fn-item-type-note-late-bound-145558.rs:17:14 + | +LL | map.push(f1); + | --- -- this argument has type `for<'a> fn(&'a A) {f1}`... + | | + | ... which causes `map` to have type `Vec fn(&'a A) {f1}>` +LL | 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 + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 21228c2dfa1a8afda35130d0fd59979ed6c34937 Mon Sep 17 00:00:00 2001 From: zakrad <49591476+zakrad@users.noreply.github.com> Date: Mon, 31 Aug 2026 13:23:02 +0330 Subject: [PATCH 2/2] Do not suppress the fn item uniqueness note for late bound lifetimes --- .../src/error_reporting/infer/suggest.rs | 4 +++- tests/ui/fn/fn-item-type-note-late-bound-145558.rs | 1 + tests/ui/fn/fn-item-type-note-late-bound-145558.stderr | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index db852701051cf..577571196a239 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -521,7 +521,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let found_sig = self.normalize_fn_sig(self.tcx.fn_sig(*did2).instantiate(self.tcx, args2)); - if self.same_type_modulo_infer(expected_sig, found_sig) { + let expected_sig_anon = self.tcx.anonymize_bound_vars(expected_sig); + let found_sig_anon = self.tcx.anonymize_bound_vars(found_sig); + if self.same_type_modulo_infer(expected_sig_anon, found_sig_anon) { diag.subdiagnostic(FnUniqTypes); } diff --git a/tests/ui/fn/fn-item-type-note-late-bound-145558.rs b/tests/ui/fn/fn-item-type-note-late-bound-145558.rs index 2463e2ba70675..3e8fc0e8b14a7 100644 --- a/tests/ui/fn/fn-item-type-note-late-bound-145558.rs +++ b/tests/ui/fn/fn-item-type-note-late-bound-145558.rs @@ -16,4 +16,5 @@ fn main() { map.push(f1); map.push(f2); //~^ ERROR mismatched types + //~| NOTE different fn items have unique types } diff --git a/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr b/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr index 31d773c7e4a79..bf0a1c3316e57 100644 --- a/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr +++ b/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr @@ -12,6 +12,7 @@ LL | map.push(f2); | = 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 --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL