Skip to content

Commit 9a07292

Browse files
authored
Rollup merge of #118964 - compiler-errors:resolve, r=aliemjay
Opportunistically resolve region var in canonicalizer (instead of resolving root var) See comment in `compiler/rustc_type_ir/src/infcx.rs`. The **root** infer region for a given region vid may not actually be nameable from the universe of the original vid. That means that the assertion in the canonicalizer was too strict, since the `EagerResolver` that we use before canonicalizing is doing only as much resolving as it can. This replaces `resolve_lt_var` and `probe_lt_var` in the `rustc_type_ir` API with `opportunistic_resolve_lt_var`, which acts as you expect it should. I left a FIXME that complains about the inconsistency. This test is really gnarly, but I have no idea how to minimize it, since it seems to kind of just be coincidental that it triggered this issue. I hope the underlying root cause is easy enough to understand, though. r? `@lcnr` or `@aliemjay` Fixes #118950
2 parents 578758a + 146e345 commit 9a07292

File tree

7 files changed

+70
-35
lines changed

7 files changed

+70
-35
lines changed

compiler/rustc_infer/src/infer/mod.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -381,17 +381,13 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
381381
self.probe_ty_var(vid).ok()
382382
}
383383

384-
fn root_lt_var(&self, vid: ty::RegionVid) -> ty::RegionVid {
385-
self.root_region_var(vid)
386-
}
387-
388-
fn probe_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
384+
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
389385
let re = self
390386
.inner
391387
.borrow_mut()
392388
.unwrap_region_constraints()
393389
.opportunistic_resolve_var(self.tcx, vid);
394-
if re.is_var() { None } else { Some(re) }
390+
if *re == ty::ReVar(vid) { None } else { Some(re) }
395391
}
396392

397393
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
@@ -1367,10 +1363,6 @@ impl<'tcx> InferCtxt<'tcx> {
13671363
self.inner.borrow_mut().type_variables().root_var(var)
13681364
}
13691365

1370-
pub fn root_region_var(&self, var: ty::RegionVid) -> ty::RegionVid {
1371-
self.inner.borrow_mut().unwrap_region_constraints().root_var(var)
1372-
}
1373-
13741366
pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
13751367
self.inner.borrow_mut().const_unification_table().find(var).vid
13761368
}

compiler/rustc_infer/src/infer/region_constraints/mod.rs

-5
Original file line numberDiff line numberDiff line change
@@ -623,11 +623,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
623623
}
624624
}
625625

626-
pub fn root_var(&mut self, vid: ty::RegionVid) -> ty::RegionVid {
627-
let mut ut = self.unification_table_mut(); // FIXME(rust-lang/ena#42): unnecessary mut
628-
ut.find(vid).vid
629-
}
630-
631626
fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
632627
match t {
633628
Glb => &mut self.glbs,

compiler/rustc_next_trait_solver/src/canonicalizer.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,10 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
242242

243243
ty::ReVar(vid) => {
244244
assert_eq!(
245-
self.infcx.root_lt_var(vid),
246-
vid,
247-
"region vid should have been resolved fully before canonicalization"
248-
);
249-
assert_eq!(
250-
self.infcx.probe_lt_var(vid),
245+
self.infcx.opportunistic_resolve_lt_var(vid),
251246
None,
252247
"region vid should have been resolved fully before canonicalization"
253248
);
254-
255249
match self.canonicalize_mode {
256250
CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
257251
CanonicalizeMode::Response { .. } => {

compiler/rustc_type_ir/src/debug.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
3232
None
3333
}
3434

35-
fn root_lt_var(&self, vid: I::InferRegion) -> I::InferRegion {
36-
vid
37-
}
38-
39-
fn probe_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
35+
fn opportunistic_resolve_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
4036
None
4137
}
4238

compiler/rustc_type_ir/src/infcx.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ pub trait InferCtxtLike {
1818
lt: <Self::Interner as Interner>::InferRegion,
1919
) -> Option<UniverseIndex>;
2020

21-
/// Resolve `InferRegion` to its root `InferRegion`.
22-
fn root_lt_var(
23-
&self,
24-
vid: <Self::Interner as Interner>::InferRegion,
25-
) -> <Self::Interner as Interner>::InferRegion;
26-
27-
/// Resolve `InferRegion` to its inferred region, if it has been equated with a non-infer region.
28-
fn probe_lt_var(
21+
/// Resolve `InferRegion` to its inferred region, if it has been equated with
22+
/// a non-infer region.
23+
///
24+
/// FIXME: This has slightly different semantics than `{probe,resolve}_{ty,ct}_var`,
25+
/// that has to do with the fact unlike `Ty` or `Const` vars, in rustc, we may
26+
/// not always be able to *name* the root region var from the universe of the
27+
/// var we're trying to resolve. That's why it's called *opportunistic*.
28+
fn opportunistic_resolve_lt_var(
2929
&self,
3030
vid: <Self::Interner as Interner>::InferRegion,
3131
) -> Option<<Self::Interner as Interner>::Region>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// compile-flags: -Znext-solver
2+
//
3+
// This is a gnarly test but I don't know how to minimize it, frankly.
4+
5+
#![feature(lazy_type_alias)]
6+
//~^ WARN the feature `lazy_type_alias` is incomplete
7+
8+
trait ToUnit<'a> {
9+
type Unit;
10+
}
11+
12+
trait Overlap<T> {}
13+
14+
type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
15+
16+
impl<T> Overlap<T> for T {}
17+
18+
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
19+
//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
20+
//~| ERROR cannot find type `Missing` in this scope
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0412]: cannot find type `Missing` in this scope
2+
--> $DIR/issue-118950-root-region.rs:18:55
3+
|
4+
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
5+
| ^^^^^^^ not found in this scope
6+
7+
warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
8+
--> $DIR/issue-118950-root-region.rs:5:12
9+
|
10+
LL | #![feature(lazy_type_alias)]
11+
| ^^^^^^^^^^^^^^^
12+
|
13+
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
14+
= note: `#[warn(incomplete_features)]` on by default
15+
16+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
17+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
18+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
19+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
20+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
21+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
22+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
23+
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
24+
error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
25+
--> $DIR/issue-118950-root-region.rs:18:1
26+
|
27+
LL | impl<T> Overlap<T> for T {}
28+
| ------------------------ first implementation here
29+
LL |
30+
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
32+
33+
error: aborting due to 2 previous errors; 1 warning emitted
34+
35+
Some errors have detailed explanations: E0119, E0412.
36+
For more information about an error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)