@@ -19,17 +19,28 @@ const NEEDS_CANONICAL: TypeFlags = TypeFlags::from_bits(
19
19
)
20
20
. unwrap ( ) ;
21
21
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
+
22
36
/// Whether we're canonicalizing a query input or the query response.
23
37
///
24
38
/// When canonicalizing an input we're in the context of the caller
25
39
/// while canonicalizing the response happens in the context of the
26
40
/// query.
27
41
#[ derive( Debug , Clone , Copy ) ]
28
42
enum 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 ) ,
33
44
/// FIXME: We currently return region constraints referring to
34
45
/// placeholders and inference variables from a binder instantiated
35
46
/// inside of the query.
@@ -122,7 +133,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
122
133
let mut variables = Vec :: new ( ) ;
123
134
let mut env_canonicalizer = Canonicalizer {
124
135
delegate,
125
- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
136
+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
126
137
127
138
variables : & mut variables,
128
139
variable_lookup_table : Default :: default ( ) ,
@@ -154,7 +165,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
154
165
} else {
155
166
let mut env_canonicalizer = Canonicalizer {
156
167
delegate,
157
- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
168
+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
158
169
159
170
variables,
160
171
variable_lookup_table : Default :: default ( ) ,
@@ -180,6 +191,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
180
191
pub fn canonicalize_input < P : TypeFoldable < I > > (
181
192
delegate : & ' a D ,
182
193
variables : & ' a mut Vec < I :: GenericArg > ,
194
+ is_hir_typeck_root_goal : bool ,
183
195
input : QueryInput < I , P > ,
184
196
) -> ty:: Canonical < I , QueryInput < I , P > > {
185
197
// First canonicalize the `param_env` while keeping `'static`
@@ -189,7 +201,9 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
189
201
// while *mostly* reusing the canonicalizer from above.
190
202
let mut rest_canonicalizer = Canonicalizer {
191
203
delegate,
192
- canonicalize_mode : CanonicalizeMode :: Input { keep_static : false } ,
204
+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
205
+ is_hir_typeck_root_goal,
206
+ } ) ,
193
207
194
208
variables,
195
209
variable_lookup_table,
@@ -413,10 +427,10 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
413
427
// We don't canonicalize `ReStatic` in the `param_env` as we use it
414
428
// when checking whether a `ParamEnv` candidate is global.
415
429
ty:: ReStatic => match self . canonicalize_mode {
416
- CanonicalizeMode :: Input { keep_static : false } => {
430
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
417
431
CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
418
432
}
419
- CanonicalizeMode :: Input { keep_static : true }
433
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
420
434
| CanonicalizeMode :: Response { .. } => return r,
421
435
} ,
422
436
@@ -428,20 +442,20 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
428
442
// `ReErased`. We may be able to short-circuit registering region
429
443
// obligations if we encounter a `ReErased` on one side, for example.
430
444
ty:: ReErased | ty:: ReError ( _) => match self . canonicalize_mode {
431
- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
445
+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
432
446
CanonicalizeMode :: Response { .. } => return r,
433
447
} ,
434
448
435
449
ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) => match self . canonicalize_mode {
436
- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
450
+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
437
451
CanonicalizeMode :: Response { .. } => {
438
452
panic ! ( "unexpected region in response: {r:?}" )
439
453
}
440
454
} ,
441
455
442
456
ty:: RePlaceholder ( placeholder) => match self . canonicalize_mode {
443
457
// 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 ) ,
445
459
CanonicalizeMode :: Response { max_input_universe } => {
446
460
// If we have a placeholder region inside of a query, it must be from
447
461
// a new universe.
@@ -459,23 +473,36 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
459
473
"region vid should have been resolved fully before canonicalization"
460
474
) ;
461
475
match self . canonicalize_mode {
462
- CanonicalizeMode :: Input { keep_static : _ } => {
463
- CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
464
- }
476
+ CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
465
477
CanonicalizeMode :: Response { .. } => {
466
478
CanonicalVarKind :: Region ( self . delegate . universe_of_lt ( vid) . unwrap ( ) )
467
479
}
468
480
}
469
481
}
470
482
} ;
471
483
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
+ } ;
473
495
474
496
Region :: new_anon_bound ( self . cx ( ) , self . binder_index , var)
475
497
}
476
498
477
499
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) ) {
479
506
ty
480
507
} else {
481
508
let res = self . cached_fold_ty ( t) ;
@@ -541,9 +568,9 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
541
568
542
569
fn fold_clauses ( & mut self , c : I :: Clauses ) -> I :: Clauses {
543
570
match self . canonicalize_mode {
544
- CanonicalizeMode :: Input { keep_static : true }
571
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
545
572
| CanonicalizeMode :: Response { max_input_universe : _ } => { }
546
- CanonicalizeMode :: Input { keep_static : false } => {
573
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
547
574
panic ! ( "erasing 'static in env" )
548
575
}
549
576
}
0 commit comments