diff options
9 files changed, 21 insertions, 13 deletions
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 ff449a858d6..2e227ead14a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -279,7 +279,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } else { let mut err = self.dcx().create_err(err); if suggest_constraining_type_param( - tcx, generics, &mut err, &qself_str, &trait_ref, None, None, + tcx, + generics, + &mut err, + &qself_str, + &trait_ref, + Some(best_trait), + None, ) && !identically_named { // We suggested constraining a type parameter, but the associated item on it diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 49ed69d4e48..a88aea3fa8e 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -345,6 +345,7 @@ pub fn suggest_constraining_type_params<'a>( let mut constraint = constraints.iter().map(|&(c, _, _)| c).collect::<Vec<_>>(); constraint.sort(); constraint.dedup(); + let all_known = constraints.iter().all(|&(_, def_id, _)| def_id.is_some()); let all_stable = constraints.iter().all(|&(_, _, stable)| stable.is_empty()); let all_unstable = constraints.iter().all(|&(_, _, stable)| !stable.is_empty()); let post = if all_stable || all_unstable { @@ -360,7 +361,8 @@ pub fn suggest_constraining_type_params<'a>( trait_names.dedup(); let n = trait_names.len(); let stable = if all_stable { "" } else { "unstable " }; - format!("{stable}trait{} {}", pluralize!(n), match &trait_names[..] { + let trait_ = if all_known { "trait" } else { "" }; + format!("{stable}{trait_}{} {}", pluralize!(n), match &trait_names[..] { [t] => t.to_string(), [ts @ .., last] => format!("{} and {last}", ts.join(", ")), [] => return false, @@ -370,7 +372,7 @@ pub fn suggest_constraining_type_params<'a>( let mut trait_names = constraints .iter() .map(|&(c, def_id, stable)| match def_id { - None => format!("{stable}trait `{c}`"), + None => format!("`{c}`"), Some(def_id) => format!("{stable}trait `{}`", tcx.item_name(def_id)), }) .collect::<Vec<_>>(); diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr index 65ee3236afd..c322d11925a 100644 --- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr @@ -16,7 +16,7 @@ LL | trait UnsafeCopy<'a, T: Copy> LL | where LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>, | ^^^^^^^^^^ required by this bound in `UnsafeCopy` -help: consider further restricting this bound with trait `<Target = T>` +help: consider further restricting this bound with `<Target = T>` | LL | impl<T: Copy + std::ops::Deref<Target = T>> UnsafeCopy<'_, T> for T { | ++++++++++++ diff --git a/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr b/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr index c2d5a8ed48d..16bfe2ec933 100644 --- a/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr +++ b/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr @@ -13,7 +13,7 @@ note: required by a bound in `UnsafeCopy::Item` | LL | type Item<'a>: std::ops::Deref<Target = T>; | ^^^^^^^^^^ required by this bound in `UnsafeCopy::Item` -help: consider further restricting this bound with trait `<Target = T>` +help: consider further restricting this bound with `<Target = T>` | LL | impl<T: Copy + std::ops::Deref<Target = T>> UnsafeCopy<T> for T { | ++++++++++++ diff --git a/tests/ui/generic-associated-types/missing-bounds.stderr b/tests/ui/generic-associated-types/missing-bounds.stderr index b10dbf6908e..c18cc3106f3 100644 --- a/tests/ui/generic-associated-types/missing-bounds.stderr +++ b/tests/ui/generic-associated-types/missing-bounds.stderr @@ -35,7 +35,7 @@ note: tuple struct defined here | LL | struct A<B>(B); | ^ -help: consider further restricting this bound with trait `<Output = B>` +help: consider further restricting this bound with `<Output = B>` | LL | impl<B> Add for A<B> where B: Add<Output = B> { | ++++++++++++ @@ -58,7 +58,7 @@ note: tuple struct defined here | LL | struct C<B>(B); | ^ -help: consider further restricting this bound with trait `<Output = B>` +help: consider further restricting this bound with `<Output = B>` | LL | impl<B: Add<Output = B>> Add for C<B> { | ++++++++++++ @@ -94,7 +94,7 @@ note: tuple struct defined here | LL | struct E<B>(B); | ^ -help: consider further restricting this bound with trait `<Output = B>` +help: consider further restricting this bound with `<Output = B>` | LL | impl<B: Add<Output = B>> Add for E<B> where <B as Add>::Output = B { | ++++++++++++ diff --git a/tests/ui/suggestions/restrict-existing-type-bounds.stderr b/tests/ui/suggestions/restrict-existing-type-bounds.stderr index 8fff4ca5d95..45dab9bec5d 100644 --- a/tests/ui/suggestions/restrict-existing-type-bounds.stderr +++ b/tests/ui/suggestions/restrict-existing-type-bounds.stderr @@ -20,7 +20,7 @@ LL | Ok(self) | this argument influences the type of `Ok` note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL -help: consider further restricting this bound with trait `<Output = T>` +help: consider further restricting this bound with `<Output = T>` | LL | impl<T: TryAdd<Output = T>> TryAdd for Option<T> { | ++++++++++++ @@ -47,7 +47,7 @@ LL | Ok(self) | this argument influences the type of `Ok` note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL -help: consider further restricting this bound with trait `, Output = T` +help: consider further restricting this bound with `, Output = T` | LL | impl<T: TryAdd<Error = X, Output = T>> TryAdd for Other<T> { | ++++++++++++ diff --git a/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr b/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr index c1dda283d9d..ddadee3ea43 100644 --- a/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr +++ b/tests/ui/trait-bounds/restrict-assoc-type-of-generic-bound.stderr @@ -11,7 +11,7 @@ LL | return a.bar(); = note: expected type parameter `B` found associated type `<A as MyTrait>::T` = note: the caller chooses a type for `B` which can be different from `<A as MyTrait>::T` -help: consider further restricting this bound with trait `<T = B>` +help: consider further restricting this bound with `<T = B>` | LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B { | +++++++ diff --git a/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr b/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr index 760a9c603de..02170a127db 100644 --- a/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr +++ b/tests/ui/traits/copy-is-not-modulo-regions.not_static.stderr @@ -12,7 +12,7 @@ note: the `Copy` impl for `Foo<'any>` requires that `'any: 'static` | LL | struct Bar<'lt>(Foo<'lt>); | ^^^^^^^^ -help: consider restricting type parameter `'any` with trait `'static` +help: consider restricting type parameter `'any` with `'static` | LL | impl<'any: 'static> Copy for Bar<'any> {} | +++++++++ 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 a3935efcd7f..885c6ec9d8e 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 @@ -30,7 +30,7 @@ error[E0220]: associated type `Proj` not found for `T` LL | type ProjOf<T> = T::Proj; | ^^^^ there is an associated type `Proj` in the trait `Parametrized` | -help: consider restricting type parameter `T` with trait `Parametrized</* 'a, T, N */>` +help: consider restricting type parameter `T` with trait `Parametrized` | LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj; | ++++++++++++++++++++++++++++++ |
