Suggest trait bounds for used associated type on type param
Fix #101351. When an associated type on a type parameter is used, and the type parameter isn't constrained by the correct trait, suggest the appropriate trait bound: ``` error[E0220]: associated type `Associated` not found for `T` --> file.rs:6:15 | 6 | field: T::Associated, | ^^^^^^^^^^ there is a similarly named associated type `Associated` in the trait `Foo` | help: consider restricting type parameter `T` | 5 | struct Generic<T: Foo> { | +++++ ``` When an associated type on a type parameter has a typo, suggest fixing it: ``` error[E0220]: associated type `Baa` not found for `T` --> $DIR/issue-55673.rs:9:8 | LL | T::Baa: std::fmt::Debug, | ^^^ there is a similarly named associated type `Bar` in the trait `Foo` | help: change the associated type name to use `Bar` from `Foo` | LL | T::Bar: std::fmt::Debug, | ~~~ ```
This commit is contained in:
@@ -1061,6 +1061,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
)
|
||||
},
|
||||
param_name,
|
||||
Some(ty_param_def_id),
|
||||
assoc_name,
|
||||
span,
|
||||
None,
|
||||
@@ -1074,6 +1075,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
&self,
|
||||
all_candidates: impl Fn() -> I,
|
||||
ty_param_name: impl Display,
|
||||
ty_param_def_id: Option<LocalDefId>,
|
||||
assoc_name: Ident,
|
||||
span: Span,
|
||||
is_equality: Option<ty::Term<'tcx>>,
|
||||
@@ -1095,6 +1097,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let reported = self.complain_about_assoc_type_not_found(
|
||||
all_candidates,
|
||||
&ty_param_name.to_string(),
|
||||
ty_param_def_id,
|
||||
assoc_name,
|
||||
span,
|
||||
);
|
||||
@@ -1142,30 +1145,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
err.span_label(
|
||||
bound_span,
|
||||
format!(
|
||||
"ambiguous `{}` from `{}`",
|
||||
assoc_name,
|
||||
"ambiguous `{assoc_name}` from `{}`",
|
||||
bound.print_only_trait_path(),
|
||||
),
|
||||
);
|
||||
if let Some(constraint) = &is_equality {
|
||||
where_bounds.push(format!(
|
||||
" T: {trait}::{assoc} = {constraint}",
|
||||
" T: {trait}::{assoc_name} = {constraint}",
|
||||
trait=bound.print_only_trait_path(),
|
||||
assoc=assoc_name,
|
||||
constraint=constraint,
|
||||
));
|
||||
} else {
|
||||
err.span_suggestion_verbose(
|
||||
span.with_hi(assoc_name.span.lo()),
|
||||
"use fully qualified syntax to disambiguate",
|
||||
format!("<{} as {}>::", ty_param_name, bound.print_only_trait_path()),
|
||||
format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
err.note(format!(
|
||||
"associated type `{}` could derive from `{}`",
|
||||
ty_param_name,
|
||||
"associated type `{ty_param_name}` could derive from `{}`",
|
||||
bound.print_only_trait_path(),
|
||||
));
|
||||
}
|
||||
@@ -1173,8 +1172,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
if !where_bounds.is_empty() {
|
||||
err.help(format!(
|
||||
"consider introducing a new type parameter `T` and adding `where` constraints:\
|
||||
\n where\n T: {},\n{}",
|
||||
ty_param_name,
|
||||
\n where\n T: {ty_param_name},\n{}",
|
||||
where_bounds.join(",\n"),
|
||||
));
|
||||
}
|
||||
@@ -1396,6 +1394,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
)
|
||||
},
|
||||
kw::SelfUpper,
|
||||
None,
|
||||
assoc_ident,
|
||||
span,
|
||||
None,
|
||||
|
||||
Reference in New Issue
Block a user