@@ -50,11 +50,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
50
50
if b_def == def && b_substs == substs {
51
51
debug ! ( "is_const_evaluatable: caller_bound ~~> ok" ) ;
52
52
return Ok ( ( ) ) ;
53
- } else if AbstractConst :: new ( tcx, b_def, b_substs) ?
54
- . map_or ( false , |b_ct| try_unify ( tcx, ct, b_ct) )
55
- {
56
- debug ! ( "is_const_evaluatable: abstract_const ~~> ok" ) ;
57
- return Ok ( ( ) ) ;
53
+ }
54
+
55
+ if let Some ( b_ct) = AbstractConst :: new ( tcx, b_def, b_substs) ? {
56
+ // Try to unify with each subtree in the AbstractConst to allow for
57
+ // `N + 1` being const evaluatable even if theres only a `ConstEvaluatable`
58
+ // predicate for `(N + 1) * 2`
59
+ let result =
60
+ walk_abstract_const ( tcx, b_ct, |b_ct| {
61
+ match try_unify ( tcx, ct, b_ct) {
62
+ true => ControlFlow :: BREAK ,
63
+ false => ControlFlow :: CONTINUE ,
64
+ }
65
+ } ) ;
66
+
67
+ if let ControlFlow :: Break ( ( ) ) = result {
68
+ debug ! ( "is_const_evaluatable: abstract_const ~~> ok" ) ;
69
+ return Ok ( ( ) ) ;
70
+ }
58
71
}
59
72
}
60
73
_ => { } // don't care
@@ -78,7 +91,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
78
91
Concrete ,
79
92
}
80
93
let mut failure_kind = FailureKind :: Concrete ;
81
- walk_abstract_const :: < !, _ > ( tcx, ct, |node| match node {
94
+ walk_abstract_const :: < !, _ > ( tcx, ct, |node| match node. root ( ) {
82
95
Node :: Leaf ( leaf) => {
83
96
let leaf = leaf. subst ( tcx, ct. substs ) ;
84
97
if leaf. has_infer_types_or_consts ( ) {
@@ -580,15 +593,15 @@ pub fn walk_abstract_const<'tcx, R, F>(
580
593
mut f : F ,
581
594
) -> ControlFlow < R >
582
595
where
583
- F : FnMut ( Node < ' tcx > ) -> ControlFlow < R > ,
596
+ F : FnMut ( AbstractConst < ' tcx > ) -> ControlFlow < R > ,
584
597
{
585
598
fn recurse < ' tcx , R > (
586
599
tcx : TyCtxt < ' tcx > ,
587
600
ct : AbstractConst < ' tcx > ,
588
- f : & mut dyn FnMut ( Node < ' tcx > ) -> ControlFlow < R > ,
601
+ f : & mut dyn FnMut ( AbstractConst < ' tcx > ) -> ControlFlow < R > ,
589
602
) -> ControlFlow < R > {
603
+ f ( ct) ?;
590
604
let root = ct. root ( ) ;
591
- f ( root) ?;
592
605
match root {
593
606
Node :: Leaf ( _) => ControlFlow :: CONTINUE ,
594
607
Node :: Binop ( _, l, r) => {
0 commit comments