8
8
//! In this case we try to build an abstract representation of this constant using
9
9
//! `mir_abstract_const` which can then be checked for structural equality with other
10
10
//! generic constants mentioned in the `caller_bounds` of the current environment.
11
+ use crate :: traits:: ty:: subst:: GenericArg ;
11
12
use rustc_errors:: ErrorReported ;
12
13
use rustc_hir:: def:: DefKind ;
13
14
use rustc_index:: bit_set:: BitSet ;
@@ -80,9 +81,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
80
81
Concrete ,
81
82
}
82
83
let mut failure_kind = FailureKind :: Concrete ;
83
- walk_abstract_const :: < !, _ > ( tcx, ct, |node| match node. root ( ) {
84
+ walk_abstract_const :: < !, _ > ( tcx, ct, |node| match node. root ( tcx , ct . substs ) {
84
85
Node :: Leaf ( leaf) => {
85
- let leaf = leaf. subst ( tcx, ct. substs ) ;
86
86
if leaf. has_infer_types_or_consts ( ) {
87
87
failure_kind = FailureKind :: MentionsInfer ;
88
88
} else if leaf. definitely_has_param_types_or_consts ( tcx) {
@@ -92,7 +92,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
92
92
ControlFlow :: CONTINUE
93
93
}
94
94
Node :: Cast ( _, _, ty) => {
95
- let ty = ty. subst ( tcx, ct. substs ) ;
96
95
if ty. has_infer_types_or_consts ( ) {
97
96
failure_kind = FailureKind :: MentionsInfer ;
98
97
} else if ty. definitely_has_param_types_or_consts ( tcx) {
@@ -218,8 +217,12 @@ impl<'tcx> AbstractConst<'tcx> {
218
217
}
219
218
220
219
#[ inline]
221
- pub fn root ( self ) -> Node < ' tcx > {
222
- self . inner . last ( ) . copied ( ) . unwrap ( )
220
+ pub fn root ( self , tcx : TyCtxt < ' tcx > , substs : & [ GenericArg < ' tcx > ] ) -> Node < ' tcx > {
221
+ let mut node = self . inner . last ( ) . copied ( ) . unwrap ( ) ;
222
+ if let Node :: Leaf ( leaf) = node {
223
+ node = Node :: Leaf ( leaf. subst ( tcx, substs) ) ;
224
+ }
225
+ node
223
226
}
224
227
}
225
228
@@ -587,7 +590,7 @@ where
587
590
f : & mut dyn FnMut ( AbstractConst < ' tcx > ) -> ControlFlow < R > ,
588
591
) -> ControlFlow < R > {
589
592
f ( ct) ?;
590
- let root = ct. root ( ) ;
593
+ let root = ct. root ( tcx , ct . substs ) ;
591
594
match root {
592
595
Node :: Leaf ( _) => ControlFlow :: CONTINUE ,
593
596
Node :: Binop ( _, l, r) => {
@@ -615,27 +618,23 @@ pub(super) fn try_unify<'tcx>(
615
618
// We substitute generics repeatedly to allow AbstractConsts to unify where a
616
619
// ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
617
620
// Param(N) should unify with Param(T), substs: [Unevaluated("T2", [Unevaluated("T3", [Param(N)])])]
618
- while let Node :: Leaf ( a_ct) = a. root ( ) {
619
- let a_ct = a_ct. subst ( tcx, a. substs ) ;
621
+ while let Node :: Leaf ( a_ct) = a. root ( tcx, a. substs ) {
620
622
match AbstractConst :: from_const ( tcx, a_ct) {
621
623
Ok ( Some ( a_act) ) => a = a_act,
622
624
Ok ( None ) => break ,
623
625
Err ( _) => return true ,
624
626
}
625
627
}
626
- while let Node :: Leaf ( b_ct) = b. root ( ) {
627
- let b_ct = b_ct. subst ( tcx, b. substs ) ;
628
+ while let Node :: Leaf ( b_ct) = b. root ( tcx, b. substs ) {
628
629
match AbstractConst :: from_const ( tcx, b_ct) {
629
630
Ok ( Some ( b_act) ) => b = b_act,
630
631
Ok ( None ) => break ,
631
632
Err ( _) => return true ,
632
633
}
633
634
}
634
635
635
- match ( a. root ( ) , b. root ( ) ) {
636
+ match ( a. root ( tcx , a . substs ) , b. root ( tcx , b . substs ) ) {
636
637
( Node :: Leaf ( a_ct) , Node :: Leaf ( b_ct) ) => {
637
- let a_ct = a_ct. subst ( tcx, a. substs ) ;
638
- let b_ct = b_ct. subst ( tcx, b. substs ) ;
639
638
if a_ct. ty != b_ct. ty {
640
639
return false ;
641
640
}
0 commit comments