diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 90861ba1ff8..c364a561631 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -128,19 +128,20 @@ pub enum AssocItemNotFoundSugg<'a> { }, #[multipart_suggestion( hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg, - style = "verbose", - applicability = "maybe-incorrect" + style = "verbose" )] SimilarInOtherTraitQPath { #[suggestion_part(code = "<")] lo: Span, - #[suggestion_part(code = " as {trait_}>")] + #[suggestion_part(code = " as {trait_ref}>")] mi: Span, #[suggestion_part(code = "{suggested_name}")] hi: Option, - trait_: &'a str, + trait_ref: String, suggested_name: Symbol, identically_named: bool, + #[applicability] + applicability: Applicability, }, #[suggestion( hir_analysis_assoc_item_not_found_other_sugg, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index fd2bbabe779..56f508a2d43 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -251,6 +251,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 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, ""; + Applicability::HasPlaceholders + } else { + Applicability::MaybeIncorrect + }; + let identically_named = suggested_name == assoc_name.name; 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(), mi: ty_param_span.shrink_to_hi(), hi: (!identically_named).then_some(assoc_name.span), - // FIXME(fmease): Use a full trait ref here (with placeholders). - trait_: &trait_name, + trait_ref, identically_named, suggested_name, + applicability, }); } else { let mut err = self.dcx().create_err(err); if suggest_constraining_type_param( - tcx, - generics, - &mut err, - &qself_str, - // FIXME(fmease): Use a full trait ref here (with placeholders). - &trait_name, - None, - None, + tcx, generics, &mut err, &qself_str, &trait_ref, None, None, ) && !identically_named { // We suggested constraining a type parameter, but the associated item on it diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr index 8e6490c548d..e891ff10fda 100644 --- a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr @@ -1,5 +1,5 @@ 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::Assoc; | ^^^^^ there is an associated type `Assoc` in the trait `Trait` @@ -10,7 +10,7 @@ LL | type AssocOf = ::Assoc; | + +++++++++ 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::Assok; | ^^^^^ 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 = ::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::Proj; + | ^^^^ there is an associated type `Proj` in the trait `Parametrized` + | +help: consider fully qualifying the associated type + | +LL | type ProjOf = >::Proj; + | + ++++++++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr index 051f181cb6f..96179a7b484 100644 --- a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr @@ -1,5 +1,5 @@ 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::Assoc; | ^^^^^ there is an associated type `Assoc` in the trait `Trait` @@ -10,7 +10,7 @@ LL | type AssocOf = T::Assoc; | +++++++ 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::Assok; | ^^^^^ 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::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::Proj; + | ^^^^ there is an associated type `Proj` in the trait `Parametrized` + | +help: consider restricting type parameter `T` + | +LL | type ProjOf> = T::Proj; + | ++++++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs index 75e4eb496b4..2c8d448f308 100644 --- a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs @@ -4,9 +4,7 @@ //@ revisions: eager lazy #![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 { type Assoc; } type AssocOf = T::Assoc; //~ ERROR associated type `Assoc` not found for `T` //[eager]~^ HELP consider fully qualifying the associated type @@ -17,4 +15,12 @@ type AssokOf = T::Assok; //~ ERROR associated type `Assok` not found for `T` //[lazy]~| HELP consider restricting type parameter `T` //[lazy]~| HELP and changing the associated type name +trait Parametrized<'a, T, const N: usize> { + type Proj; +} + +type ProjOf = 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() {}