Improve "associated type not found" diagnostics
This commit is contained in:
parent
1e746d7741
commit
96c96645c7
10 changed files with 69 additions and 22 deletions
|
@ -110,16 +110,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
{
|
||||
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
|
||||
// valid span, so we point at the whole path segment instead.
|
||||
let span = if assoc_name.span != DUMMY_SP { assoc_name.span } else { span };
|
||||
let is_dummy = assoc_name.span == DUMMY_SP;
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx().sess,
|
||||
span,
|
||||
if is_dummy { span } else { assoc_name.span },
|
||||
E0220,
|
||||
"associated type `{}` not found for `{}`",
|
||||
assoc_name,
|
||||
ty_param_name
|
||||
);
|
||||
|
||||
if is_dummy {
|
||||
err.span_label(span, format!("associated type `{assoc_name}` not found"));
|
||||
return err.emit();
|
||||
}
|
||||
|
||||
let all_candidate_names: Vec<_> = all_candidates()
|
||||
.flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
|
||||
.filter_map(|item| {
|
||||
|
@ -131,10 +137,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
})
|
||||
.collect();
|
||||
|
||||
if let (Some(suggested_name), true) = (
|
||||
find_best_match_for_name(&all_candidate_names, assoc_name.name, None),
|
||||
assoc_name.span != DUMMY_SP,
|
||||
) {
|
||||
if let Some(suggested_name) =
|
||||
find_best_match_for_name(&all_candidate_names, assoc_name.name, None)
|
||||
{
|
||||
err.span_suggestion(
|
||||
assoc_name.span,
|
||||
"there is an associated type with a similar name",
|
||||
|
@ -172,10 +177,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
})
|
||||
.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 Some(suggested_name) =
|
||||
find_best_match_for_name(&wider_candidate_names, assoc_name.name, None)
|
||||
{
|
||||
if let [best_trait] = visible_traits
|
||||
.iter()
|
||||
.filter(|trait_def_id| {
|
||||
|
@ -197,7 +201,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
}
|
||||
|
||||
err.span_label(span, format!("associated type `{assoc_name}` not found"));
|
||||
// If we still couldn't find any associated type, just list them all.
|
||||
|
||||
if all_candidate_names.is_empty() {
|
||||
err.help(format!(
|
||||
"`{ty_param_name}` has no associated type, try removing `{assoc_name}`"
|
||||
));
|
||||
return err.emit();
|
||||
}
|
||||
|
||||
let msg = if all_candidate_names.len() > 1 {
|
||||
format!("`{ty_param_name}` has the following associated types")
|
||||
} else {
|
||||
format!("`{ty_param_name}` has the following associated type")
|
||||
};
|
||||
|
||||
let applicability = if self.tcx().features().associated_type_defaults {
|
||||
Applicability::Unspecified // `type A = Self::B` would suggest `type A = Self::A`
|
||||
} else {
|
||||
Applicability::MaybeIncorrect
|
||||
};
|
||||
|
||||
err.span_suggestions(
|
||||
assoc_name.span,
|
||||
msg,
|
||||
all_candidate_names.iter().map(|symbol| symbol.to_string()),
|
||||
applicability,
|
||||
);
|
||||
|
||||
err.emit()
|
||||
}
|
||||
|
||||
|
|
|
@ -2,19 +2,25 @@ error[E0220]: associated type `Z` not found for `Foo`
|
|||
--> $DIR/assoc-const-eq-missing.rs:15:16
|
||||
|
|
||||
LL | fn foo1<F: Foo<Z=3>>() {}
|
||||
| ^ associated type `Z` not found
|
||||
| ^
|
||||
|
|
||||
= help: `Foo` has no associated type, try removing `Z`
|
||||
|
||||
error[E0220]: associated type `Z` not found for `Foo`
|
||||
--> $DIR/assoc-const-eq-missing.rs:17:16
|
||||
|
|
||||
LL | fn foo2<F: Foo<Z=usize>>() {}
|
||||
| ^ associated type `Z` not found
|
||||
| ^
|
||||
|
|
||||
= help: `Foo` has no associated type, try removing `Z`
|
||||
|
||||
error[E0220]: associated type `Z` not found for `Foo`
|
||||
--> $DIR/assoc-const-eq-missing.rs:19:16
|
||||
|
|
||||
LL | fn foo3<F: Foo<Z=5>>() {}
|
||||
| ^ associated type `Z` not found
|
||||
| ^
|
||||
|
|
||||
= help: `Foo` has no associated type, try removing `Z`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ error[E0220]: associated type `Item` not found for `M`
|
|||
--> $DIR/missing-trait-bound-for-assoc-fails.rs:4:8
|
||||
|
|
||||
LL | M::Item: Temp,
|
||||
| ^^^^ associated type `Item` not found
|
||||
| ^^^^
|
||||
|
|
||||
= help: `M` has no associated type, try removing `Item`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@ error[E0220]: associated type `A` not found for `T`
|
|||
--> $DIR/associated-types-path-1.rs:10:26
|
||||
|
|
||||
LL | pub fn f1<T>(a: T, x: T::A) {}
|
||||
| ^ associated type `A` not found
|
||||
| ^
|
||||
|
|
||||
= help: `T` has no associated type, try removing `A`
|
||||
|
||||
error[E0221]: ambiguous associated type `A` in bounds of `T`
|
||||
--> $DIR/associated-types-path-1.rs:11:34
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0220]: associated type `anything_here_kills_it` not found for `Self`
|
|||
--> $DIR/issue-23595-2.rs:6:22
|
||||
|
|
||||
LL | type B = C<Self::anything_here_kills_it>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ associated type `anything_here_kills_it` not found
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: `Self` has the following associated type: `B`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0220]: associated type `F` not found for `Trait`
|
|||
--> $DIR/E0220.rs:5:22
|
||||
|
|
||||
LL | type Foo = dyn Trait<F=i32>;
|
||||
| ^ associated type `F` not found
|
||||
| ^ help: `Trait` has the following associated type: `Bar`
|
||||
|
||||
error[E0191]: the value of the associated type `Bar` (from trait `Trait`) must be specified
|
||||
--> $DIR/E0220.rs:5:16
|
||||
|
|
|
@ -19,7 +19,9 @@ error[E0220]: associated type `m` not found for `Trait`
|
|||
--> $DIR/feature-gate-return_type_notation.rs:14:17
|
||||
|
|
||||
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||
| ^ associated type `m` not found
|
||||
| ^
|
||||
|
|
||||
= help: `Trait` has no associated type, try removing `m`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ error[E0220]: associated type `m` not found for `Trait`
|
|||
--> $DIR/feature-gate-return_type_notation.rs:17:17
|
||||
|
|
||||
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||
| ^ associated type `m` not found
|
||||
| ^
|
||||
|
|
||||
= help: `Trait` has no associated type, try removing `m`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ error[E0220]: associated type `m` not found for `Trait`
|
|||
--> $DIR/feature-gate-return_type_notation.rs:17:17
|
||||
|
|
||||
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||
| ^ associated type `m` not found
|
||||
| ^
|
||||
|
|
||||
= help: `Trait` has no associated type, try removing `m`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ error[E0220]: associated type `B` not found for `Self`
|
|||
--> $DIR/issue-95023.rs:6:44
|
||||
|
|
||||
LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
|
||||
| ^ associated type `B` not found
|
||||
| ^ help: `Self` has the following associated type: `Output`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue