@@ -28,6 +28,9 @@ pub trait TypeRelation<'tcx>: Sized {
28
28
/// Returns a static string we can use for printouts.
29
29
fn tag ( & self ) -> & ' static str ;
30
30
31
+ /// Returns whether or not structural equality can be used to fast-path this relation
32
+ fn fast_equate_combine ( & self ) -> bool ;
33
+
31
34
/// Returns `true` if the value `a` is the "expected" type in the
32
35
/// relation. Just affects error messages.
33
36
fn a_is_expected ( & self ) -> bool ;
@@ -140,6 +143,10 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
140
143
a_subst : SubstsRef < ' tcx > ,
141
144
b_subst : SubstsRef < ' tcx > ,
142
145
) -> RelateResult < ' tcx , SubstsRef < ' tcx > > {
146
+ if relation. fast_equate_combine ( ) && a_subst == b_subst {
147
+ return Ok ( a_subst) ;
148
+ }
149
+
143
150
relation. tcx ( ) . mk_substs ( iter:: zip ( a_subst, b_subst) . map ( |( a, b) | {
144
151
relation. relate_with_variance ( ty:: Invariant , ty:: VarianceDiagInfo :: default ( ) , a, b)
145
152
} ) )
@@ -152,6 +159,10 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
152
159
a_subst : SubstsRef < ' tcx > ,
153
160
b_subst : SubstsRef < ' tcx > ,
154
161
) -> RelateResult < ' tcx , SubstsRef < ' tcx > > {
162
+ if relation. fast_equate_combine ( ) && a_subst == b_subst {
163
+ return Ok ( a_subst) ;
164
+ }
165
+
155
166
let tcx = relation. tcx ( ) ;
156
167
157
168
let mut cached_ty = None ;
@@ -345,7 +356,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
345
356
}
346
357
}
347
358
348
- #[ derive( Copy , Debug , Clone , TypeFoldable , TypeVisitable ) ]
359
+ #[ derive( Copy , Debug , Clone , PartialEq , Eq , TypeFoldable , TypeVisitable ) ]
349
360
struct GeneratorWitness < ' tcx > ( & ' tcx ty:: List < Ty < ' tcx > > ) ;
350
361
351
362
impl < ' tcx > Relate < ' tcx > for GeneratorWitness < ' tcx > {
@@ -354,6 +365,10 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
354
365
a : GeneratorWitness < ' tcx > ,
355
366
b : GeneratorWitness < ' tcx > ,
356
367
) -> RelateResult < ' tcx , GeneratorWitness < ' tcx > > {
368
+ if relation. fast_equate_combine ( ) && a == b {
369
+ return Ok ( a) ;
370
+ }
371
+
357
372
assert_eq ! ( a. 0 . len( ) , b. 0 . len( ) ) ;
358
373
let tcx = relation. tcx ( ) ;
359
374
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
655
670
a : Self ,
656
671
b : Self ,
657
672
) -> RelateResult < ' tcx , Self > {
673
+ if relation. fast_equate_combine ( ) && a == b {
674
+ return Ok ( a) ;
675
+ }
676
+
658
677
let tcx = relation. tcx ( ) ;
659
678
660
679
// 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> {
799
818
b : ty:: TraitPredicate < ' tcx > ,
800
819
) -> RelateResult < ' tcx , ty:: TraitPredicate < ' tcx > > {
801
820
Ok ( ty:: TraitPredicate {
802
- trait_ref : relation. relate ( a. trait_ref , b. trait_ref ) ?,
803
821
constness : relation. relate ( a. constness , b. constness ) ?,
804
822
polarity : relation. relate ( a. polarity , b. polarity ) ?,
823
+ trait_ref : relation. relate ( a. trait_ref , b. trait_ref ) ?,
805
824
} )
806
825
}
807
826
}
0 commit comments