Skip to content

Commit

Permalink
Use derivative to simplify impls in rustc_type_ir
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 25, 2023
1 parent b66fe58 commit 2d309ff
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 508 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,17 @@ dependencies = [
"syn 2.0.29",
]

[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]

[[package]]
name = "derive_builder"
version = "0.12.0"
Expand Down Expand Up @@ -4671,6 +4682,7 @@ name = "rustc_type_ir"
version = "0.0.0"
dependencies = [
"bitflags 1.3.2",
"derivative",
"rustc_data_structures",
"rustc_index",
"rustc_macros",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_macros = { path = "../rustc_macros" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
derivative = "2.2.0"
93 changes: 11 additions & 82 deletions compiler/rustc_type_ir/src/const_kind.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use rustc_data_structures::stable_hasher::HashStable;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_serialize::{Decodable, Decoder, Encodable};
use std::cmp::Ordering;
use std::fmt;
use std::hash;

use crate::{
DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, TyDecoder,
Expand All @@ -13,7 +11,17 @@ use crate::{
use self::ConstKind::*;

/// Represents a constant in Rust.
// #[derive(derive_more::From)]
#[derive(derivative::Derivative)]
#[derivative(
Clone(bound = ""),
PartialEq(bound = ""),
Eq(bound = ""),
PartialOrd(bound = ""),
PartialOrd = "feature_allow_slow_enum",
Ord(bound = ""),
Ord = "feature_allow_slow_enum",
Hash(bound = "")
)]
pub enum ConstKind<I: Interner> {
/// A const generic parameter.
Param(I::ParamConst),
Expand Down Expand Up @@ -57,25 +65,6 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
}
}

impl<I: Interner> hash::Hash for ConstKind<I> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
const_kind_discriminant(self).hash(state);
match self {
Param(p) => p.hash(state),
Infer(i) => i.hash(state),
Bound(d, b) => {
d.hash(state);
b.hash(state);
}
Placeholder(p) => p.hash(state),
Unevaluated(u) => u.hash(state),
Value(v) => v.hash(state),
Error(e) => e.hash(state),
Expr(e) => e.hash(state),
}
}
}

impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
where
I::ParamConst: HashStable<CTX>,
Expand Down Expand Up @@ -166,66 +155,6 @@ where
}
}

impl<I: Interner> PartialOrd for ConstKind<I> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl<I: Interner> Ord for ConstKind<I> {
fn cmp(&self, other: &Self) -> Ordering {
const_kind_discriminant(self)
.cmp(&const_kind_discriminant(other))
.then_with(|| match (self, other) {
(Param(p1), Param(p2)) => p1.cmp(p2),
(Infer(i1), Infer(i2)) => i1.cmp(i2),
(Bound(d1, b1), Bound(d2, b2)) => d1.cmp(d2).then_with(|| b1.cmp(b2)),
(Placeholder(p1), Placeholder(p2)) => p1.cmp(p2),
(Unevaluated(u1), Unevaluated(u2)) => u1.cmp(u2),
(Value(v1), Value(v2)) => v1.cmp(v2),
(Error(e1), Error(e2)) => e1.cmp(e2),
(Expr(e1), Expr(e2)) => e1.cmp(e2),
_ => {
debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}");
Ordering::Equal
}
})
}
}

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), Value(r0)) => l0 == r0,
(Error(l0), Error(r0)) => l0 == r0,
(Expr(l0), Expr(r0)) => l0 == r0,
_ => false,
}
}
}

impl<I: Interner> Eq for ConstKind<I> {}

impl<I: Interner> Clone for ConstKind<I> {
fn clone(&self) -> Self {
match self {
Param(arg0) => Param(arg0.clone()),
Infer(arg0) => Infer(arg0.clone()),
Bound(arg0, arg1) => Bound(arg0.clone(), arg1.clone()),
Placeholder(arg0) => Placeholder(arg0.clone()),
Unevaluated(arg0) => Unevaluated(arg0.clone()),
Value(arg0) => Value(arg0.clone()),
Error(arg0) => Error(arg0.clone()),
Expr(arg0) => Expr(arg0.clone()),
}
}
}

impl<I: Interner> fmt::Debug for ConstKind<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
WithInfcx::with_no_infcx(self).fmt(f)
Expand Down
121 changes: 4 additions & 117 deletions compiler/rustc_type_ir/src/predicate_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_serialize::Decoder;
use rustc_serialize::{Decodable, Encodable};
use std::fmt;
use std::hash;
use std::ops::ControlFlow;

use crate::fold::{FallibleTypeFolder, TypeFoldable};
Expand All @@ -12,6 +11,8 @@ use crate::{TyDecoder, TyEncoder};

/// A clause is something that can appear in where bounds or be inferred
/// by implied bounds.
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""), PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))]
pub enum ClauseKind<I: Interner> {
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
Expand Down Expand Up @@ -39,20 +40,6 @@ pub enum ClauseKind<I: Interner> {
ConstEvaluatable(I::Const),
}

impl<I: Interner> Clone for ClauseKind<I> {
fn clone(&self) -> Self {
match self {
Self::Trait(arg0) => Self::Trait(arg0.clone()),
Self::RegionOutlives(arg0) => Self::RegionOutlives(arg0.clone()),
Self::TypeOutlives(arg0) => Self::TypeOutlives(arg0.clone()),
Self::Projection(arg0) => Self::Projection(arg0.clone()),
Self::ConstArgHasType(arg0, arg1) => Self::ConstArgHasType(arg0.clone(), arg1.clone()),
Self::WellFormed(arg0) => Self::WellFormed(arg0.clone()),
Self::ConstEvaluatable(arg0) => Self::ConstEvaluatable(arg0.clone()),
}
}
}

impl<I: Interner> Copy for ClauseKind<I>
where
I::Ty: Copy,
Expand All @@ -65,23 +52,6 @@ where
{
}

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,
}
}
}

impl<I: Interner> Eq for ClauseKind<I> {}

fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> usize {
match value {
ClauseKind::Trait(_) => 0,
Expand All @@ -94,24 +64,6 @@ fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> usize {
}
}

impl<I: Interner> hash::Hash for ClauseKind<I> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
clause_kind_discriminant(self).hash(state);
match self {
ClauseKind::Trait(p) => p.hash(state),
ClauseKind::RegionOutlives(p) => p.hash(state),
ClauseKind::TypeOutlives(p) => p.hash(state),
ClauseKind::Projection(p) => p.hash(state),
ClauseKind::ConstArgHasType(c, t) => {
c.hash(state);
t.hash(state);
}
ClauseKind::WellFormed(t) => t.hash(state),
ClauseKind::ConstEvaluatable(c) => c.hash(state),
}
}
}

impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ClauseKind<I>
where
I::Ty: HashStable<CTX>,
Expand Down Expand Up @@ -249,6 +201,8 @@ where
}
}

#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""), PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))]
pub enum PredicateKind<I: Interner> {
/// Prove a clause
Clause(ClauseKind<I>),
Expand Down Expand Up @@ -305,46 +259,6 @@ where
{
}

impl<I: Interner> Clone for PredicateKind<I> {
fn clone(&self) -> Self {
match self {
Self::Clause(arg0) => Self::Clause(arg0.clone()),
Self::ObjectSafe(arg0) => Self::ObjectSafe(arg0.clone()),
Self::ClosureKind(arg0, arg1, arg2) => {
Self::ClosureKind(arg0.clone(), arg1.clone(), arg2.clone())
}
Self::Subtype(arg0) => Self::Subtype(arg0.clone()),
Self::Coerce(arg0) => Self::Coerce(arg0.clone()),
Self::ConstEquate(arg0, arg1) => Self::ConstEquate(arg0.clone(), arg1.clone()),
Self::Ambiguous => Self::Ambiguous,
Self::AliasRelate(arg0, arg1, arg2) => {
Self::AliasRelate(arg0.clone(), arg1.clone(), arg2.clone())
}
}
}
}

impl<I: Interner> PartialEq for PredicateKind<I> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Clause(l0), Self::Clause(r0)) => l0 == r0,
(Self::ObjectSafe(l0), Self::ObjectSafe(r0)) => l0 == r0,
(Self::ClosureKind(l0, l1, l2), Self::ClosureKind(r0, r1, r2)) => {
l0 == r0 && l1 == r1 && l2 == r2
}
(Self::Subtype(l0), Self::Subtype(r0)) => l0 == r0,
(Self::Coerce(l0), Self::Coerce(r0)) => l0 == r0,
(Self::ConstEquate(l0, l1), Self::ConstEquate(r0, r1)) => l0 == r0 && l1 == r1,
(Self::AliasRelate(l0, l1, l2), Self::AliasRelate(r0, r1, r2)) => {
l0 == r0 && l1 == r1 && l2 == r2
}
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
}
}
}

impl<I: Interner> Eq for PredicateKind<I> {}

fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> usize {
match value {
PredicateKind::Clause(_) => 0,
Expand All @@ -358,33 +272,6 @@ fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> usize {
}
}

impl<I: Interner> hash::Hash for PredicateKind<I> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
predicate_kind_discriminant(self).hash(state);
match self {
PredicateKind::Clause(p) => p.hash(state),
PredicateKind::ObjectSafe(d) => d.hash(state),
PredicateKind::ClosureKind(d, g, k) => {
d.hash(state);
g.hash(state);
k.hash(state);
}
PredicateKind::Subtype(p) => p.hash(state),
PredicateKind::Coerce(p) => p.hash(state),
PredicateKind::ConstEquate(c1, c2) => {
c1.hash(state);
c2.hash(state);
}
PredicateKind::Ambiguous => {}
PredicateKind::AliasRelate(t1, t2, r) => {
t1.hash(state);
t2.hash(state);
r.hash(state);
}
}
}
}

impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for PredicateKind<I>
where
I::DefId: HashStable<CTX>,
Expand Down
Loading

0 comments on commit 2d309ff

Please sign in to comment.