Skip to content

Commit 3a5bf11

Browse files
Fast-path some relations via strict equality
1 parent ff0ffda commit 3a5bf11

File tree

11 files changed

+67
-2
lines changed

11 files changed

+67
-2
lines changed

compiler/rustc_hir_analysis/src/check/dropck.rs

+4
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
248248
self.param_env
249249
}
250250

251+
fn fast_equate_combine(&self) -> bool {
252+
true
253+
}
254+
251255
fn tag(&self) -> &'static str {
252256
"dropck::SimpleEqRelation"
253257
}

compiler/rustc_infer/src/infer/combine.rs

+8
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
525525
self.param_env
526526
}
527527

528+
fn fast_equate_combine(&self) -> bool {
529+
false
530+
}
531+
528532
fn tag(&self) -> &'static str {
529533
"Generalizer"
530534
}
@@ -802,6 +806,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
802806
self.param_env
803807
}
804808

809+
fn fast_equate_combine(&self) -> bool {
810+
false
811+
}
812+
805813
fn tag(&self) -> &'static str {
806814
"ConstInferUnifier"
807815
}

compiler/rustc_infer/src/infer/equate.rs

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
3232
self.fields.tcx()
3333
}
3434

35+
fn fast_equate_combine(&self) -> bool {
36+
true
37+
}
38+
3539
fn param_env(&self) -> ty::ParamEnv<'tcx> {
3640
self.fields.param_env
3741
}

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2945,6 +2945,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
29452945
"SameTypeModuloInfer"
29462946
}
29472947

2948+
fn fast_equate_combine(&self) -> bool {
2949+
true
2950+
}
2951+
29482952
fn a_is_expected(&self) -> bool {
29492953
true
29502954
}

compiler/rustc_infer/src/infer/glb.rs

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
3434
self.fields.tcx()
3535
}
3636

37+
fn fast_equate_combine(&self) -> bool {
38+
true
39+
}
40+
3741
fn param_env(&self) -> ty::ParamEnv<'tcx> {
3842
self.fields.param_env
3943
}

compiler/rustc_infer/src/infer/lub.rs

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
3434
self.fields.tcx()
3535
}
3636

37+
fn fast_equate_combine(&self) -> bool {
38+
true
39+
}
40+
3741
fn param_env(&self) -> ty::ParamEnv<'tcx> {
3842
self.fields.param_env
3943
}

compiler/rustc_infer/src/infer/nll_relate/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,10 @@ where
535535
self.delegate.param_env()
536536
}
537537

538+
fn fast_equate_combine(&self) -> bool {
539+
false
540+
}
541+
538542
fn tag(&self) -> &'static str {
539543
"nll::subtype"
540544
}
@@ -901,6 +905,10 @@ where
901905
self.delegate.param_env()
902906
}
903907

908+
fn fast_equate_combine(&self) -> bool {
909+
false
910+
}
911+
904912
fn tag(&self) -> &'static str {
905913
"nll::generalizer"
906914
}

compiler/rustc_infer/src/infer/outlives/test_type_match.rs

+3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
142142
fn param_env(&self) -> ty::ParamEnv<'tcx> {
143143
self.param_env
144144
}
145+
fn fast_equate_combine(&self) -> bool {
146+
false
147+
}
145148
fn a_is_expected(&self) -> bool {
146149
true
147150
} // irrelevant

compiler/rustc_infer/src/infer/sub.rs

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
4343
self.fields.param_env
4444
}
4545

46+
fn fast_equate_combine(&self) -> bool {
47+
true
48+
}
49+
4650
fn a_is_expected(&self) -> bool {
4751
self.a_is_expected
4852
}

compiler/rustc_middle/src/ty/_match.rs

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
3939
fn param_env(&self) -> ty::ParamEnv<'tcx> {
4040
self.param_env
4141
}
42+
fn fast_equate_combine(&self) -> bool {
43+
false
44+
}
4245
fn a_is_expected(&self) -> bool {
4346
true
4447
} // irrelevant

compiler/rustc_middle/src/ty/relate.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ pub trait TypeRelation<'tcx>: Sized {
2828
/// Returns a static string we can use for printouts.
2929
fn tag(&self) -> &'static str;
3030

31+
/// Returns whether or not structural equality can be used to fast-path this relation
32+
fn fast_equate_combine(&self) -> bool;
33+
3134
/// Returns `true` if the value `a` is the "expected" type in the
3235
/// relation. Just affects error messages.
3336
fn a_is_expected(&self) -> bool;
@@ -140,6 +143,10 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
140143
a_subst: SubstsRef<'tcx>,
141144
b_subst: SubstsRef<'tcx>,
142145
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
146+
if relation.fast_equate_combine() && a_subst == b_subst {
147+
return Ok(a_subst);
148+
}
149+
143150
relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| {
144151
relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
145152
}))
@@ -152,6 +159,10 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
152159
a_subst: SubstsRef<'tcx>,
153160
b_subst: SubstsRef<'tcx>,
154161
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
162+
if relation.fast_equate_combine() && a_subst == b_subst {
163+
return Ok(a_subst);
164+
}
165+
155166
let tcx = relation.tcx();
156167

157168
let mut cached_ty = None;
@@ -345,7 +356,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
345356
}
346357
}
347358

348-
#[derive(Copy, Debug, Clone, TypeFoldable, TypeVisitable)]
359+
#[derive(Copy, Debug, Clone, PartialEq, Eq, TypeFoldable, TypeVisitable)]
349360
struct GeneratorWitness<'tcx>(&'tcx ty::List<Ty<'tcx>>);
350361

351362
impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
@@ -354,6 +365,10 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
354365
a: GeneratorWitness<'tcx>,
355366
b: GeneratorWitness<'tcx>,
356367
) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
368+
if relation.fast_equate_combine() && a == b {
369+
return Ok(a);
370+
}
371+
357372
assert_eq!(a.0.len(), b.0.len());
358373
let tcx = relation.tcx();
359374
let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
@@ -655,6 +670,10 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredi
655670
a: Self,
656671
b: Self,
657672
) -> RelateResult<'tcx, Self> {
673+
if relation.fast_equate_combine() && a == b {
674+
return Ok(a);
675+
}
676+
658677
let tcx = relation.tcx();
659678

660679
// FIXME: this is wasteful, but want to do a perf run to see how slow it is.
@@ -799,9 +818,9 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
799818
b: ty::TraitPredicate<'tcx>,
800819
) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> {
801820
Ok(ty::TraitPredicate {
802-
trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
803821
constness: relation.relate(a.constness, b.constness)?,
804822
polarity: relation.relate(a.polarity, b.polarity)?,
823+
trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
805824
})
806825
}
807826
}

0 commit comments

Comments
 (0)