@@ -4,8 +4,8 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
44use rustc_type_ir:: inherent:: * ;
55use rustc_type_ir:: solve:: { Goal , QueryInput } ;
66use 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 ,
99} ;
1010
1111use crate :: delegate:: SolverDelegate ;
@@ -79,7 +79,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
7979 cache : Default :: default ( ) ,
8080 } ;
8181
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+ } ;
8387 assert ! ( !value. has_infer( ) , "unexpected infer in {value:?}" ) ;
8488 assert ! ( !value. has_placeholders( ) , "unexpected placeholders in {value:?}" ) ;
8589 let ( max_universe, variables) = canonicalizer. finalize ( ) ;
@@ -111,7 +115,14 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
111115
112116 cache : Default :: default ( ) ,
113117 } ;
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+
115126 debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
116127 // Then canonicalize the rest of the input without keeping `'static`
117128 // while *mostly* reusing the canonicalizer from above.
@@ -134,10 +145,24 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
134145 cache : Default :: default ( ) ,
135146 } ;
136147
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+ } ;
138154 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+
141166 let value = QueryInput { goal, predefined_opaques_in_body } ;
142167
143168 assert ! ( !value. has_infer( ) , "unexpected infer in {value:?}" ) ;
@@ -387,7 +412,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
387412 | ty:: Alias ( _, _)
388413 | ty:: Bound ( _, _)
389414 | 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+ } ;
391420 }
392421 } ;
393422
@@ -522,11 +551,25 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
522551 | ty:: ConstKind :: Unevaluated ( _)
523552 | ty:: ConstKind :: Value ( _)
524553 | 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+ }
526561 } ;
527562
528563 let var = self . get_or_insert_bound_var ( c, kind) ;
529564
530565 Const :: new_anon_bound ( self . cx ( ) , self . binder_index , var)
531566 }
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+ }
532575}
0 commit comments