@@ -19,6 +19,12 @@ const NEEDS_CANONICAL: TypeFlags = TypeFlags::from_bits(
19
19
)
20
20
. unwrap ( ) ;
21
21
22
+ #[ derive( Debug , Clone , Copy ) ]
23
+ enum CanonicalizeInputKind {
24
+ ParamEnv ,
25
+ Predicate { is_hir_typeck_root_goal : bool } ,
26
+ }
27
+
22
28
/// Whether we're canonicalizing a query input or the query response.
23
29
///
24
30
/// When canonicalizing an input we're in the context of the caller
@@ -29,7 +35,7 @@ enum CanonicalizeMode {
29
35
/// When canonicalizing the `param_env`, we keep `'static` as merging
30
36
/// trait candidates relies on it when deciding whether a where-bound
31
37
/// is trivial.
32
- Input { keep_static : bool } ,
38
+ Input ( CanonicalizeInputKind ) ,
33
39
/// FIXME: We currently return region constraints referring to
34
40
/// placeholders and inference variables from a binder instantiated
35
41
/// inside of the query.
@@ -122,7 +128,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
122
128
let mut variables = Vec :: new ( ) ;
123
129
let mut env_canonicalizer = Canonicalizer {
124
130
delegate,
125
- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
131
+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
126
132
127
133
variables : & mut variables,
128
134
variable_lookup_table : Default :: default ( ) ,
@@ -154,7 +160,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
154
160
} else {
155
161
let mut env_canonicalizer = Canonicalizer {
156
162
delegate,
157
- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
163
+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv ) ,
158
164
159
165
variables,
160
166
variable_lookup_table : Default :: default ( ) ,
@@ -180,6 +186,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
180
186
pub fn canonicalize_input < P : TypeFoldable < I > > (
181
187
delegate : & ' a D ,
182
188
variables : & ' a mut Vec < I :: GenericArg > ,
189
+ is_hir_typeck_root_goal : bool ,
183
190
input : QueryInput < I , P > ,
184
191
) -> ty:: Canonical < I , QueryInput < I , P > > {
185
192
// First canonicalize the `param_env` while keeping `'static`
@@ -189,7 +196,9 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
189
196
// while *mostly* reusing the canonicalizer from above.
190
197
let mut rest_canonicalizer = Canonicalizer {
191
198
delegate,
192
- canonicalize_mode : CanonicalizeMode :: Input { keep_static : false } ,
199
+ canonicalize_mode : CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate {
200
+ is_hir_typeck_root_goal,
201
+ } ) ,
193
202
194
203
variables,
195
204
variable_lookup_table,
@@ -413,10 +422,10 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
413
422
// We don't canonicalize `ReStatic` in the `param_env` as we use it
414
423
// when checking whether a `ParamEnv` candidate is global.
415
424
ty:: ReStatic => match self . canonicalize_mode {
416
- CanonicalizeMode :: Input { keep_static : false } => {
425
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
417
426
CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
418
427
}
419
- CanonicalizeMode :: Input { keep_static : true }
428
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
420
429
| CanonicalizeMode :: Response { .. } => return r,
421
430
} ,
422
431
@@ -428,20 +437,20 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
428
437
// `ReErased`. We may be able to short-circuit registering region
429
438
// obligations if we encounter a `ReErased` on one side, for example.
430
439
ty:: ReErased | ty:: ReError ( _) => match self . canonicalize_mode {
431
- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
440
+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
432
441
CanonicalizeMode :: Response { .. } => return r,
433
442
} ,
434
443
435
444
ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) => match self . canonicalize_mode {
436
- CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
445
+ CanonicalizeMode :: Input ( _ ) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
437
446
CanonicalizeMode :: Response { .. } => {
438
447
panic ! ( "unexpected region in response: {r:?}" )
439
448
}
440
449
} ,
441
450
442
451
ty:: RePlaceholder ( placeholder) => match self . canonicalize_mode {
443
452
// 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 ) ,
445
454
CanonicalizeMode :: Response { max_input_universe } => {
446
455
// If we have a placeholder region inside of a query, it must be from
447
456
// a new universe.
@@ -459,23 +468,36 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
459
468
"region vid should have been resolved fully before canonicalization"
460
469
) ;
461
470
match self . canonicalize_mode {
462
- CanonicalizeMode :: Input { keep_static : _ } => {
463
- CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
464
- }
471
+ CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
465
472
CanonicalizeMode :: Response { .. } => {
466
473
CanonicalVarKind :: Region ( self . delegate . universe_of_lt ( vid) . unwrap ( ) )
467
474
}
468
475
}
469
476
}
470
477
} ;
471
478
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
+ } ;
473
490
474
491
Region :: new_anon_bound ( self . cx ( ) , self . binder_index , var)
475
492
}
476
493
477
494
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) ) {
479
501
ty
480
502
} else {
481
503
let res = self . cached_fold_ty ( t) ;
@@ -541,9 +563,9 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
541
563
542
564
fn fold_clauses ( & mut self , c : I :: Clauses ) -> I :: Clauses {
543
565
match self . canonicalize_mode {
544
- CanonicalizeMode :: Input { keep_static : true }
566
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
545
567
| CanonicalizeMode :: Response { max_input_universe : _ } => { }
546
- CanonicalizeMode :: Input { keep_static : false } => {
568
+ CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate { .. } ) => {
547
569
panic ! ( "erasing 'static in env" )
548
570
}
549
571
}
0 commit comments