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
- }
380
- }
381
- }
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) ;
290
+ ( max_universe, var_kinds)
393
291
}
394
292
}
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 {
0 commit comments