Skip to content

Commit 782f2d1

Browse files
Don't compress input universes
1 parent e0a8529 commit 782f2d1

File tree

1 file changed

+6
-111
lines changed

1 file changed

+6
-111
lines changed

compiler/rustc_next_trait_solver/src/canonicalizer.rs

Lines changed: 6 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::cmp::Ordering;
2-
31
use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
42
use rustc_type_ir::inherent::*;
53
use rustc_type_ir::solve::{Goal, QueryInput};
@@ -266,11 +264,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
266264
// See the rustc-dev-guide section about how we deal with universes
267265
// during canonicalization in the new solver.
268266
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+
}
274272
// When canonicalizing a response we map a universes already entered
275273
// by the caller to the root universe and only return useful universe
276274
// information for placeholders and inference variables created inside
@@ -288,113 +286,10 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
288286
.map(|kind| kind.universe())
289287
.max()
290288
.unwrap_or(ty::UniverseIndex::ROOT);
291-
292289
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)
393291
}
394292
}
395-
396-
let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds);
397-
(curr_compressed_uv, var_kinds)
398293
}
399294

400295
fn cached_fold_ty(&mut self, t: I::Ty) -> I::Ty {

0 commit comments

Comments
 (0)