Skip to content

Commit 21d6b1f

Browse files
authored
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
2 parents 9fc297a + 680fef4 commit 21d6b1f

File tree

5 files changed

+78
-5
lines changed

5 files changed

+78
-5
lines changed

Diff for: compiler/rustc_typeck/src/astconv/errors.rs

+54-2
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,62 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
164164
suggested_name,
165165
Applicability::MaybeIncorrect,
166166
);
167-
} else {
168-
err.span_label(span, format!("associated type `{}` not found", assoc_name));
167+
return err.emit();
169168
}
170169

170+
// If we didn't find a good item in the supertraits (or couldn't get
171+
// the supertraits), like in ItemCtxt, then look more generally from
172+
// all visible traits. If there's one clear winner, just suggest that.
173+
174+
let visible_traits: Vec<_> = self
175+
.tcx()
176+
.all_traits()
177+
.filter(|trait_def_id| {
178+
let viz = self.tcx().visibility(*trait_def_id);
179+
if let Some(def_id) = self.item_def_id() {
180+
viz.is_accessible_from(def_id, self.tcx())
181+
} else {
182+
viz.is_visible_locally()
183+
}
184+
})
185+
.collect();
186+
187+
let wider_candidate_names: Vec<_> = visible_traits
188+
.iter()
189+
.flat_map(|trait_def_id| {
190+
self.tcx().associated_items(*trait_def_id).in_definition_order()
191+
})
192+
.filter_map(
193+
|item| if item.kind == ty::AssocKind::Type { Some(item.name) } else { None },
194+
)
195+
.collect();
196+
197+
if let (Some(suggested_name), true) = (
198+
find_best_match_for_name(&wider_candidate_names, assoc_name.name, None),
199+
assoc_name.span != DUMMY_SP,
200+
) {
201+
if let [best_trait] = visible_traits
202+
.iter()
203+
.filter(|trait_def_id| {
204+
self.tcx()
205+
.associated_items(*trait_def_id)
206+
.filter_by_name_unhygienic(suggested_name)
207+
.any(|item| item.kind == ty::AssocKind::Type)
208+
})
209+
.collect::<Vec<_>>()[..]
210+
{
211+
err.span_label(
212+
assoc_name.span,
213+
format!(
214+
"there is a similarly named associated type `{suggested_name}` in the trait `{}`",
215+
self.tcx().def_path_str(*best_trait)
216+
),
217+
);
218+
return err.emit();
219+
}
220+
}
221+
222+
err.span_label(span, format!("associated type `{}` not found", assoc_name));
171223
err.emit()
172224
}
173225

Diff for: src/test/ui/resolve/issue-55673.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
trait Foo {
2+
type Bar;
3+
}
4+
5+
fn foo<T: Foo>()
6+
where
7+
T::Baa: std::fmt::Debug,
8+
//~^ ERROR associated type `Baa` not found for `T`
9+
{
10+
}
11+
12+
fn main() {}

Diff for: src/test/ui/resolve/issue-55673.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0220]: associated type `Baa` not found for `T`
2+
--> $DIR/issue-55673.rs:7:8
3+
|
4+
LL | T::Baa: std::fmt::Debug,
5+
| ^^^ there is a similarly named associated type `Bar` in the trait `Foo`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0220`.

Diff for: src/test/ui/traits/issue-59029-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0220]: associated type `Res` not found for `Self`
22
--> $DIR/issue-59029-1.rs:5:52
33
|
44
LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
5-
| ^^^ associated type `Res` not found
5+
| ^^^ there is a similarly named associated type `Res` in the trait `Svc`
66

77
error[E0220]: associated type `Res` not found for `Self`
88
--> $DIR/issue-59029-1.rs:5:52
99
|
1010
LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
11-
| ^^^ associated type `Res` not found
11+
| ^^^ there is a similarly named associated type `Res` in the trait `Svc`
1212

1313
error: aborting due to 2 previous errors
1414

Diff for: src/test/ui/type-alias-impl-trait/not_well_formed.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0220]: associated type `Assoc` not found for `V`
22
--> $DIR/not_well_formed.rs:9:29
33
|
44
LL | type Foo<V> = impl Trait<V::Assoc>;
5-
| ^^^^^ associated type `Assoc` not found
5+
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc`
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)