@@ -80,9 +80,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
8080 Concrete ,
8181 }
8282 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 ) {
8484 Node :: Leaf ( leaf) => {
85- let leaf = leaf. subst ( tcx, ct. substs ) ;
8685 if leaf. has_infer_types_or_consts ( ) {
8786 failure_kind = FailureKind :: MentionsInfer ;
8887 } else if leaf. definitely_has_param_types_or_consts ( tcx) {
@@ -92,7 +91,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
9291 ControlFlow :: CONTINUE
9392 }
9493 Node :: Cast ( _, _, ty) => {
95- let ty = ty. subst ( tcx, ct. substs ) ;
9694 if ty. has_infer_types_or_consts ( ) {
9795 failure_kind = FailureKind :: MentionsInfer ;
9896 } else if ty. definitely_has_param_types_or_consts ( tcx) {
@@ -187,8 +185,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
187185pub struct AbstractConst < ' tcx > {
188186 // FIXME: Consider adding something like `IndexSlice`
189187 // and use this here.
190- pub inner : & ' tcx [ Node < ' tcx > ] ,
191- pub substs : SubstsRef < ' tcx > ,
188+ inner : & ' tcx [ Node < ' tcx > ] ,
189+ substs : SubstsRef < ' tcx > ,
192190}
193191
194192impl < ' tcx > AbstractConst < ' tcx > {
@@ -218,8 +216,14 @@ impl<'tcx> AbstractConst<'tcx> {
218216 }
219217
220218 #[ 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+ }
223227 }
224228}
225229
@@ -542,7 +546,7 @@ where
542546 f : & mut dyn FnMut ( AbstractConst < ' tcx > ) -> ControlFlow < R > ,
543547 ) -> ControlFlow < R > {
544548 f ( ct) ?;
545- let root = ct. root ( ) ;
549+ let root = ct. root ( tcx ) ;
546550 match root {
547551 Node :: Leaf ( _) => ControlFlow :: CONTINUE ,
548552 Node :: Binop ( _, l, r) => {
@@ -570,27 +574,23 @@ pub(super) fn try_unify<'tcx>(
570574 // We substitute generics repeatedly to allow AbstractConsts to unify where a
571575 // ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
572576 // 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) {
575578 match AbstractConst :: from_const ( tcx, a_ct) {
576579 Ok ( Some ( a_act) ) => a = a_act,
577580 Ok ( None ) => break ,
578581 Err ( _) => return true ,
579582 }
580583 }
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) {
583585 match AbstractConst :: from_const ( tcx, b_ct) {
584586 Ok ( Some ( b_act) ) => b = b_act,
585587 Ok ( None ) => break ,
586588 Err ( _) => return true ,
587589 }
588590 }
589591
590- match ( a. root ( ) , b. root ( ) ) {
592+ match ( a. root ( tcx ) , b. root ( tcx ) ) {
591593 ( 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 ) ;
594594 if a_ct. ty != b_ct. ty {
595595 return false ;
596596 }
0 commit comments