@@ -80,9 +80,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
80
80
Concrete ,
81
81
}
82
82
let mut failure_kind = FailureKind :: Concrete ;
83
- walk_abstract_const :: < !, _ > ( tcx, ct, |node| match node. root ( ) {
83
+ walk_abstract_const :: < !, _ > ( tcx, ct, |node| match node. root ( tcx ) {
84
84
Node :: Leaf ( leaf) => {
85
- let leaf = leaf. subst ( tcx, ct. substs ) ;
86
85
if leaf. has_infer_types_or_consts ( ) {
87
86
failure_kind = FailureKind :: MentionsInfer ;
88
87
} else if leaf. definitely_has_param_types_or_consts ( tcx) {
@@ -92,7 +91,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
92
91
ControlFlow :: CONTINUE
93
92
}
94
93
Node :: Cast ( _, _, ty) => {
95
- let ty = ty. subst ( tcx, ct. substs ) ;
96
94
if ty. has_infer_types_or_consts ( ) {
97
95
failure_kind = FailureKind :: MentionsInfer ;
98
96
} else if ty. definitely_has_param_types_or_consts ( tcx) {
@@ -187,8 +185,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
187
185
pub struct AbstractConst < ' tcx > {
188
186
// FIXME: Consider adding something like `IndexSlice`
189
187
// and use this here.
190
- pub inner : & ' tcx [ Node < ' tcx > ] ,
191
- pub substs : SubstsRef < ' tcx > ,
188
+ inner : & ' tcx [ Node < ' tcx > ] ,
189
+ substs : SubstsRef < ' tcx > ,
192
190
}
193
191
194
192
impl < ' tcx > AbstractConst < ' tcx > {
@@ -218,8 +216,14 @@ impl<'tcx> AbstractConst<'tcx> {
218
216
}
219
217
220
218
#[ inline]
221
- pub fn root ( self ) -> Node < ' tcx > {
222
- self . inner . last ( ) . copied ( ) . unwrap ( )
219
+ pub fn root ( self , tcx : TyCtxt < ' tcx > ) -> Node < ' tcx > {
220
+ let node = self . inner . last ( ) . copied ( ) . unwrap ( ) ;
221
+ match node {
222
+ Node :: Leaf ( leaf) => Node :: Leaf ( leaf. subst ( tcx, self . substs ) ) ,
223
+ Node :: Cast ( kind, operand, ty) => Node :: Cast ( kind, operand, ty. subst ( tcx, self . substs ) ) ,
224
+ // Don't perform substitution on the following as they can't directly contain generic params
225
+ Node :: Binop ( _, _, _) | Node :: UnaryOp ( _, _) | Node :: FunctionCall ( _, _) => node,
226
+ }
223
227
}
224
228
}
225
229
@@ -542,7 +546,7 @@ where
542
546
f : & mut dyn FnMut ( AbstractConst < ' tcx > ) -> ControlFlow < R > ,
543
547
) -> ControlFlow < R > {
544
548
f ( ct) ?;
545
- let root = ct. root ( ) ;
549
+ let root = ct. root ( tcx ) ;
546
550
match root {
547
551
Node :: Leaf ( _) => ControlFlow :: CONTINUE ,
548
552
Node :: Binop ( _, l, r) => {
@@ -570,27 +574,23 @@ pub(super) fn try_unify<'tcx>(
570
574
// We substitute generics repeatedly to allow AbstractConsts to unify where a
571
575
// ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
572
576
// Param(N) should unify with Param(T), substs: [Unevaluated("T2", [Unevaluated("T3", [Param(N)])])]
573
- while let Node :: Leaf ( a_ct) = a. root ( ) {
574
- let a_ct = a_ct. subst ( tcx, a. substs ) ;
577
+ while let Node :: Leaf ( a_ct) = a. root ( tcx) {
575
578
match AbstractConst :: from_const ( tcx, a_ct) {
576
579
Ok ( Some ( a_act) ) => a = a_act,
577
580
Ok ( None ) => break ,
578
581
Err ( _) => return true ,
579
582
}
580
583
}
581
- while let Node :: Leaf ( b_ct) = b. root ( ) {
582
- let b_ct = b_ct. subst ( tcx, b. substs ) ;
584
+ while let Node :: Leaf ( b_ct) = b. root ( tcx) {
583
585
match AbstractConst :: from_const ( tcx, b_ct) {
584
586
Ok ( Some ( b_act) ) => b = b_act,
585
587
Ok ( None ) => break ,
586
588
Err ( _) => return true ,
587
589
}
588
590
}
589
591
590
- match ( a. root ( ) , b. root ( ) ) {
592
+ match ( a. root ( tcx ) , b. root ( tcx ) ) {
591
593
( Node :: Leaf ( a_ct) , Node :: Leaf ( b_ct) ) => {
592
- let a_ct = a_ct. subst ( tcx, a. substs ) ;
593
- let b_ct = b_ct. subst ( tcx, b. substs ) ;
594
594
if a_ct. ty != b_ct. ty {
595
595
return false ;
596
596
}
0 commit comments