1
- use std:: cmp:: Ordering ;
2
-
3
1
use rustc_type_ir:: data_structures:: { HashMap , ensure_sufficient_stack} ;
4
2
use rustc_type_ir:: inherent:: * ;
5
3
use rustc_type_ir:: solve:: { Goal , QueryInput } ;
@@ -266,11 +264,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
266
264
// See the rustc-dev-guide section about how we deal with universes
267
265
// during canonicalization in the new solver.
268
266
match self . canonicalize_mode {
269
- // We try to deduplicate as many query calls as possible and hide
270
- // all information which should not matter for the solver.
271
- //
272
- // For this we compress universes as much as possible.
273
- CanonicalizeMode :: Input { .. } => { }
267
+ // All placeholders and vars are canonicalized in the root universe.
268
+ CanonicalizeMode :: Input { .. } => {
269
+ let var_kinds = self . delegate . cx ( ) . mk_canonical_var_kinds ( & var_kinds ) ;
270
+ ( ty :: UniverseIndex :: ROOT , var_kinds )
271
+ }
274
272
// When canonicalizing a response we map a universes already entered
275
273
// by the caller to the root universe and only return useful universe
276
274
// information for placeholders and inference variables created inside
@@ -288,113 +286,10 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
288
286
. map ( |kind| kind. universe ( ) )
289
287
. max ( )
290
288
. unwrap_or ( ty:: UniverseIndex :: ROOT ) ;
291
-
292
289
let var_kinds = self . delegate . cx ( ) . mk_canonical_var_kinds ( & var_kinds) ;
293
- return ( max_universe, var_kinds) ;
294
- }
295
- }
296
-
297
- // Given a `var_kinds` with existentials `En` and universals `Un` in
298
- // universes `n`, this algorithm compresses them in place so that:
299
- //
300
- // - the new universe indices are as small as possible
301
- // - we create a new universe if we would otherwise
302
- // 1. put existentials from a different universe into the same one
303
- // 2. put a placeholder in the same universe as an existential which cannot name it
304
- //
305
- // Let's walk through an example:
306
- // - var_kinds: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 0
307
- // - var_kinds: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 1
308
- // - var_kinds: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 1, next_orig_uv: 2
309
- // - var_kinds: [E0, U1, E5, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 5
310
- // - var_kinds: [E0, U1, E2, U1, E1, E6, U6], curr_compressed_uv: 2, next_orig_uv: 6
311
- // - var_kinds: [E0, U1, E1, U1, E1, E3, U3], curr_compressed_uv: 2, next_orig_uv: -
312
- //
313
- // This algorithm runs in `O(mn)` where `n` is the number of different universes and
314
- // `m` the number of variables. This should be fine as both are expected to be small.
315
- let mut curr_compressed_uv = ty:: UniverseIndex :: ROOT ;
316
- let mut existential_in_new_uv = None ;
317
- let mut next_orig_uv = Some ( ty:: UniverseIndex :: ROOT ) ;
318
- while let Some ( orig_uv) = next_orig_uv. take ( ) {
319
- let mut update_uv = |var : & mut CanonicalVarKind < I > , orig_uv, is_existential| {
320
- let uv = var. universe ( ) ;
321
- match uv. cmp ( & orig_uv) {
322
- Ordering :: Less => ( ) , // Already updated
323
- Ordering :: Equal => {
324
- if is_existential {
325
- if existential_in_new_uv. is_some_and ( |uv| uv < orig_uv) {
326
- // Condition 1.
327
- //
328
- // We already put an existential from a outer universe
329
- // into the current compressed universe, so we need to
330
- // create a new one.
331
- curr_compressed_uv = curr_compressed_uv. next_universe ( ) ;
332
- }
333
-
334
- // `curr_compressed_uv` will now contain an existential from
335
- // `orig_uv`. Trying to canonicalizing an existential from
336
- // a higher universe has to therefore use a new compressed
337
- // universe.
338
- existential_in_new_uv = Some ( orig_uv) ;
339
- } else if existential_in_new_uv. is_some ( ) {
340
- // Condition 2.
341
- //
342
- // `var` is a placeholder from a universe which is not nameable
343
- // by an existential which we already put into the compressed
344
- // universe `curr_compressed_uv`. We therefore have to create a
345
- // new universe for `var`.
346
- curr_compressed_uv = curr_compressed_uv. next_universe ( ) ;
347
- existential_in_new_uv = None ;
348
- }
349
-
350
- * var = var. with_updated_universe ( curr_compressed_uv) ;
351
- }
352
- Ordering :: Greater => {
353
- // We can ignore this variable in this iteration. We only look at
354
- // universes which actually occur in the input for performance.
355
- //
356
- // For this we set `next_orig_uv` to the next smallest, not yet compressed,
357
- // universe of the input.
358
- if next_orig_uv. is_none_or ( |curr_next_uv| uv. cannot_name ( curr_next_uv) ) {
359
- next_orig_uv = Some ( uv) ;
360
- }
361
- }
362
- }
363
- } ;
364
-
365
- // For each universe which occurs in the input, we first iterate over all
366
- // placeholders and then over all inference variables.
367
- //
368
- // Whenever we compress the universe of a placeholder, no existential with
369
- // an already compressed universe can name that placeholder.
370
- for is_existential in [ false , true ] {
371
- for var in var_kinds. iter_mut ( ) {
372
- // We simply put all regions from the input into the highest
373
- // compressed universe, so we only deal with them at the end.
374
- if !var. is_region ( ) {
375
- if is_existential == var. is_existential ( ) {
376
- update_uv ( var, orig_uv, is_existential)
377
- }
378
- }
379
- }
290
+ ( max_universe, var_kinds)
380
291
}
381
292
}
382
-
383
- // We put all regions into a separate universe.
384
- let mut first_region = true ;
385
- for var in var_kinds. iter_mut ( ) {
386
- if var. is_region ( ) {
387
- if first_region {
388
- first_region = false ;
389
- curr_compressed_uv = curr_compressed_uv. next_universe ( ) ;
390
- }
391
- debug_assert ! ( var. is_existential( ) ) ;
392
- * var = var. with_updated_universe ( curr_compressed_uv) ;
393
- }
394
- }
395
-
396
- let var_kinds = self . delegate . cx ( ) . mk_canonical_var_kinds ( & var_kinds) ;
397
- ( curr_compressed_uv, var_kinds)
398
293
}
399
294
400
295
fn cached_fold_ty ( & mut self , t : I :: Ty ) -> I :: Ty {
@@ -407,11 +302,18 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
407
302
"ty vid should have been resolved fully before canonicalization"
408
303
) ;
409
304
410
- CanonicalVarKind :: Ty ( CanonicalTyVarKind :: General (
411
- self . delegate
412
- . universe_of_ty ( vid)
413
- . unwrap_or_else ( || panic ! ( "ty var should have been resolved: {t:?}" ) ) ,
414
- ) )
305
+ match self . canonicalize_mode {
306
+ CanonicalizeMode :: Input { .. } => CanonicalVarKind :: Ty (
307
+ CanonicalTyVarKind :: General ( ty:: UniverseIndex :: ROOT ) ,
308
+ ) ,
309
+ CanonicalizeMode :: Response { .. } => {
310
+ CanonicalVarKind :: Ty ( CanonicalTyVarKind :: General (
311
+ self . delegate . universe_of_ty ( vid) . unwrap_or_else ( || {
312
+ panic ! ( "ty var should have been resolved: {t:?}" )
313
+ } ) ,
314
+ ) )
315
+ }
316
+ }
415
317
}
416
318
ty:: IntVar ( vid) => {
417
319
debug_assert_eq ! (
@@ -435,7 +337,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
435
337
} ,
436
338
ty:: Placeholder ( placeholder) => match self . canonicalize_mode {
437
339
CanonicalizeMode :: Input { .. } => CanonicalVarKind :: PlaceholderTy (
438
- PlaceholderLike :: new_anon ( placeholder . universe ( ) , self . variables . len ( ) . into ( ) ) ,
340
+ PlaceholderLike :: new_anon ( ty :: UniverseIndex :: ROOT , self . variables . len ( ) . into ( ) ) ,
439
341
) ,
440
342
CanonicalizeMode :: Response { .. } => CanonicalVarKind :: PlaceholderTy ( placeholder) ,
441
343
} ,
@@ -588,13 +490,21 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
588
490
c,
589
491
"const vid should have been resolved fully before canonicalization"
590
492
) ;
591
- CanonicalVarKind :: Const ( self . delegate . universe_of_ct ( vid) . unwrap ( ) )
493
+
494
+ match self . canonicalize_mode {
495
+ CanonicalizeMode :: Input { .. } => {
496
+ CanonicalVarKind :: Const ( ty:: UniverseIndex :: ROOT )
497
+ }
498
+ CanonicalizeMode :: Response { .. } => {
499
+ CanonicalVarKind :: Const ( self . delegate . universe_of_ct ( vid) . unwrap ( ) )
500
+ }
501
+ }
592
502
}
593
503
ty:: InferConst :: Fresh ( _) => todo ! ( ) ,
594
504
} ,
595
505
ty:: ConstKind :: Placeholder ( placeholder) => match self . canonicalize_mode {
596
506
CanonicalizeMode :: Input { .. } => CanonicalVarKind :: PlaceholderConst (
597
- PlaceholderLike :: new_anon ( placeholder . universe ( ) , self . variables . len ( ) . into ( ) ) ,
507
+ PlaceholderLike :: new_anon ( ty :: UniverseIndex :: ROOT , self . variables . len ( ) . into ( ) ) ,
598
508
) ,
599
509
CanonicalizeMode :: Response { .. } => {
600
510
CanonicalVarKind :: PlaceholderConst ( placeholder)
0 commit comments