Skip to content

Commit

Permalink
Rollup merge of #99147 - compiler-errors:issue-55673, r=lcnr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Dylan-DPC authored Jul 11, 2022
2 parents fa5b776 + 680fef4 commit 96c969c
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 5 deletions.
56 changes: 54 additions & 2 deletions compiler/rustc_typeck/src/astconv/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/resolve/issue-55673.rs
Original file line number Diff line number Diff line change
@@ -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() {}
9 changes: 9 additions & 0 deletions src/test/ui/resolve/issue-55673.stderr
Original file line number Diff line number Diff line change
@@ -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`.
4 changes: 2 additions & 2 deletions src/test/ui/traits/issue-59029-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/type-alias-impl-trait/not_well_formed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 96c969c

Please sign in to comment.