Rollup merge of #99147 - compiler-errors:issue-55673, r=lcnr

Mention similarly named associated type even if it's not clearly in supertrait

Due to query cycle avoidance, we sometimes restrict the candidates in `complain_about_assoc_type_not_found` too much so that we can't detect typo replacements from just supertraits.

This creates a more general note of the existence of a similarly named associated type from _all_ visible traits when possible.

Fixes #55673
This commit is contained in:
Dylan DPC 2022-07-11 15:19:33 +05:30 committed by GitHub
commit 21d6b1fc0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 5 deletions

View File

@ -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::<Vec<_>>()[..]
{
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()
}

View File

@ -0,0 +1,12 @@
trait Foo {
type Bar;
}
fn foo<T: Foo>()
where
T::Baa: std::fmt::Debug,
//~^ ERROR associated type `Baa` not found for `T`
{
}
fn main() {}

View File

@ -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`.

View File

@ -2,13 +2,13 @@ error[E0220]: associated type `Res` not found for `Self`
--> $DIR/issue-59029-1.rs:5:52
|
LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
| ^^^ 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<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
| ^^^ associated type `Res` not found
| ^^^ there is a similarly named associated type `Res` in the trait `Svc`
error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error[E0220]: associated type `Assoc` not found for `V`
--> $DIR/not_well_formed.rs:9:29
|
LL | type Foo<V> = impl Trait<V::Assoc>;
| ^^^^^ associated type `Assoc` not found
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc`
error: aborting due to previous error