From c02f72722b178b50374ac3bba7dfcf1364be3fb4 Mon Sep 17 00:00:00 2001 From: Raushan kumar Date: Fri, 3 Jul 2026 16:38:17 +0000 Subject: [PATCH] Improve E0277 diagnostic for imperfect derives --- .../src/error_reporting/traits/suggestions.rs | 6 ++++-- tests/ui/associated-types/issue-38821.stderr | 6 ++++-- .../adt_const_params/unsizing-wfcheck-issue-126272.stderr | 6 ++++-- tests/ui/derives/clone-copy/deriving-copyclone.stderr | 3 ++- .../derives/redundant-derive-note-on-unimplemented.stderr | 3 ++- tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr | 3 ++- .../suggestions/missing-bound-in-derive-copy-impl-2.stderr | 6 ++++-- .../ui/suggestions/missing-bound-in-derive-copy-impl.stderr | 6 ++++-- tests/ui/traits/derive-implicit-bound.stderr | 3 ++- 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index cc2d722ded8d3..ff823594ce1c0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4258,9 +4258,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.span_note(spans, msg); if derived && trait_name != "Copy" { err.help(format!( - "consider manually implementing `{trait_name}` to avoid undesired \ - bounds", + "consider manually implementing `{trait_name}` to avoid undesired bounds caused by \"imperfect derives\"", )); + err.note( + "to learn more, visit ", + ); } point_at_assoc_type_restriction( tcx, diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index e3398f0e2390d..d7fcec380a3de 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -108,7 +108,8 @@ LL | pub enum ColumnInsertValue where ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds + = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -238,7 +239,8 @@ LL | pub enum ColumnInsertValue where ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound - = help: consider manually implementing `Clone` to avoid undesired bounds + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index f520413927c36..029c41b46ff40 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -67,7 +67,8 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ----- in this derive macro expansion LL | struct Bar(T); | ^^^ - unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds + = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` = note: required for the cast from `&&&'static Bar<(dyn Debug + 'static)>` to `&dyn Debug` @@ -102,7 +103,8 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | -- in this derive macro expansion LL | struct Bar(T); | ^^^ - type parameter would need to implement `Eq` - = help: consider manually implementing `Eq` to avoid undesired bounds + = help: consider manually implementing `Eq` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` note: required by a bound in `std::cmp::AssertParamIsEq` diff --git a/tests/ui/derives/clone-copy/deriving-copyclone.stderr b/tests/ui/derives/clone-copy/deriving-copyclone.stderr index 20a73ffdcfbfe..356678ada17bb 100644 --- a/tests/ui/derives/clone-copy/deriving-copyclone.stderr +++ b/tests/ui/derives/clone-copy/deriving-copyclone.stderr @@ -38,7 +38,8 @@ LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion LL | struct B { | ^ - type parameter would need to implement `Clone` - = help: consider manually implementing `Clone` to avoid undesired bounds + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 | diff --git a/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr b/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr index 09b45212c3c9a..ef3c94b4f07f7 100644 --- a/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr +++ b/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr @@ -21,7 +21,8 @@ LL | #[derive(Debug)] | ----- in this derive macro expansion LL | struct S(T); | ^ - type parameter would need to implement `Debug` - = help: consider manually implementing `Debug` to avoid undesired bounds + = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit help: consider annotating `X` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index b53ebe9f72718..179f9fc51a4ba 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -44,7 +44,8 @@ LL | #[derive(PartialOrd, AddImpl)] ... LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^ - type parameter would need to implement `PartialOrd` - = help: consider manually implementing `PartialOrd` to avoid undesired bounds + = help: consider manually implementing `PartialOrd` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index 791e2d19f2f96..779339232e692 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -30,7 +30,8 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds + = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` | @@ -72,7 +73,8 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Clone` to avoid undesired bounds + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit help: consider further restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 55d6391f975e6..225ab3cd5838d 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -66,7 +66,8 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds + = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` | @@ -136,7 +137,8 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Clone` to avoid undesired bounds + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit help: consider restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr index fe2bc77b9529c..9c8cb11440d0c 100644 --- a/tests/ui/traits/derive-implicit-bound.stderr +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -14,7 +14,8 @@ LL | #[derive(PartialEq, Eq)] | --------- in this derive macro expansion LL | pub struct Id(PhantomData); | ^^ - type parameter would need to implement `PartialEq` - = help: consider manually implementing `PartialEq` to avoid undesired bounds + = help: consider manually implementing `PartialEq` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit note: required by a bound in `accept_eq` --> $DIR/derive-implicit-bound.rs:17:23 |