88//! In this case we try to build an abstract representation of this constant using
99//! `mir_abstract_const` which can then be checked for structural equality with other
1010//! generic constants mentioned in the `caller_bounds` of the current environment.
11+ use crate :: traits:: ty:: subst:: GenericArg ;
1112use rustc_errors:: ErrorReported ;
1213use rustc_hir:: def:: DefKind ;
1314use rustc_index:: bit_set:: BitSet ;
@@ -80,9 +81,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
8081 Concrete ,
8182 }
8283 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 ) {
8485 Node :: Leaf ( leaf) => {
85- let leaf = leaf. subst ( tcx, ct. substs ) ;
8686 if leaf. has_infer_types_or_consts ( ) {
8787 failure_kind = FailureKind :: MentionsInfer ;
8888 } else if leaf. definitely_has_param_types_or_consts ( tcx) {
@@ -92,7 +92,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
9292 ControlFlow :: CONTINUE
9393 }
9494 Node :: Cast ( _, _, ty) => {
95- let ty = ty. subst ( tcx, ct. substs ) ;
9695 if ty. has_infer_types_or_consts ( ) {
9796 failure_kind = FailureKind :: MentionsInfer ;
9897 } else if ty. definitely_has_param_types_or_consts ( tcx) {
@@ -218,8 +217,12 @@ impl<'tcx> AbstractConst<'tcx> {
218217 }
219218
220219 #[ 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
223226 }
224227}
225228
@@ -587,7 +590,7 @@ where
587590 f : & mut dyn FnMut ( AbstractConst < ' tcx > ) -> ControlFlow < R > ,
588591 ) -> ControlFlow < R > {
589592 f ( ct) ?;
590- let root = ct. root ( ) ;
593+ let root = ct. root ( tcx , ct . substs ) ;
591594 match root {
592595 Node :: Leaf ( _) => ControlFlow :: CONTINUE ,
593596 Node :: Binop ( _, l, r) => {
@@ -615,27 +618,23 @@ pub(super) fn try_unify<'tcx>(
615618 // We substitute generics repeatedly to allow AbstractConsts to unify where a
616619 // ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
617620 // 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 ) {
620622 match AbstractConst :: from_const ( tcx, a_ct) {
621623 Ok ( Some ( a_act) ) => a = a_act,
622624 Ok ( None ) => break ,
623625 Err ( _) => return true ,
624626 }
625627 }
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 ) {
628629 match AbstractConst :: from_const ( tcx, b_ct) {
629630 Ok ( Some ( b_act) ) => b = b_act,
630631 Ok ( None ) => break ,
631632 Err ( _) => return true ,
632633 }
633634 }
634635
635- match ( a. root ( ) , b. root ( ) ) {
636+ match ( a. root ( tcx , a . substs ) , b. root ( tcx , b . substs ) ) {
636637 ( 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 ) ;
639638 if a_ct. ty != b_ct. ty {
640639 return false ;
641640 }
0 commit comments