about summary refs log tree commit diff
diff options
context:
space:
mode:
authorohno418 <yutaro.ono.418@gmail.com>2022-04-01 11:28:28 +0900
committerohno418 <yutaro.ono.418@gmail.com>2022-04-05 11:31:11 +0900
commit0ff2f58330a590fcc967b890731d2ebedf6ecb0c (patch)
tree20cc2e36bfff877796a8eef8a8e3207859e8f525
parent0d2a00058b4b3d4a04712309cc4cc371a8fb8653 (diff)
downloadrust-0ff2f58330a590fcc967b890731d2ebedf6ecb0c.tar.gz
rust-0ff2f58330a590fcc967b890731d2ebedf6ecb0c.zip
Suggest only when Rhs for PartialEq and PartialOrd is the same type as self
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs60
1 files changed, 31 insertions, 29 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 4db6ff08754..64fb352ac45 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2593,35 +2593,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     }
 
     fn suggest_derive(&self, err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>) {
-        if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
-            let adt = match trait_pred.skip_binder().self_ty().ty_adt_def() {
-                Some(adt) if adt.did().is_local() => adt,
-                _ => return,
-            };
-            let can_derive = match diagnostic_name {
-                sym::Default => !adt.is_enum(),
-                sym::Eq
-                | sym::PartialEq
-                | sym::Ord
-                | sym::PartialOrd
-                | sym::Clone
-                | sym::Copy
-                | sym::Hash
-                | sym::Debug => true,
-                _ => false,
-            };
-            if can_derive {
-                err.span_suggestion_verbose(
-                    self.tcx.def_span(adt.did()).shrink_to_lo(),
-                    &format!(
-                        "consider annotating `{}` with `#[derive({})]`",
-                        trait_pred.skip_binder().self_ty().to_string(),
-                        diagnostic_name.to_string(),
-                    ),
-                    format!("#[derive({})]\n", diagnostic_name.to_string()),
-                    Applicability::MaybeIncorrect,
-                );
-            }
+        let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
+            return;
+        };
+        let Some(self_ty) = trait_pred.self_ty().no_bound_vars() else {
+            return;
+        };
+
+        let adt = match self_ty.ty_adt_def() {
+            Some(adt) if adt.did().is_local() => adt,
+            _ => return,
+        };
+        let can_derive = match diagnostic_name {
+            sym::Default => !adt.is_enum(),
+            sym::PartialEq | sym::PartialOrd => {
+                let rhs_ty = trait_pred.skip_binder().trait_ref.substs.type_at(1);
+                self_ty == rhs_ty
+            }
+            sym::Eq | sym::Ord | sym::Clone | sym::Copy | sym::Hash | sym::Debug => true,
+            _ => false,
+        };
+        if can_derive {
+            err.span_suggestion_verbose(
+                self.tcx.def_span(adt.did()).shrink_to_lo(),
+                &format!(
+                    "consider annotating `{}` with `#[derive({})]`",
+                    trait_pred.skip_binder().self_ty().to_string(),
+                    diagnostic_name.to_string(),
+                ),
+                format!("#[derive({})]\n", diagnostic_name.to_string()),
+                Applicability::MaybeIncorrect,
+            );
         }
     }
 }