Skip to content

Commit f60a770

Browse files
authored
Rollup merge of rust-lang#110180 - lcnr:canonicalize, r=compiler-errors
don't uniquify regions when canonicalizing uniquifying causes a bunch of issues, most notably it causes `AliasEq(<?x as Trait<'a>>::Assoc, <?x as Trait<'a>>::Assoc)` to result in ambiguity because both `normalizes-to` paths result in ambiguity and substs equate should trivially succeed but doesn't because we uniquified `'a` to two different regions. I originally added uniquification to make it easier to deal with requirement 6 from the dev-guide: https://rustc-dev-guide.rust-lang.org/solve/trait-solving.html#requirements > ### 6. Trait solving must be (free) lifetime agnostic > > Trait solving during codegen should have the same result as during typeck. As we erase > all free regions during codegen we must not rely on them during typeck. A noteworthy example > is special behavior for `'static`. cc rust-lang/rustc-dev-guide#1671 Relying on regions being identical may cause ICE during MIR typeck, but even without this PR we can end up relying on that as type inference vars can resolve to types which contain an identical region. Let's land this and deal with any ICE that crop up as we go. Will look at this issue again before stabilization. r? ``@compiler-errors``
2 parents f8e0b48 + c68c6c3 commit f60a770

File tree

3 files changed

+23
-341
lines changed

3 files changed

+23
-341
lines changed

compiler/rustc_trait_selection/src/solve/canonicalize.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ impl<'a, 'tcx> Canonicalizer<'a, 'tcx> {
125125
// - var_infos: [E0, U1, E1, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 6
126126
// - var_infos: [E0, U1, E1, U1, E1, E2, U2], curr_compressed_uv: 2, next_orig_uv: -
127127
//
128-
// This algorithm runs in `O(n²)` where `n` is the number of different universe
129-
// indices in the input. This should be fine as `n` is expected to be small.
128+
// This algorithm runs in `O(nm)` where `n` is the number of different universe
129+
// indices in the input and `m` is the number of canonical variables.
130+
// This should be fine as both `n` and `m` are expected to be small.
130131
let mut curr_compressed_uv = ty::UniverseIndex::ROOT;
131132
let mut existential_in_new_uv = false;
132133
let mut next_orig_uv = Some(ty::UniverseIndex::ROOT);
@@ -245,18 +246,14 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
245246
ty::ReError(_) => return r,
246247
};
247248

248-
let existing_bound_var = match self.canonicalize_mode {
249-
CanonicalizeMode::Input => None,
250-
CanonicalizeMode::Response { .. } => {
251-
self.variables.iter().position(|&v| v == r.into()).map(ty::BoundVar::from)
252-
}
253-
};
254-
let var = existing_bound_var.unwrap_or_else(|| {
255-
let var = ty::BoundVar::from(self.variables.len());
256-
self.variables.push(r.into());
257-
self.primitive_var_infos.push(CanonicalVarInfo { kind });
258-
var
259-
});
249+
let var = ty::BoundVar::from(
250+
self.variables.iter().position(|&v| v == r.into()).unwrap_or_else(|| {
251+
let var = self.variables.len();
252+
self.variables.push(r.into());
253+
self.primitive_var_infos.push(CanonicalVarInfo { kind });
254+
var
255+
}),
256+
);
260257
let br = ty::BoundRegion { var, kind: BrAnon(None) };
261258
self.interner().mk_re_late_bound(self.binder_index, br)
262259
}

tests/ui/regions/issue-2718.rs

-327
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
use std::{iter, slice};
5+
6+
struct Attr;
7+
8+
fn test<'a, T: Iterator<Item = &'a Attr>>() {}
9+
10+
fn main() {
11+
test::<iter::Filter<slice::Iter<'_, Attr>, fn(&&Attr) -> bool>>();
12+
}

0 commit comments

Comments
 (0)