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 new file mode 100644 index 0000000000000..3e8fc0e8b14a7 --- /dev/null +++ b/tests/ui/fn/fn-item-type-note-late-bound-145558.rs @@ -0,0 +1,20 @@ +//! 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 + //~| 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 new file mode 100644 index 0000000000000..bf0a1c3316e57 --- /dev/null +++ b/tests/ui/fn/fn-item-type-note-late-bound-145558.stderr @@ -0,0 +1,21 @@ +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: 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 + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.