diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index d111008e82c83..c873cf27e42c5 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -164,10 +164,62 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { suggested_name, Applicability::MaybeIncorrect, ); - } else { - err.span_label(span, format!("associated type `{}` not found", assoc_name)); + return err.emit(); } + // If we didn't find a good item in the supertraits (or couldn't get + // the supertraits), like in ItemCtxt, then look more generally from + // all visible traits. If there's one clear winner, just suggest that. + + let visible_traits: Vec<_> = self + .tcx() + .all_traits() + .filter(|trait_def_id| { + let viz = self.tcx().visibility(*trait_def_id); + if let Some(def_id) = self.item_def_id() { + viz.is_accessible_from(def_id, self.tcx()) + } else { + viz.is_visible_locally() + } + }) + .collect(); + + let wider_candidate_names: Vec<_> = visible_traits + .iter() + .flat_map(|trait_def_id| { + self.tcx().associated_items(*trait_def_id).in_definition_order() + }) + .filter_map( + |item| if item.kind == ty::AssocKind::Type { Some(item.name) } else { None }, + ) + .collect(); + + if let (Some(suggested_name), true) = ( + find_best_match_for_name(&wider_candidate_names, assoc_name.name, None), + assoc_name.span != DUMMY_SP, + ) { + if let [best_trait] = visible_traits + .iter() + .filter(|trait_def_id| { + self.tcx() + .associated_items(*trait_def_id) + .filter_by_name_unhygienic(suggested_name) + .any(|item| item.kind == ty::AssocKind::Type) + }) + .collect::>()[..] + { + err.span_label( + assoc_name.span, + format!( + "there is a similarly named associated type `{suggested_name}` in the trait `{}`", + self.tcx().def_path_str(*best_trait) + ), + ); + return err.emit(); + } + } + + err.span_label(span, format!("associated type `{}` not found", assoc_name)); err.emit() } diff --git a/src/test/ui/resolve/issue-55673.rs b/src/test/ui/resolve/issue-55673.rs new file mode 100644 index 0000000000000..0436bd397424c --- /dev/null +++ b/src/test/ui/resolve/issue-55673.rs @@ -0,0 +1,12 @@ +trait Foo { + type Bar; +} + +fn foo() +where + T::Baa: std::fmt::Debug, + //~^ ERROR associated type `Baa` not found for `T` +{ +} + +fn main() {} diff --git a/src/test/ui/resolve/issue-55673.stderr b/src/test/ui/resolve/issue-55673.stderr new file mode 100644 index 0000000000000..39318f959056f --- /dev/null +++ b/src/test/ui/resolve/issue-55673.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Baa` not found for `T` + --> $DIR/issue-55673.rs:7:8 + | +LL | T::Baa: std::fmt::Debug, + | ^^^ there is a similarly named associated type `Bar` in the trait `Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/traits/issue-59029-1.stderr b/src/test/ui/traits/issue-59029-1.stderr index 53cdb8b1baf4c..203a89285306d 100644 --- a/src/test/ui/traits/issue-59029-1.stderr +++ b/src/test/ui/traits/issue-59029-1.stderr @@ -2,13 +2,13 @@ error[E0220]: associated type `Res` not found for `Self` --> $DIR/issue-59029-1.rs:5:52 | LL | trait MkSvc = Svc where Self::Res: Svc; - | ^^^ associated type `Res` not found + | ^^^ there is a similarly named associated type `Res` in the trait `Svc` error[E0220]: associated type `Res` not found for `Self` --> $DIR/issue-59029-1.rs:5:52 | LL | trait MkSvc = Svc where Self::Res: Svc; - | ^^^ associated type `Res` not found + | ^^^ there is a similarly named associated type `Res` in the trait `Svc` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/not_well_formed.stderr b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr index 91c1d031e4e5e..c36b95f47e837 100644 --- a/src/test/ui/type-alias-impl-trait/not_well_formed.stderr +++ b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr @@ -2,7 +2,7 @@ error[E0220]: associated type `Assoc` not found for `V` --> $DIR/not_well_formed.rs:9:29 | LL | type Foo = impl Trait; - | ^^^^^ associated type `Assoc` not found + | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc` error: aborting due to previous error