diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 5b06cc33302..7f9f1a32701 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1196,10 +1196,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(adt) if adt.did.is_local() => adt, _ => continue, }; - let diagnostic_name = self.tcx.get_diagnostic_name(trait_pred.def_id()); - let can_derive = match diagnostic_name { - Some(sym::Default) => !adt.is_enum(), - Some( + if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) { + let can_derive = match diagnostic_name { + sym::Default => !adt.is_enum(), sym::Eq | sym::PartialEq | sym::Ord @@ -1207,24 +1206,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | sym::Clone | sym::Copy | sym::Hash - | sym::Debug, - ) => true, - _ => false, - }; - if can_derive { - let self_name = trait_pred.self_ty().to_string(); - let self_span = self.tcx.def_span(adt.did); - if let Some(sym::Ord) = diagnostic_name { - derives.push((self_name.clone(), self_span.clone(), "PartialOrd".to_string())); + | sym::Debug => true, + _ => false, + }; + if can_derive { + let self_name = trait_pred.self_ty().to_string(); + let self_span = self.tcx.def_span(adt.did); + use crate::rustc_middle::ty::ToPolyTraitRef; + if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() { + for super_trait in rustc_middle::traits::util::supertraits( + self.tcx, + poly_trait_ref.to_poly_trait_ref(), + ) { + if let Some(parent_diagnostic_name) = + self.tcx.get_diagnostic_name(super_trait.def_id()) + { + derives.push(( + self_name.clone(), + self_span.clone(), + parent_diagnostic_name.to_string(), + )); + } + } + } + derives.push((self_name, self_span, diagnostic_name.to_string())); + } else { + traits.push(self.tcx.def_span(trait_pred.def_id())); } - if let Some(sym::Eq) = diagnostic_name { - derives.push((self_name.clone(), self_span.clone(), "PartialEq".to_string())); - } - derives.push(( - self_name, - self_span, - trait_pred.trait_ref.print_only_trait_name().to_string(), - )); } else { traits.push(self.tcx.def_span(trait_pred.def_id())); } diff --git a/src/test/ui/binop/issue-28837.stderr b/src/test/ui/binop/issue-28837.stderr index 10f243bab15..1875ea06a06 100644 --- a/src/test/ui/binop/issue-28837.stderr +++ b/src/test/ui/binop/issue-28837.stderr @@ -272,9 +272,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A` | LL | struct A; | ^^^^^^^^^ must implement `PartialOrd<_>` -help: consider annotating `A` with `#[derive(PartialOrd)]` +help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL | #[derive(PartialEq, PartialOrd)] | error[E0369]: binary operation `<=` cannot be applied to type `A` @@ -290,9 +290,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A` | LL | struct A; | ^^^^^^^^^ must implement `PartialOrd<_>` -help: consider annotating `A` with `#[derive(PartialOrd)]` +help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL | #[derive(PartialEq, PartialOrd)] | error[E0369]: binary operation `>` cannot be applied to type `A` @@ -308,9 +308,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A` | LL | struct A; | ^^^^^^^^^ must implement `PartialOrd<_>` -help: consider annotating `A` with `#[derive(PartialOrd)]` +help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL | #[derive(PartialEq, PartialOrd)] | error[E0369]: binary operation `>=` cannot be applied to type `A` @@ -326,9 +326,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A` | LL | struct A; | ^^^^^^^^^ must implement `PartialOrd<_>` -help: consider annotating `A` with `#[derive(PartialOrd)]` +help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]` | -LL | #[derive(PartialOrd)] +LL | #[derive(PartialEq, PartialOrd)] | error: aborting due to 15 previous errors diff --git a/src/test/ui/derives/issue-91550.stderr b/src/test/ui/derives/issue-91550.stderr index 2b88c35c6a3..bf4b7c7da0d 100644 --- a/src/test/ui/derives/issue-91550.stderr +++ b/src/test/ui/derives/issue-91550.stderr @@ -51,9 +51,9 @@ LL | foo.use_ord(); | = note: the following trait bounds were not satisfied: `NoDerives: Ord` -help: consider annotating `NoDerives` with `#[derive(Ord, PartialOrd)]` +help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | -LL | #[derive(Ord, PartialOrd)] +LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] | error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied @@ -74,9 +74,9 @@ LL | foo.use_ord_and_partial_ord(); = note: the following trait bounds were not satisfied: `NoDerives: Ord` `NoDerives: PartialOrd` -help: consider annotating `NoDerives` with `#[derive(Ord, PartialOrd)]` +help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | -LL | #[derive(Ord, PartialOrd)] +LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] | error: aborting due to 4 previous errors diff --git a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr index 146a627bcde..e8e65fe5d1d 100644 --- a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr +++ b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr @@ -16,9 +16,9 @@ LL | let w = u.clone(); = note: the following trait bounds were not satisfied: `CloneNoCopy: Copy` which is required by `U5<CloneNoCopy>: Clone` -help: consider annotating `CloneNoCopy` with `#[derive(Copy)]` +help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | -LL | #[derive(Copy)] +LL | #[derive(Clone, Copy)] | error[E0277]: the trait bound `U1: Copy` is not satisfied diff --git a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr index 146a627bcde..e8e65fe5d1d 100644 --- a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr +++ b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr @@ -16,9 +16,9 @@ LL | let w = u.clone(); = note: the following trait bounds were not satisfied: `CloneNoCopy: Copy` which is required by `U5<CloneNoCopy>: Clone` -help: consider annotating `CloneNoCopy` with `#[derive(Copy)]` +help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | -LL | #[derive(Copy)] +LL | #[derive(Clone, Copy)] | error[E0277]: the trait bound `U1: Copy` is not satisfied