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