@@ -19,6 +19,12 @@ const NEEDS_CANONICAL: TypeFlags = TypeFlags::from_bits(
1919)
2020. unwrap ( ) ;
2121
22+ #[ derive( Debug , Clone , Copy ) ]
23+ enum CanonicalizeInputKind {
24+ ParamEnv ,
25+ Predicate { is_hir_typeck_root_goal : bool } ,
26+ }
27+
2228/// Whether we're canonicalizing a query input or the query response.
2329///
2430/// When canonicalizing an input we're in the context of the caller
@@ -29,7 +35,7 @@ enum CanonicalizeMode {
2935 /// When canonicalizing the `param_env`, we keep `'static` as merging
3036 /// trait candidates relies on it when deciding whether a where-bound
3137 /// is trivial.
32- Input { keep_static : bool } ,
38+ Input ( CanonicalizeInputKind ) ,
3339 /// FIXME: We currently return region constraints referring to
3440 /// placeholders and inference variables from a binder instantiated
3541 /// inside of the query.
@@ -122,7 +128,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
122128 let mut variables = Vec :: new ( ) ;
123129 let mut env_canonicalizer = Canonicalizer {
124130 delegate,
125- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
131+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
126132
127133 variables : & mut variables,
128134 variable_lookup_table : Default :: default ( ) ,
@@ -154,7 +160,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
154160 } else {
155161 let mut env_canonicalizer = Canonicalizer {
156162 delegate,
157- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
163+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
158164
159165 variables,
160166 variable_lookup_table : Default :: default ( ) ,
@@ -180,6 +186,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
180186 pub fn canonicalize_input < P : TypeFoldable < I > > (
181187 delegate : & ' a D ,
182188 variables : & ' a mut Vec < I :: GenericArg > ,
189+ is_hir_typeck_root_goal : bool ,
183190 input : QueryInput < I , P > ,
184191 ) -> ty:: Canonical < I , QueryInput < I , P > > {
185192 // First canonicalize the `param_env` while keeping `'static`
@@ -189,7 +196,9 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
189196 // while *mostly* reusing the canonicalizer from above.
190197 let mut rest_canonicalizer = Canonicalizer {
191198 delegate,
192- canonicalize_mode : CanonicalizeMode :: Input { keep_static : false } ,
199+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
200+ is_hir_typeck_root_goal,
201+ } ) ,
193202
194203 variables,
195204 variable_lookup_table,
@@ -413,10 +422,10 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
413422 // We don't canonicalize `ReStatic` in the `param_env` as we use it
414423 // when checking whether a `ParamEnv` candidate is global.
415424 ty:: ReStatic => match self . canonicalize_mode {
416- CanonicalizeMode :: Input { keep_static : false } => {
425+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
417426 CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
418427 }
419- CanonicalizeMode :: Input { keep_static : true }
428+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
420429 | CanonicalizeMode :: Response { .. } => return r,
421430 } ,
422431
@@ -428,20 +437,20 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
428437 // `ReErased`. We may be able to short-circuit registering region
429438 // obligations if we encounter a `ReErased` on one side, for example.
430439 ty:: ReErased | ty:: ReError ( _) => match self . canonicalize_mode {
431- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
440+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
432441 CanonicalizeMode :: Response { .. } => return r,
433442 } ,
434443
435444 ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) => match self . canonicalize_mode {
436- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
445+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
437446 CanonicalizeMode :: Response { .. } => {
438447 panic ! ( "unexpected region in response: {r:?}" )
439448 }
440449 } ,
441450
442451 ty:: RePlaceholder ( placeholder) => match self . canonicalize_mode {
443452 // We canonicalize placeholder regions as existentials in query inputs.
444- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
453+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
445454 CanonicalizeMode :: Response { max_input_universe } => {
446455 // If we have a placeholder region inside of a query, it must be from
447456 // a new universe.
@@ -459,23 +468,36 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
459468 "region vid should have been resolved fully before canonicalization"
460469 ) ;
461470 match self . canonicalize_mode {
462- CanonicalizeMode :: Input { keep_static : _ } => {
463- CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
464- }
471+ CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
465472 CanonicalizeMode :: Response { .. } => {
466473 CanonicalVarKind :: Region ( self . delegate . universe_of_lt ( vid) . unwrap ( ) )
467474 }
468475 }
469476 }
470477 } ;
471478
472- let var = self . get_or_insert_bound_var ( r, kind) ;
479+ let var = if let CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
480+ is_hir_typeck_root_goal : true ,
481+ } ) = self . canonicalize_mode
482+ {
483+ let var = ty:: BoundVar :: from ( self . variables . len ( ) ) ;
484+ self . variables . push ( r. into ( ) ) ;
485+ self . var_kinds . push ( kind) ;
486+ var
487+ } else {
488+ self . get_or_insert_bound_var ( r, kind)
489+ } ;
473490
474491 Region :: new_anon_bound ( self . cx ( ) , self . binder_index , var)
475492 }
476493
477494 fn fold_ty ( & mut self , t : I :: Ty ) -> I :: Ty {
478- if let Some ( & ty) = self . cache . get ( & ( self . binder_index , t) ) {
495+ if let CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
496+ is_hir_typeck_root_goal : true ,
497+ } ) = self . canonicalize_mode
498+ {
499+ self . cached_fold_ty ( t)
500+ } else if let Some ( & ty) = self . cache . get ( & ( self . binder_index , t) ) {
479501 ty
480502 } else {
481503 let res = self . cached_fold_ty ( t) ;
@@ -541,9 +563,9 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
541563
542564 fn fold_clauses ( & mut self , c : I :: Clauses ) -> I :: Clauses {
543565 match self . canonicalize_mode {
544- CanonicalizeMode :: Input { keep_static : true }
566+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
545567 | CanonicalizeMode :: Response { max_input_universe : _ } => { }
546- CanonicalizeMode :: Input { keep_static : false } => {
568+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
547569 panic ! ( "erasing 'static in env" )
548570 }
549571 }
0 commit comments