Skip to content

Commit d7d9f15

Browse files
committed
Auto merge of #117407 - compiler-errors:derive-clone, r=oli-obk
Use derivative for `Clone`/`PartialOrd`/`Ord`/`Hash` in `rustc_type_ir` This uses `derivative` to derive `Clone`/`PartialOrd`/`Ord`/`Hash` for types in `rustc_type_ir`. This doesn't derive `PartialEq`/`Eq` yet, because I have no idea why those are generating slower implementations from derivative.
2 parents 045f158 + 8b4fa0f commit d7d9f15

File tree

8 files changed

+50
-391
lines changed

8 files changed

+50
-391
lines changed

Cargo.lock

+12
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,17 @@ dependencies = [
10111011
"syn 2.0.29",
10121012
]
10131013

1014+
[[package]]
1015+
name = "derivative"
1016+
version = "2.2.0"
1017+
source = "registry+https://github.com/rust-lang/crates.io-index"
1018+
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
1019+
dependencies = [
1020+
"proc-macro2",
1021+
"quote",
1022+
"syn 1.0.109",
1023+
]
1024+
10141025
[[package]]
10151026
name = "derive_builder"
10161027
version = "0.12.0"
@@ -4667,6 +4678,7 @@ name = "rustc_type_ir"
46674678
version = "0.0.0"
46684679
dependencies = [
46694680
"bitflags 1.3.2",
4681+
"derivative",
46704682
"rustc_data_structures",
46714683
"rustc_index",
46724684
"rustc_macros",

compiler/rustc_type_ir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
[dependencies]
77
# tidy-alphabetical-start
88
bitflags = "1.2.1"
9+
derivative = "2.2.0"
910
rustc_data_structures = { path = "../rustc_data_structures" }
1011
rustc_index = { path = "../rustc_index" }
1112
rustc_macros = { path = "../rustc_macros" }

compiler/rustc_type_ir/src/canonical.rs

+3-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::fmt;
2-
use std::hash;
2+
use std::hash::Hash;
33
use std::ops::ControlFlow;
44

55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -13,6 +13,8 @@ use crate::{HashStableContext, Interner, TyEncoder, UniverseIndex};
1313
/// A "canonicalized" type `V` is one where all free inference
1414
/// variables have been rewritten to "canonical vars". These are
1515
/// numbered starting from 0 in order of first appearance.
16+
#[derive(derivative::Derivative)]
17+
#[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))]
1618
pub struct Canonical<I: Interner, V> {
1719
pub value: V,
1820
pub max_universe: UniverseIndex,
@@ -59,14 +61,6 @@ impl<I: Interner, V> Canonical<I, V> {
5961
}
6062
}
6163

62-
impl<I: Interner, V: hash::Hash> hash::Hash for Canonical<I, V> {
63-
fn hash<H: hash::Hasher>(&self, state: &mut H) {
64-
self.value.hash(state);
65-
self.max_universe.hash(state);
66-
self.variables.hash(state);
67-
}
68-
}
69-
7064
impl<CTX: HashStableContext, I: Interner, V: HashStable<CTX>> HashStable<CTX> for Canonical<I, V>
7165
where
7266
I::CanonicalVars: HashStable<CTX>,
@@ -108,16 +102,6 @@ impl<I: Interner, V: fmt::Debug> fmt::Debug for Canonical<I, V> {
108102
}
109103
}
110104

111-
impl<I: Interner, V: Clone> Clone for Canonical<I, V> {
112-
fn clone(&self) -> Self {
113-
Canonical {
114-
value: self.value.clone(),
115-
max_universe: self.max_universe.clone(),
116-
variables: self.variables.clone(),
117-
}
118-
}
119-
}
120-
121105
impl<I: Interner, V: Copy> Copy for Canonical<I, V> where I::CanonicalVars: Copy {}
122106

123107
impl<I: Interner, V: TypeFoldable<I>> TypeFoldable<I> for Canonical<I, V>

compiler/rustc_type_ir/src/const_kind.rs

+9-64
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use rustc_data_structures::stable_hasher::HashStable;
22
use rustc_data_structures::stable_hasher::StableHasher;
33
use rustc_serialize::{Decodable, Decoder, Encodable};
4-
use std::cmp::Ordering;
54
use std::fmt;
6-
use std::hash;
75

86
use crate::{
97
DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, TyDecoder,
@@ -13,7 +11,15 @@ use crate::{
1311
use self::ConstKind::*;
1412

1513
/// Represents a constant in Rust.
16-
// #[derive(derive_more::From)]
14+
#[derive(derivative::Derivative)]
15+
#[derivative(
16+
Clone(bound = ""),
17+
PartialOrd(bound = ""),
18+
PartialOrd = "feature_allow_slow_enum",
19+
Ord(bound = ""),
20+
Ord = "feature_allow_slow_enum",
21+
Hash(bound = "")
22+
)]
1723
pub enum ConstKind<I: Interner> {
1824
/// A const generic parameter.
1925
Param(I::ParamConst),
@@ -57,25 +63,6 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
5763
}
5864
}
5965

60-
impl<I: Interner> hash::Hash for ConstKind<I> {
61-
fn hash<H: hash::Hasher>(&self, state: &mut H) {
62-
const_kind_discriminant(self).hash(state);
63-
match self {
64-
Param(p) => p.hash(state),
65-
Infer(i) => i.hash(state),
66-
Bound(d, b) => {
67-
d.hash(state);
68-
b.hash(state);
69-
}
70-
Placeholder(p) => p.hash(state),
71-
Unevaluated(u) => u.hash(state),
72-
Value(v) => v.hash(state),
73-
Error(e) => e.hash(state),
74-
Expr(e) => e.hash(state),
75-
}
76-
}
77-
}
78-
7966
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
8067
where
8168
I::ParamConst: HashStable<CTX>,
@@ -166,33 +153,6 @@ where
166153
}
167154
}
168155

169-
impl<I: Interner> PartialOrd for ConstKind<I> {
170-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
171-
Some(self.cmp(other))
172-
}
173-
}
174-
175-
impl<I: Interner> Ord for ConstKind<I> {
176-
fn cmp(&self, other: &Self) -> Ordering {
177-
const_kind_discriminant(self)
178-
.cmp(&const_kind_discriminant(other))
179-
.then_with(|| match (self, other) {
180-
(Param(p1), Param(p2)) => p1.cmp(p2),
181-
(Infer(i1), Infer(i2)) => i1.cmp(i2),
182-
(Bound(d1, b1), Bound(d2, b2)) => d1.cmp(d2).then_with(|| b1.cmp(b2)),
183-
(Placeholder(p1), Placeholder(p2)) => p1.cmp(p2),
184-
(Unevaluated(u1), Unevaluated(u2)) => u1.cmp(u2),
185-
(Value(v1), Value(v2)) => v1.cmp(v2),
186-
(Error(e1), Error(e2)) => e1.cmp(e2),
187-
(Expr(e1), Expr(e2)) => e1.cmp(e2),
188-
_ => {
189-
debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}");
190-
Ordering::Equal
191-
}
192-
})
193-
}
194-
}
195-
196156
impl<I: Interner> PartialEq for ConstKind<I> {
197157
fn eq(&self, other: &Self) -> bool {
198158
match (self, other) {
@@ -211,21 +171,6 @@ impl<I: Interner> PartialEq for ConstKind<I> {
211171

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

214-
impl<I: Interner> Clone for ConstKind<I> {
215-
fn clone(&self) -> Self {
216-
match self {
217-
Param(arg0) => Param(arg0.clone()),
218-
Infer(arg0) => Infer(arg0.clone()),
219-
Bound(arg0, arg1) => Bound(arg0.clone(), arg1.clone()),
220-
Placeholder(arg0) => Placeholder(arg0.clone()),
221-
Unevaluated(arg0) => Unevaluated(arg0.clone()),
222-
Value(arg0) => Value(arg0.clone()),
223-
Error(arg0) => Error(arg0.clone()),
224-
Expr(arg0) => Expr(arg0.clone()),
225-
}
226-
}
227-
}
228-
229174
impl<I: Interner> fmt::Debug for ConstKind<I> {
230175
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
231176
WithInfcx::with_no_infcx(self).fmt(f)

compiler/rustc_type_ir/src/predicate_kind.rs

+4-79
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
22
use rustc_serialize::Decoder;
33
use rustc_serialize::{Decodable, Encodable};
44
use std::fmt;
5-
use std::hash;
65
use std::ops::ControlFlow;
76

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

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

42-
impl<I: Interner> Clone for ClauseKind<I> {
43-
fn clone(&self) -> Self {
44-
match self {
45-
Self::Trait(arg0) => Self::Trait(arg0.clone()),
46-
Self::RegionOutlives(arg0) => Self::RegionOutlives(arg0.clone()),
47-
Self::TypeOutlives(arg0) => Self::TypeOutlives(arg0.clone()),
48-
Self::Projection(arg0) => Self::Projection(arg0.clone()),
49-
Self::ConstArgHasType(arg0, arg1) => Self::ConstArgHasType(arg0.clone(), arg1.clone()),
50-
Self::WellFormed(arg0) => Self::WellFormed(arg0.clone()),
51-
Self::ConstEvaluatable(arg0) => Self::ConstEvaluatable(arg0.clone()),
52-
}
53-
}
54-
}
55-
5643
impl<I: Interner> Copy for ClauseKind<I>
5744
where
5845
I::Ty: Copy,
@@ -94,24 +81,6 @@ fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> usize {
9481
}
9582
}
9683

97-
impl<I: Interner> hash::Hash for ClauseKind<I> {
98-
fn hash<H: hash::Hasher>(&self, state: &mut H) {
99-
clause_kind_discriminant(self).hash(state);
100-
match self {
101-
ClauseKind::Trait(p) => p.hash(state),
102-
ClauseKind::RegionOutlives(p) => p.hash(state),
103-
ClauseKind::TypeOutlives(p) => p.hash(state),
104-
ClauseKind::Projection(p) => p.hash(state),
105-
ClauseKind::ConstArgHasType(c, t) => {
106-
c.hash(state);
107-
t.hash(state);
108-
}
109-
ClauseKind::WellFormed(t) => t.hash(state),
110-
ClauseKind::ConstEvaluatable(c) => c.hash(state),
111-
}
112-
}
113-
}
114-
11584
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ClauseKind<I>
11685
where
11786
I::Ty: HashStable<CTX>,
@@ -249,6 +218,8 @@ where
249218
}
250219
}
251220

221+
#[derive(derivative::Derivative)]
222+
#[derivative(Clone(bound = ""), Hash(bound = ""))]
252223
pub enum PredicateKind<I: Interner> {
253224
/// Prove a clause
254225
Clause(ClauseKind<I>),
@@ -305,25 +276,6 @@ where
305276
{
306277
}
307278

308-
impl<I: Interner> Clone for PredicateKind<I> {
309-
fn clone(&self) -> Self {
310-
match self {
311-
Self::Clause(arg0) => Self::Clause(arg0.clone()),
312-
Self::ObjectSafe(arg0) => Self::ObjectSafe(arg0.clone()),
313-
Self::ClosureKind(arg0, arg1, arg2) => {
314-
Self::ClosureKind(arg0.clone(), arg1.clone(), arg2.clone())
315-
}
316-
Self::Subtype(arg0) => Self::Subtype(arg0.clone()),
317-
Self::Coerce(arg0) => Self::Coerce(arg0.clone()),
318-
Self::ConstEquate(arg0, arg1) => Self::ConstEquate(arg0.clone(), arg1.clone()),
319-
Self::Ambiguous => Self::Ambiguous,
320-
Self::AliasRelate(arg0, arg1, arg2) => {
321-
Self::AliasRelate(arg0.clone(), arg1.clone(), arg2.clone())
322-
}
323-
}
324-
}
325-
}
326-
327279
impl<I: Interner> PartialEq for PredicateKind<I> {
328280
fn eq(&self, other: &Self) -> bool {
329281
match (self, other) {
@@ -358,33 +310,6 @@ fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> usize {
358310
}
359311
}
360312

361-
impl<I: Interner> hash::Hash for PredicateKind<I> {
362-
fn hash<H: hash::Hasher>(&self, state: &mut H) {
363-
predicate_kind_discriminant(self).hash(state);
364-
match self {
365-
PredicateKind::Clause(p) => p.hash(state),
366-
PredicateKind::ObjectSafe(d) => d.hash(state),
367-
PredicateKind::ClosureKind(d, g, k) => {
368-
d.hash(state);
369-
g.hash(state);
370-
k.hash(state);
371-
}
372-
PredicateKind::Subtype(p) => p.hash(state),
373-
PredicateKind::Coerce(p) => p.hash(state),
374-
PredicateKind::ConstEquate(c1, c2) => {
375-
c1.hash(state);
376-
c2.hash(state);
377-
}
378-
PredicateKind::Ambiguous => {}
379-
PredicateKind::AliasRelate(t1, t2, r) => {
380-
t1.hash(state);
381-
t2.hash(state);
382-
r.hash(state);
383-
}
384-
}
385-
}
386-
}
387-
388313
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for PredicateKind<I>
389314
where
390315
I::DefId: HashStable<CTX>,

0 commit comments

Comments
 (0)