@@ -39,7 +39,7 @@ use rustc_hir::def_id::DefId;
39
39
use rustc_middle:: ty:: error:: TypeError ;
40
40
use rustc_middle:: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
41
41
use rustc_middle:: ty:: subst:: SubstsRef ;
42
- use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt } ;
42
+ use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt , TypeFoldable } ;
43
43
use rustc_middle:: ty:: { IntType , UintType } ;
44
44
use rustc_span:: { Span , DUMMY_SP } ;
45
45
@@ -126,7 +126,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
126
126
b : & ' tcx ty:: Const < ' tcx > ,
127
127
) -> RelateResult < ' tcx , & ' tcx ty:: Const < ' tcx > >
128
128
where
129
- R : TypeRelation < ' tcx > ,
129
+ R : ConstEquateRelation < ' tcx > ,
130
130
{
131
131
debug ! ( "{}.consts({:?}, {:?})" , relation. tag( ) , a, b) ;
132
132
if a == b {
@@ -164,7 +164,22 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
164
164
( _, ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) ) => {
165
165
return self . unify_const_variable ( !a_is_expected, vid, a) ;
166
166
}
167
-
167
+ ( ty:: ConstKind :: Unevaluated ( ..) , _) if self . tcx . lazy_normalization ( ) => {
168
+ // FIXME(#59490): Need to remove the leak check to accomodate
169
+ // escaping bound variables here.
170
+ if !a. has_escaping_bound_vars ( ) && !b. has_escaping_bound_vars ( ) {
171
+ relation. const_equate_obligation ( a, b) ;
172
+ }
173
+ return Ok ( b) ;
174
+ }
175
+ ( _, ty:: ConstKind :: Unevaluated ( ..) ) if self . tcx . lazy_normalization ( ) => {
176
+ // FIXME(#59490): Need to remove the leak check to accomodate
177
+ // escaping bound variables here.
178
+ if !a. has_escaping_bound_vars ( ) && !b. has_escaping_bound_vars ( ) {
179
+ relation. const_equate_obligation ( a, b) ;
180
+ }
181
+ return Ok ( a) ;
182
+ }
168
183
_ => { }
169
184
}
170
185
@@ -375,6 +390,20 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
375
390
debug ! ( "generalize: success {{ {:?}, {:?} }}" , ty, needs_wf) ;
376
391
Ok ( Generalization { ty, needs_wf } )
377
392
}
393
+
394
+ pub fn add_const_equate_obligation (
395
+ & mut self ,
396
+ a_is_expected : bool ,
397
+ a : & ' tcx ty:: Const < ' tcx > ,
398
+ b : & ' tcx ty:: Const < ' tcx > ,
399
+ ) {
400
+ let predicate = if a_is_expected {
401
+ ty:: Predicate :: ConstEquate ( a, b)
402
+ } else {
403
+ ty:: Predicate :: ConstEquate ( b, a)
404
+ } ;
405
+ self . obligations . push ( Obligation :: new ( self . trace . cause . clone ( ) , self . param_env , predicate) ) ;
406
+ }
378
407
}
379
408
380
409
struct Generalizer < ' cx , ' tcx > {
@@ -637,11 +666,19 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
637
666
}
638
667
}
639
668
}
669
+ ty:: ConstKind :: Unevaluated ( ..) if self . tcx ( ) . lazy_normalization ( ) => Ok ( c) ,
640
670
_ => relate:: super_relate_consts ( self , c, c) ,
641
671
}
642
672
}
643
673
}
644
674
675
+ pub trait ConstEquateRelation < ' tcx > : TypeRelation < ' tcx > {
676
+ /// Register an obligation that both constants must be equal to each other.
677
+ ///
678
+ /// If they aren't equal then the relation doesn't hold.
679
+ fn const_equate_obligation ( & mut self , a : & ' tcx ty:: Const < ' tcx > , b : & ' tcx ty:: Const < ' tcx > ) ;
680
+ }
681
+
645
682
pub trait RelateResultCompare < ' tcx , T > {
646
683
fn compare < F > ( & self , t : T , f : F ) -> RelateResult < ' tcx , T >
647
684
where
0 commit comments