@@ -19,17 +19,28 @@ const NEEDS_CANONICAL: TypeFlags = TypeFlags::from_bits(
1919)
2020. unwrap ( ) ;
2121
22+ #[ derive( Debug , Clone , Copy ) ]
23+ enum CanonicalizeInputKind {
24+ /// When canonicalizing the `param_env`, we keep `'static` as merging
25+ /// trait candidates relies on it when deciding whether a where-bound
26+ /// is trivial.
27+ ParamEnv ,
28+ /// When canonicalizing predicates, we don't keep `'static`. If we're
29+ /// currently outside of the trait solver and canonicalize the root goal
30+ /// during HIR typeck, we replace each occurance of a region with a
31+ /// unique region variable. See the comment on `InferCtxt::in_hir_typeck`
32+ /// for more details.
33+ Predicate { is_hir_typeck_root_goal : bool } ,
34+ }
35+
2236/// Whether we're canonicalizing a query input or the query response.
2337///
2438/// When canonicalizing an input we're in the context of the caller
2539/// while canonicalizing the response happens in the context of the
2640/// query.
2741#[ derive( Debug , Clone , Copy ) ]
2842enum CanonicalizeMode {
29- /// When canonicalizing the `param_env`, we keep `'static` as merging
30- /// trait candidates relies on it when deciding whether a where-bound
31- /// is trivial.
32- Input { keep_static : bool } ,
43+ Input ( CanonicalizeInputKind ) ,
3344 /// FIXME: We currently return region constraints referring to
3445 /// placeholders and inference variables from a binder instantiated
3546 /// inside of the query.
@@ -122,7 +133,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
122133 let mut variables = Vec :: new ( ) ;
123134 let mut env_canonicalizer = Canonicalizer {
124135 delegate,
125- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
136+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
126137
127138 variables : & mut variables,
128139 variable_lookup_table : Default :: default ( ) ,
@@ -154,7 +165,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
154165 } else {
155166 let mut env_canonicalizer = Canonicalizer {
156167 delegate,
157- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
168+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
158169
159170 variables,
160171 variable_lookup_table : Default :: default ( ) ,
@@ -180,6 +191,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
180191 pub fn canonicalize_input < P : TypeFoldable < I > > (
181192 delegate : & ' a D ,
182193 variables : & ' a mut Vec < I :: GenericArg > ,
194+ is_hir_typeck_root_goal : bool ,
183195 input : QueryInput < I , P > ,
184196 ) -> ty:: Canonical < I , QueryInput < I , P > > {
185197 // First canonicalize the `param_env` while keeping `'static`
@@ -189,7 +201,9 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
189201 // while *mostly* reusing the canonicalizer from above.
190202 let mut rest_canonicalizer = Canonicalizer {
191203 delegate,
192- canonicalize_mode : CanonicalizeMode :: Input { keep_static : false } ,
204+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
205+ is_hir_typeck_root_goal,
206+ } ) ,
193207
194208 variables,
195209 variable_lookup_table,
@@ -413,10 +427,10 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
413427 // We don't canonicalize `ReStatic` in the `param_env` as we use it
414428 // when checking whether a `ParamEnv` candidate is global.
415429 ty:: ReStatic => match self . canonicalize_mode {
416- CanonicalizeMode :: Input { keep_static : false } => {
430+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
417431 CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
418432 }
419- CanonicalizeMode :: Input { keep_static : true }
433+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
420434 | CanonicalizeMode :: Response { .. } => return r,
421435 } ,
422436
@@ -428,20 +442,20 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
428442 // `ReErased`. We may be able to short-circuit registering region
429443 // obligations if we encounter a `ReErased` on one side, for example.
430444 ty:: ReErased | ty:: ReError ( _) => match self . canonicalize_mode {
431- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
445+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
432446 CanonicalizeMode :: Response { .. } => return r,
433447 } ,
434448
435449 ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) => match self . canonicalize_mode {
436- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
450+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
437451 CanonicalizeMode :: Response { .. } => {
438452 panic ! ( "unexpected region in response: {r:?}" )
439453 }
440454 } ,
441455
442456 ty:: RePlaceholder ( placeholder) => match self . canonicalize_mode {
443457 // We canonicalize placeholder regions as existentials in query inputs.
444- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
458+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
445459 CanonicalizeMode :: Response { max_input_universe } => {
446460 // If we have a placeholder region inside of a query, it must be from
447461 // a new universe.
@@ -459,23 +473,36 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
459473 "region vid should have been resolved fully before canonicalization"
460474 ) ;
461475 match self . canonicalize_mode {
462- CanonicalizeMode :: Input { keep_static : _ } => {
463- CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
464- }
476+ CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
465477 CanonicalizeMode :: Response { .. } => {
466478 CanonicalVarKind :: Region ( self . delegate . universe_of_lt ( vid) . unwrap ( ) )
467479 }
468480 }
469481 }
470482 } ;
471483
472- let var = self . get_or_insert_bound_var ( r, kind) ;
484+ let var = if let CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
485+ is_hir_typeck_root_goal : true ,
486+ } ) = self . canonicalize_mode
487+ {
488+ let var = ty:: BoundVar :: from ( self . variables . len ( ) ) ;
489+ self . variables . push ( r. into ( ) ) ;
490+ self . var_kinds . push ( kind) ;
491+ var
492+ } else {
493+ self . get_or_insert_bound_var ( r, kind)
494+ } ;
473495
474496 Region :: new_anon_bound ( self . cx ( ) , self . binder_index , var)
475497 }
476498
477499 fn fold_ty ( & mut self , t : I :: Ty ) -> I :: Ty {
478- if let Some ( & ty) = self . cache . get ( & ( self . binder_index , t) ) {
500+ if let CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
501+ is_hir_typeck_root_goal : true ,
502+ } ) = self . canonicalize_mode
503+ {
504+ self . cached_fold_ty ( t)
505+ } else if let Some ( & ty) = self . cache . get ( & ( self . binder_index , t) ) {
479506 ty
480507 } else {
481508 let res = self . cached_fold_ty ( t) ;
@@ -541,9 +568,9 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
541568
542569 fn fold_clauses ( & mut self , c : I :: Clauses ) -> I :: Clauses {
543570 match self . canonicalize_mode {
544- CanonicalizeMode :: Input { keep_static : true }
571+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
545572 | CanonicalizeMode :: Response { max_input_universe : _ } => { }
546- CanonicalizeMode :: Input { keep_static : false } => {
573+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
547574 panic ! ( "erasing 'static in env" )
548575 }
549576 }
0 commit comments