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