Skip to content

Commit f156a05

Browse files
authored
Unrolled build for rust-lang#115662
Rollup merge of rust-lang#115662 - ShE3py:E0220-note, r=compiler-errors Improve "associated type not found" diagnostics ```rs use core::ops::Deref; fn foo<T>() where T: Deref<Output = u32> {} ``` Before: ``` error[E0220]: associated type `Output` not found for `Deref` --> E0220.rs:5:28 | 5 | fn foo<T>() where T: Deref<Output = u32> {} | ^^^^^^ associated type `Output` not found ``` After: ``` error[E0220]: associated type `Output` not found for `Deref` --> E0220.rs:5:28 | 5 | fn foo<T>() where T: Deref<Output = u32> {} | ^^^^^^ help: `Deref` has the following associated type: `Target` ``` --- `@rustbot` label +A-diagnostics +D-papercut
2 parents 62ebe3a + a0e0a32 commit f156a05

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

compiler/rustc_hir_analysis/src/astconv/errors.rs

+36-11
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
110110
{
111111
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
112112
// valid span, so we point at the whole path segment instead.
113-
let span = if assoc_name.span != DUMMY_SP { assoc_name.span } else { span };
113+
let is_dummy = assoc_name.span == DUMMY_SP;
114+
114115
let mut err = struct_span_err!(
115116
self.tcx().sess,
116-
span,
117+
if is_dummy { span } else { assoc_name.span },
117118
E0220,
118119
"associated type `{}` not found for `{}`",
119120
assoc_name,
120121
ty_param_name
121122
);
122123

124+
if is_dummy {
125+
err.span_label(span, format!("associated type `{assoc_name}` not found"));
126+
return err.emit();
127+
}
128+
123129
let all_candidate_names: Vec<_> = all_candidates()
124130
.flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
125131
.filter_map(|item| {
@@ -131,10 +137,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
131137
})
132138
.collect();
133139

134-
if let (Some(suggested_name), true) = (
135-
find_best_match_for_name(&all_candidate_names, assoc_name.name, None),
136-
assoc_name.span != DUMMY_SP,
137-
) {
140+
if let Some(suggested_name) =
141+
find_best_match_for_name(&all_candidate_names, assoc_name.name, None)
142+
{
138143
err.span_suggestion(
139144
assoc_name.span,
140145
"there is an associated type with a similar name",
@@ -172,10 +177,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
172177
})
173178
.collect();
174179

175-
if let (Some(suggested_name), true) = (
176-
find_best_match_for_name(&wider_candidate_names, assoc_name.name, None),
177-
assoc_name.span != DUMMY_SP,
178-
) {
180+
if let Some(suggested_name) =
181+
find_best_match_for_name(&wider_candidate_names, assoc_name.name, None)
182+
{
179183
if let [best_trait] = visible_traits
180184
.iter()
181185
.filter(|trait_def_id| {
@@ -197,7 +201,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
197201
}
198202
}
199203

200-
err.span_label(span, format!("associated type `{assoc_name}` not found"));
204+
// If we still couldn't find any associated type, and only one associated type exists,
205+
// suggests using it.
206+
207+
if all_candidate_names.len() == 1 {
208+
// this should still compile, except on `#![feature(associated_type_defaults)]`
209+
// where it could suggests `type A = Self::A`, thus recursing infinitely
210+
let applicability = if self.tcx().features().associated_type_defaults {
211+
Applicability::Unspecified
212+
} else {
213+
Applicability::MaybeIncorrect
214+
};
215+
216+
err.span_suggestion(
217+
assoc_name.span,
218+
format!("`{ty_param_name}` has the following associated type"),
219+
all_candidate_names.first().unwrap().to_string(),
220+
applicability,
221+
);
222+
} else {
223+
err.span_label(assoc_name.span, format!("associated type `{assoc_name}` not found"));
224+
}
225+
201226
err.emit()
202227
}
203228

tests/ui/associated-types/issue-23595-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0220]: associated type `anything_here_kills_it` not found for `Self`
22
--> $DIR/issue-23595-2.rs:6:22
33
|
44
LL | type B = C<Self::anything_here_kills_it>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^ associated type `anything_here_kills_it` not found
5+
| ^^^^^^^^^^^^^^^^^^^^^^ help: `Self` has the following associated type: `B`
66

77
error: aborting due to previous error
88

tests/ui/error-codes/E0220.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0220]: associated type `F` not found for `Trait`
22
--> $DIR/E0220.rs:5:22
33
|
44
LL | type Foo = dyn Trait<F=i32>;
5-
| ^ associated type `F` not found
5+
| ^ help: `Trait` has the following associated type: `Bar`
66

77
error[E0191]: the value of the associated type `Bar` (from trait `Trait`) must be specified
88
--> $DIR/E0220.rs:5:16

tests/ui/lifetimes/issue-95023.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ error[E0220]: associated type `B` not found for `Self`
3636
--> $DIR/issue-95023.rs:6:44
3737
|
3838
LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
39-
| ^ associated type `B` not found
39+
| ^ help: `Self` has the following associated type: `Output`
4040

4141
error: aborting due to 5 previous errors
4242

0 commit comments

Comments
 (0)