Skip to content

Commit 64f6c00

Browse files
authored
Rollup merge of rust-lang#112443 - compiler-errors:next-solver-opportunistically-resolve-regions, r=lcnr
Opportunistically resolve regions in new solver Use `opportunistic_resolve_var` during canonicalization to collapse some regions. We have to start using `CanonicalVarValues::is_identity_modulo_regions`. We also have to modify that function to consider responses like `['static, ^0, '^1, ^2]` to be an "identity" response, since because we opportunistically resolve regions, there's no longer a 1:1 mapping between canonical var values and bound var indices in the response... There's one nasty side-effect -- one test (`tests/ui/dyn-star/param-env-infer.rs`) starts to ICE because the certainty goes from `Yes` to `Maybe(Overflow)`... Not exactly sure why, though? Putting this up for discussion/investigation. r? ```@lcnr```
2 parents b41db84 + 01377e8 commit 64f6c00

File tree

4 files changed

+75
-11
lines changed

4 files changed

+75
-11
lines changed

compiler/rustc_middle/src/infer/canonical.rs

+33-8
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,40 @@ impl CanonicalVarValues<'_> {
8282
}
8383

8484
pub fn is_identity_modulo_regions(&self) -> bool {
85-
self.var_values.iter().enumerate().all(|(bv, arg)| match arg.unpack() {
86-
ty::GenericArgKind::Lifetime(_) => true,
87-
ty::GenericArgKind::Type(ty) => {
88-
matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var.as_usize() == bv)
89-
}
90-
ty::GenericArgKind::Const(ct) => {
91-
matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc.as_usize() == bv)
85+
let mut var = ty::BoundVar::from_u32(0);
86+
for arg in self.var_values {
87+
match arg.unpack() {
88+
ty::GenericArgKind::Lifetime(r) => {
89+
if let ty::ReLateBound(ty::INNERMOST, br) = *r
90+
&& var == br.var
91+
{
92+
var = var + 1;
93+
} else {
94+
// It's ok if this region var isn't unique
95+
}
96+
},
97+
ty::GenericArgKind::Type(ty) => {
98+
if let ty::Bound(ty::INNERMOST, bt) = *ty.kind()
99+
&& var == bt.var
100+
{
101+
var = var + 1;
102+
} else {
103+
return false;
104+
}
105+
}
106+
ty::GenericArgKind::Const(ct) => {
107+
if let ty::ConstKind::Bound(ty::INNERMOST, bc) = ct.kind()
108+
&& var == bc
109+
{
110+
var = var + 1;
111+
} else {
112+
return false;
113+
}
114+
}
92115
}
93-
})
116+
}
117+
118+
true
94119
}
95120
}
96121

compiler/rustc_trait_selection/src/solve/canonicalize.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,25 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
208208
t
209209
}
210210

211-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
212-
let r = self.infcx.shallow_resolve(r);
211+
fn fold_region(&mut self, mut r: ty::Region<'tcx>) -> ty::Region<'tcx> {
212+
match self.canonicalize_mode {
213+
CanonicalizeMode::Input => {
214+
// Don't resolve infer vars in input, since it affects
215+
// caching and may cause trait selection bugs which rely
216+
// on regions to be equal.
217+
}
218+
CanonicalizeMode::Response { .. } => {
219+
if let ty::ReVar(vid) = *r {
220+
r = self
221+
.infcx
222+
.inner
223+
.borrow_mut()
224+
.unwrap_region_constraints()
225+
.opportunistic_resolve_var(self.infcx.tcx, vid);
226+
}
227+
}
228+
}
229+
213230
let kind = match *r {
214231
ty::ReLateBound(..) => return r,
215232

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
263263
let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
264264
let new_canonical_response =
265265
EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?;
266-
if !new_canonical_response.value.var_values.is_identity() {
266+
// We only check for modulo regions as we convert all regions in
267+
// the input to new existentials, even if they're expected to be
268+
// `'static` or a placeholder region.
269+
if !new_canonical_response.value.var_values.is_identity_modulo_regions() {
267270
bug!(
268271
"unstable result: re-canonicalized goal={canonical_goal:#?} \
269272
first_response={canonical_response:#?} \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
#![feature(rustc_attrs)]
5+
6+
#[rustc_coinductive]
7+
trait Trait {}
8+
9+
#[rustc_coinductive]
10+
trait Indirect {}
11+
impl<T: Trait + ?Sized> Indirect for T {}
12+
13+
impl<'a> Trait for &'a () where &'a (): Indirect {}
14+
15+
fn impls_trait<T: Trait>() {}
16+
17+
fn main() {
18+
impls_trait::<&'static ()>();
19+
}

0 commit comments

Comments
 (0)