Suggest full trait ref (with placeholders) on unresolved assoc tys

This commit is contained in:
León Orell Valerian Liehr 2024-06-15 11:08:12 +02:00
parent 3c8b108512
commit 02a2f02727
No known key found for this signature in database
GPG key ID: D17A07215F68E713
5 changed files with 57 additions and 23 deletions

View file

@ -128,19 +128,20 @@ pub enum AssocItemNotFoundSugg<'a> {
}, },
#[multipart_suggestion( #[multipart_suggestion(
hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg, hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg,
style = "verbose", style = "verbose"
applicability = "maybe-incorrect"
)] )]
SimilarInOtherTraitQPath { SimilarInOtherTraitQPath {
#[suggestion_part(code = "<")] #[suggestion_part(code = "<")]
lo: Span, lo: Span,
#[suggestion_part(code = " as {trait_}>")] #[suggestion_part(code = " as {trait_ref}>")]
mi: Span, mi: Span,
#[suggestion_part(code = "{suggested_name}")] #[suggestion_part(code = "{suggested_name}")]
hi: Option<Span>, hi: Option<Span>,
trait_: &'a str, trait_ref: String,
suggested_name: Symbol, suggested_name: Symbol,
identically_named: bool, identically_named: bool,
#[applicability]
applicability: Applicability,
}, },
#[suggestion( #[suggestion(
hir_analysis_assoc_item_not_found_other_sugg, hir_analysis_assoc_item_not_found_other_sugg,

View file

@ -251,6 +251,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
return self.dcx().emit_err(err); return self.dcx().emit_err(err);
} }
let trait_args = &ty::GenericArgs::identity_for_item(tcx, best_trait)[1..];
let mut trait_ref = trait_name.clone();
let applicability = if let [arg, args @ ..] = trait_args {
use std::fmt::Write;
write!(trait_ref, "</* {arg}").unwrap();
args.iter().try_for_each(|arg| write!(trait_ref, ", {arg}")).unwrap();
trait_ref += " */>";
Applicability::HasPlaceholders
} else {
Applicability::MaybeIncorrect
};
let identically_named = suggested_name == assoc_name.name; let identically_named = suggested_name == assoc_name.name;
if let DefKind::TyAlias = tcx.def_kind(item_def_id) if let DefKind::TyAlias = tcx.def_kind(item_def_id)
@ -260,22 +272,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
lo: ty_param_span.shrink_to_lo(), lo: ty_param_span.shrink_to_lo(),
mi: ty_param_span.shrink_to_hi(), mi: ty_param_span.shrink_to_hi(),
hi: (!identically_named).then_some(assoc_name.span), hi: (!identically_named).then_some(assoc_name.span),
// FIXME(fmease): Use a full trait ref here (with placeholders). trait_ref,
trait_: &trait_name,
identically_named, identically_named,
suggested_name, suggested_name,
applicability,
}); });
} else { } else {
let mut err = self.dcx().create_err(err); let mut err = self.dcx().create_err(err);
if suggest_constraining_type_param( if suggest_constraining_type_param(
tcx, tcx, generics, &mut err, &qself_str, &trait_ref, None, None,
generics,
&mut err,
&qself_str,
// FIXME(fmease): Use a full trait ref here (with placeholders).
&trait_name,
None,
None,
) && !identically_named ) && !identically_named
{ {
// We suggested constraining a type parameter, but the associated item on it // We suggested constraining a type parameter, but the associated item on it

View file

@ -1,5 +1,5 @@
error[E0220]: associated type `Assoc` not found for `T` error[E0220]: associated type `Assoc` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:11:22 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
| |
LL | type AssocOf<T> = T::Assoc; LL | type AssocOf<T> = T::Assoc;
| ^^^^^ there is an associated type `Assoc` in the trait `Trait` | ^^^^^ there is an associated type `Assoc` in the trait `Trait`
@ -10,7 +10,7 @@ LL | type AssocOf<T> = <T as Trait>::Assoc;
| + +++++++++ | + +++++++++
error[E0220]: associated type `Assok` not found for `T` error[E0220]: associated type `Assok` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:15:22 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
| |
LL | type AssokOf<T> = T::Assok; LL | type AssokOf<T> = T::Assok;
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait` | ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
@ -20,6 +20,17 @@ help: consider fully qualifying and renaming the associated type
LL | type AssokOf<T> = <T as Trait>::Assoc; LL | type AssokOf<T> = <T as Trait>::Assoc;
| + +++++++++ ~~~~~ | + +++++++++ ~~~~~
error: aborting due to 2 previous errors error[E0220]: associated type `Proj` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
|
LL | type ProjOf<T> = T::Proj;
| ^^^^ there is an associated type `Proj` in the trait `Parametrized`
|
help: consider fully qualifying the associated type
|
LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj;
| + ++++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0220`. For more information about this error, try `rustc --explain E0220`.

View file

@ -1,5 +1,5 @@
error[E0220]: associated type `Assoc` not found for `T` error[E0220]: associated type `Assoc` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:11:22 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
| |
LL | type AssocOf<T> = T::Assoc; LL | type AssocOf<T> = T::Assoc;
| ^^^^^ there is an associated type `Assoc` in the trait `Trait` | ^^^^^ there is an associated type `Assoc` in the trait `Trait`
@ -10,7 +10,7 @@ LL | type AssocOf<T: Trait> = T::Assoc;
| +++++++ | +++++++
error[E0220]: associated type `Assok` not found for `T` error[E0220]: associated type `Assok` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:15:22 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
| |
LL | type AssokOf<T> = T::Assok; LL | type AssokOf<T> = T::Assok;
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait` | ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
@ -24,6 +24,17 @@ help: ...and changing the associated type name
LL | type AssokOf<T> = T::Assoc; LL | type AssokOf<T> = T::Assoc;
| ~~~~~ | ~~~~~
error: aborting due to 2 previous errors error[E0220]: associated type `Proj` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
|
LL | type ProjOf<T> = T::Proj;
| ^^^^ there is an associated type `Proj` in the trait `Parametrized`
|
help: consider restricting type parameter `T`
|
LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj;
| ++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0220`. For more information about this error, try `rustc --explain E0220`.

View file

@ -4,9 +4,7 @@
//@ revisions: eager lazy //@ revisions: eager lazy
#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))] #![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))]
// FIXME(fmease): Suggest a full trait ref (with placeholders) instead of just a trait name. trait Trait { type Assoc; }
trait Trait<T> { type Assoc; }
type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T` type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T`
//[eager]~^ HELP consider fully qualifying the associated type //[eager]~^ HELP consider fully qualifying the associated type
@ -17,4 +15,12 @@ type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T`
//[lazy]~| HELP consider restricting type parameter `T` //[lazy]~| HELP consider restricting type parameter `T`
//[lazy]~| HELP and changing the associated type name //[lazy]~| HELP and changing the associated type name
trait Parametrized<'a, T, const N: usize> {
type Proj;
}
type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T`
//[eager]~^ HELP consider fully qualifying the associated type
//[lazy]~| HELP consider restricting type parameter `T`
fn main() {} fn main() {}