@@ -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, 
@@ -296,7 +310,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
296310        } 
297311    } 
298312
299-     fn  cached_fold_ty ( & mut  self ,  t :  I :: Ty )  -> I :: Ty  { 
313+     fn  inner_fold_ty ( & mut  self ,  t :  I :: Ty )  -> I :: Ty  { 
300314        let  kind = match  t. kind ( )  { 
301315            ty:: Infer ( i)  => match  i { 
302316                ty:: TyVar ( vid)  => { 
@@ -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,26 +473,42 @@ 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+             // If we're canonicalizing a root goal during HIR typeck, we 
505+             // must not use the `cache` as we want to map each occurrence 
506+             // of a region to a unique existential variable. 
507+             self . inner_fold_ty ( t) 
508+         }  else  if  let  Some ( & ty)  = self . cache . get ( & ( self . binder_index ,  t) )  { 
479509            ty
480510        }  else  { 
481-             let  res = self . cached_fold_ty ( t) ; 
511+             let  res = self . inner_fold_ty ( t) ; 
482512            let  old = self . cache . insert ( ( self . binder_index ,  t) ,  res) ; 
483513            assert_eq ! ( old,  None ) ; 
484514            res
@@ -541,9 +571,9 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
541571
542572    fn  fold_clauses ( & mut  self ,  c :  I :: Clauses )  -> I :: Clauses  { 
543573        match  self . canonicalize_mode  { 
544-             CanonicalizeMode :: Input   {   keep_static :   true   } 
574+             CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) 
545575            | CanonicalizeMode :: Response  {  max_input_universe :  _ }  => { } 
546-             CanonicalizeMode :: Input  {  keep_static :   false   }  => { 
576+             CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate  {  ..  } )  => { 
547577                panic ! ( "erasing 'static in env" ) 
548578            } 
549579        } 
0 commit comments