about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-28 16:28:25 +0000
committerbors <bors@rust-lang.org>2024-07-28 16:28:25 +0000
commit188ddf4d6a694fa263c2ff8be8f8eade659599d6 (patch)
tree16c644d5b03d04f4bd3524248f1f35350a0eac2f
parent78c857394ec8c01f06cb1df260c51178180a40e5 (diff)
parent17f8361a38c16c71d1c5d30d3a900a931477659a (diff)
downloadrust-188ddf4d6a694fa263c2ff8be8f8eade659599d6.tar.gz
rust-188ddf4d6a694fa263c2ff8be8f8eade659599d6.zip
Auto merge of #128246 - GrigorenkoPV:derive-where, r=compiler-errors
Don't manually implement `PartialEq` for some types in `rustc_type_ir`

> > As a follow-up, we should look at not manually implementing PartialEq for these types but instead going thru a derive
>
> I will try to tackle this later in a separate PR

https://github.com/rust-lang/rust/issues/127042#issuecomment-2218838446
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs19
-rw-r--r--compiler/rustc_type_ir/src/const_kind.rs34
-rw-r--r--compiler/rustc_type_ir/src/predicate_kind.rs20
-rw-r--r--compiler/rustc_type_ir/src/region_kind.rs46
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs90
5 files changed, 6 insertions, 203 deletions
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 7e93dc248cc..5285635975c 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::derived_hash_with_manual_eq)]
-
 use derive_where::derive_where;
 #[cfg(feature = "nightly")]
 use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
@@ -141,7 +139,7 @@ impl<I: Interner> CanonicalVarInfo<I> {
 /// Describes the "kind" of the canonical variable. This is a "kind"
 /// in the type-theory sense of the term -- i.e., a "meta" type system
 /// that analyzes type-like values.
-#[derive_where(Clone, Copy, Hash, Eq, Debug; I: Interner)]
+#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
 pub enum CanonicalVarKind<I: Interner> {
@@ -169,21 +167,6 @@ pub enum CanonicalVarKind<I: Interner> {
     PlaceholderConst(I::PlaceholderConst),
 }
 
-// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
-impl<I: Interner> PartialEq for CanonicalVarKind<I> {
-    fn eq(&self, other: &Self) -> bool {
-        match (self, other) {
-            (Self::Ty(l0), Self::Ty(r0)) => l0 == r0,
-            (Self::PlaceholderTy(l0), Self::PlaceholderTy(r0)) => l0 == r0,
-            (Self::Region(l0), Self::Region(r0)) => l0 == r0,
-            (Self::PlaceholderRegion(l0), Self::PlaceholderRegion(r0)) => l0 == r0,
-            (Self::Const(l0), Self::Const(r0)) => l0 == r0,
-            (Self::PlaceholderConst(l0), Self::PlaceholderConst(r0)) => l0 == r0,
-            _ => std::mem::discriminant(self) == std::mem::discriminant(other),
-        }
-    }
-}
-
 impl<I: Interner> CanonicalVarKind<I> {
     pub fn universe(self) -> UniverseIndex {
         match self {
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs
index 458ffdabe94..76b70e4ad44 100644
--- a/compiler/rustc_type_ir/src/const_kind.rs
+++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::derived_hash_with_manual_eq)]
-
 use derive_where::derive_where;
 #[cfg(feature = "nightly")]
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -10,10 +8,8 @@ use std::fmt;
 
 use crate::{self as ty, DebruijnIndex, Interner};
 
-use self::ConstKind::*;
-
 /// Represents a constant in Rust.
-#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
+#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
 pub enum ConstKind<I: Interner> {
     /// A const generic parameter.
@@ -45,23 +41,6 @@ pub enum ConstKind<I: Interner> {
     Expr(I::ExprConst),
 }
 
-// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
-impl<I: Interner> PartialEq for ConstKind<I> {
-    fn eq(&self, other: &Self) -> bool {
-        match (self, other) {
-            (Param(l0), Param(r0)) => l0 == r0,
-            (Infer(l0), Infer(r0)) => l0 == r0,
-            (Bound(l0, l1), Bound(r0, r1)) => l0 == r0 && l1 == r1,
-            (Placeholder(l0), Placeholder(r0)) => l0 == r0,
-            (Unevaluated(l0), Unevaluated(r0)) => l0 == r0,
-            (Value(l0, l1), Value(r0, r1)) => l0 == r0 && l1 == r1,
-            (Error(l0), Error(r0)) => l0 == r0,
-            (Expr(l0), Expr(r0)) => l0 == r0,
-            _ => false,
-        }
-    }
-}
-
 impl<I: Interner> fmt::Debug for ConstKind<I> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         use ConstKind::*;
@@ -80,7 +59,7 @@ impl<I: Interner> fmt::Debug for ConstKind<I> {
 }
 
 /// An unevaluated (potentially generic) constant used in the type-system.
-#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
+#[derive_where(Clone, Copy, Debug, Hash, PartialEq, Eq; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
 #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
 pub struct UnevaluatedConst<I: Interner> {
@@ -95,15 +74,6 @@ impl<I: Interner> UnevaluatedConst<I> {
     }
 }
 
-impl<I: Interner> fmt::Debug for UnevaluatedConst<I> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("UnevaluatedConst")
-            .field("def", &self.def)
-            .field("args", &self.args)
-            .finish()
-    }
-}
-
 rustc_index::newtype_index! {
     /// A **`const`** **v**ariable **ID**.
     #[encodable]
diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs
index 70b7c29bdfc..acd03143210 100644
--- a/compiler/rustc_type_ir/src/predicate_kind.rs
+++ b/compiler/rustc_type_ir/src/predicate_kind.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::derived_hash_with_manual_eq)]
-
 use derive_where::derive_where;
 #[cfg(feature = "nightly")]
 use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
@@ -10,7 +8,7 @@ use crate::{self as ty, Interner};
 
 /// A clause is something that can appear in where bounds or be inferred
 /// by implied bounds.
-#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
+#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
 pub enum ClauseKind<I: Interner> {
@@ -40,22 +38,6 @@ pub enum ClauseKind<I: Interner> {
     ConstEvaluatable(I::Const),
 }
 
-// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
-impl<I: Interner> PartialEq for ClauseKind<I> {
-    fn eq(&self, other: &Self) -> bool {
-        match (self, other) {
-            (Self::Trait(l0), Self::Trait(r0)) => l0 == r0,
-            (Self::RegionOutlives(l0), Self::RegionOutlives(r0)) => l0 == r0,
-            (Self::TypeOutlives(l0), Self::TypeOutlives(r0)) => l0 == r0,
-            (Self::Projection(l0), Self::Projection(r0)) => l0 == r0,
-            (Self::ConstArgHasType(l0, l1), Self::ConstArgHasType(r0, r1)) => l0 == r0 && l1 == r1,
-            (Self::WellFormed(l0), Self::WellFormed(r0)) => l0 == r0,
-            (Self::ConstEvaluatable(l0), Self::ConstEvaluatable(r0)) => l0 == r0,
-            _ => false,
-        }
-    }
-}
-
 #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs
index ef18ef15235..9c993b3039a 100644
--- a/compiler/rustc_type_ir/src/region_kind.rs
+++ b/compiler/rustc_type_ir/src/region_kind.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::derived_hash_with_manual_eq)]
-
 use derive_where::derive_where;
 #[cfg(feature = "nightly")]
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -127,7 +125,7 @@ rustc_index::newtype_index! {
 /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
-#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
+#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
 pub enum RegionKind<I: Interner> {
     /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.
@@ -179,48 +177,6 @@ pub enum RegionKind<I: Interner> {
     ReError(I::ErrorGuaranteed),
 }
 
-// This is manually implemented for `RegionKind` because `std::mem::discriminant`
-// returns an opaque value that is `PartialEq` but not `PartialOrd`
-#[inline]
-const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
-    match value {
-        ReEarlyParam(_) => 0,
-        ReBound(_, _) => 1,
-        ReLateParam(_) => 2,
-        ReStatic => 3,
-        ReVar(_) => 4,
-        RePlaceholder(_) => 5,
-        ReErased => 6,
-        ReError(_) => 7,
-    }
-}
-
-// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
-// This is manually implemented because a derive would require `I: PartialEq`
-impl<I: Interner> PartialEq for RegionKind<I> {
-    #[inline]
-    fn eq(&self, other: &RegionKind<I>) -> bool {
-        regionkind_discriminant(self) == regionkind_discriminant(other)
-            && match (self, other) {
-                (ReEarlyParam(a_r), ReEarlyParam(b_r)) => a_r == b_r,
-                (ReBound(a_d, a_r), ReBound(b_d, b_r)) => a_d == b_d && a_r == b_r,
-                (ReLateParam(a_r), ReLateParam(b_r)) => a_r == b_r,
-                (ReStatic, ReStatic) => true,
-                (ReVar(a_r), ReVar(b_r)) => a_r == b_r,
-                (RePlaceholder(a_r), RePlaceholder(b_r)) => a_r == b_r,
-                (ReErased, ReErased) => true,
-                (ReError(_), ReError(_)) => true,
-                _ => {
-                    debug_assert!(
-                        false,
-                        "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}"
-                    );
-                    true
-                }
-            }
-    }
-}
-
 impl<I: Interner> fmt::Debug for RegionKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 4672904ab73..fcbf4bfcdb7 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -1,5 +1,3 @@
-#![allow(clippy::derived_hash_with_manual_eq)]
-
 use derive_where::derive_where;
 
 #[cfg(feature = "nightly")]
@@ -68,7 +66,7 @@ impl AliasTyKind {
 /// Types written by the user start out as `hir::TyKind` and get
 /// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
 #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
-#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
+#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
 pub enum TyKind<I: Interner> {
     /// The primitive boolean type. Written as `bool`.
@@ -259,92 +257,6 @@ impl<I: Interner> TyKind<I> {
     }
 }
 
-// This is manually implemented for `TyKind` because `std::mem::discriminant`
-// returns an opaque value that is `PartialEq` but not `PartialOrd`
-#[inline]
-const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
-    match value {
-        Bool => 0,
-        Char => 1,
-        Int(_) => 2,
-        Uint(_) => 3,
-        Float(_) => 4,
-        Adt(_, _) => 5,
-        Foreign(_) => 6,
-        Str => 7,
-        Array(_, _) => 8,
-        Slice(_) => 9,
-        RawPtr(_, _) => 10,
-        Ref(_, _, _) => 11,
-        FnDef(_, _) => 12,
-        FnPtr(_) => 13,
-        Dynamic(..) => 14,
-        Closure(_, _) => 15,
-        CoroutineClosure(_, _) => 16,
-        Coroutine(_, _) => 17,
-        CoroutineWitness(_, _) => 18,
-        Never => 19,
-        Tuple(_) => 20,
-        Pat(_, _) => 21,
-        Alias(_, _) => 22,
-        Param(_) => 23,
-        Bound(_, _) => 24,
-        Placeholder(_) => 25,
-        Infer(_) => 26,
-        Error(_) => 27,
-    }
-}
-
-// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
-// This is manually implemented because a derive would require `I: PartialEq`
-impl<I: Interner> PartialEq for TyKind<I> {
-    #[inline]
-    fn eq(&self, other: &TyKind<I>) -> bool {
-        // You might expect this `match` to be preceded with this:
-        //
-        //   tykind_discriminant(self) == tykind_discriminant(other) &&
-        //
-        // but the data patterns in practice are such that a comparison
-        // succeeds 99%+ of the time, and it's faster to omit it.
-        match (self, other) {
-            (Int(a_i), Int(b_i)) => a_i == b_i,
-            (Uint(a_u), Uint(b_u)) => a_u == b_u,
-            (Float(a_f), Float(b_f)) => a_f == b_f,
-            (Adt(a_d, a_s), Adt(b_d, b_s)) => a_d == b_d && a_s == b_s,
-            (Foreign(a_d), Foreign(b_d)) => a_d == b_d,
-            (Array(a_t, a_c), Array(b_t, b_c)) => a_t == b_t && a_c == b_c,
-            (Pat(a_t, a_c), Pat(b_t, b_c)) => a_t == b_t && a_c == b_c,
-            (Slice(a_t), Slice(b_t)) => a_t == b_t,
-            (RawPtr(a_t, a_m), RawPtr(b_t, b_m)) => a_t == b_t && a_m == b_m,
-            (Ref(a_r, a_t, a_m), Ref(b_r, b_t, b_m)) => a_r == b_r && a_t == b_t && a_m == b_m,
-            (FnDef(a_d, a_s), FnDef(b_d, b_s)) => a_d == b_d && a_s == b_s,
-            (FnPtr(a_s), FnPtr(b_s)) => a_s == b_s,
-            (Dynamic(a_p, a_r, a_repr), Dynamic(b_p, b_r, b_repr)) => {
-                a_p == b_p && a_r == b_r && a_repr == b_repr
-            }
-            (Closure(a_d, a_s), Closure(b_d, b_s)) => a_d == b_d && a_s == b_s,
-            (CoroutineClosure(a_d, a_s), CoroutineClosure(b_d, b_s)) => a_d == b_d && a_s == b_s,
-            (Coroutine(a_d, a_s), Coroutine(b_d, b_s)) => a_d == b_d && a_s == b_s,
-            (CoroutineWitness(a_d, a_s), CoroutineWitness(b_d, b_s)) => a_d == b_d && a_s == b_s,
-            (Tuple(a_t), Tuple(b_t)) => a_t == b_t,
-            (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p,
-            (Param(a_p), Param(b_p)) => a_p == b_p,
-            (Bound(a_d, a_b), Bound(b_d, b_b)) => a_d == b_d && a_b == b_b,
-            (Placeholder(a_p), Placeholder(b_p)) => a_p == b_p,
-            (Infer(a_t), Infer(b_t)) => a_t == b_t,
-            (Error(a_e), Error(b_e)) => a_e == b_e,
-            (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => true,
-            _ => {
-                debug_assert!(
-                    tykind_discriminant(self) != tykind_discriminant(other),
-                    "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}"
-                );
-                false
-            }
-        }
-    }
-}
-
 // This is manually implemented because a derive would require `I: Debug`
 impl<I: Interner> fmt::Debug for TyKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {