@@ -4,8 +4,8 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
4
4
use rustc_type_ir:: inherent:: * ;
5
5
use rustc_type_ir:: solve:: { Goal , QueryInput } ;
6
6
use rustc_type_ir:: {
7
- self as ty, Canonical , CanonicalTyVarKind , CanonicalVarKind , InferCtxtLike , Interner ,
8
- TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
7
+ self as ty, Canonical , CanonicalTyVarKind , CanonicalVarKind , Flags , InferCtxtLike , Interner ,
8
+ TypeFlags , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
9
9
} ;
10
10
11
11
use crate :: delegate:: SolverDelegate ;
@@ -79,7 +79,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
79
79
cache : Default :: default ( ) ,
80
80
} ;
81
81
82
- let value = value. fold_with ( & mut canonicalizer) ;
82
+ let value = if value. has_type_flags ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER ) {
83
+ value. fold_with ( & mut canonicalizer)
84
+ } else {
85
+ value
86
+ } ;
83
87
assert ! ( !value. has_infer( ) , "unexpected infer in {value:?}" ) ;
84
88
assert ! ( !value. has_placeholders( ) , "unexpected placeholders in {value:?}" ) ;
85
89
let ( max_universe, variables) = canonicalizer. finalize ( ) ;
@@ -111,7 +115,14 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
111
115
112
116
cache : Default :: default ( ) ,
113
117
} ;
114
- let param_env = input. goal . param_env . fold_with ( & mut env_canonicalizer) ;
118
+
119
+ let param_env = input. goal . param_env ;
120
+ let param_env = if param_env. has_type_flags ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER ) {
121
+ param_env. fold_with ( & mut env_canonicalizer)
122
+ } else {
123
+ param_env
124
+ } ;
125
+
115
126
debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
116
127
// Then canonicalize the rest of the input without keeping `'static`
117
128
// while *mostly* reusing the canonicalizer from above.
@@ -134,10 +145,24 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
134
145
cache : Default :: default ( ) ,
135
146
} ;
136
147
137
- let predicate = input. goal . predicate . fold_with ( & mut rest_canonicalizer) ;
148
+ let predicate = input. goal . predicate ;
149
+ let predicate = if predicate. has_type_flags ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER ) {
150
+ predicate. fold_with ( & mut rest_canonicalizer)
151
+ } else {
152
+ predicate
153
+ } ;
138
154
let goal = Goal { param_env, predicate } ;
139
- let predefined_opaques_in_body =
140
- input. predefined_opaques_in_body . fold_with ( & mut rest_canonicalizer) ;
155
+
156
+ let predefined_opaques_in_body = input. predefined_opaques_in_body ;
157
+ let predefined_opaques_in_body = if input
158
+ . predefined_opaques_in_body
159
+ . has_type_flags ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER )
160
+ {
161
+ predefined_opaques_in_body. fold_with ( & mut rest_canonicalizer)
162
+ } else {
163
+ predefined_opaques_in_body
164
+ } ;
165
+
141
166
let value = QueryInput { goal, predefined_opaques_in_body } ;
142
167
143
168
assert ! ( !value. has_infer( ) , "unexpected infer in {value:?}" ) ;
@@ -387,7 +412,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
387
412
| ty:: Alias ( _, _)
388
413
| ty:: Bound ( _, _)
389
414
| ty:: Error ( _) => {
390
- return ensure_sufficient_stack ( || t. super_fold_with ( self ) ) ;
415
+ return if t. has_type_flags ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER ) {
416
+ ensure_sufficient_stack ( || t. super_fold_with ( self ) )
417
+ } else {
418
+ t
419
+ } ;
391
420
}
392
421
} ;
393
422
@@ -522,11 +551,25 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
522
551
| ty:: ConstKind :: Unevaluated ( _)
523
552
| ty:: ConstKind :: Value ( _)
524
553
| ty:: ConstKind :: Error ( _)
525
- | ty:: ConstKind :: Expr ( _) => return c. super_fold_with ( self ) ,
554
+ | ty:: ConstKind :: Expr ( _) => {
555
+ return if c. has_type_flags ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER ) {
556
+ c. super_fold_with ( self )
557
+ } else {
558
+ c
559
+ } ;
560
+ }
526
561
} ;
527
562
528
563
let var = self . get_or_insert_bound_var ( c, kind) ;
529
564
530
565
Const :: new_anon_bound ( self . cx ( ) , self . binder_index , var)
531
566
}
567
+
568
+ fn fold_predicate ( & mut self , p : I :: Predicate ) -> I :: Predicate {
569
+ if p. flags ( ) . intersects ( TypeFlags :: NEEDS_CANONICAL_NEXT_SOLVER ) {
570
+ p. super_fold_with ( self )
571
+ } else {
572
+ p
573
+ }
574
+ }
532
575
}
0 commit comments