@@ -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