Skip to content

Commit 5e7672a

Browse files
Rollup merge of rust-lang#157807 - Dnreikronos:assumptions_on_binders_non_lifetime_binder_ambiguity, r=BoxyUwU
don't ice on non-lifetime binders under `-Zassumptions-on-binders` fixes rust-lang#157778 w/ `-Znext-solver=globally -Zassumptions-on-binders` and a non-lifetime binder we hit `assert!(max_universe < u)` in `pull_region_outlives_constraints_out_of_universe` and ICE. the machinery here is region-outlives only, but a `for<T>` binder leaves a placeholder type in universe `u` that the region-only rewrite can't pull out, so an alias outlives like `<!T as Trait>::Assoc: 'r` reaches that assert still in `u`. just report ambiguity in that case, same as the `None => Ambiguity` bails right next to it — now it errors normally (E0284) instead of ICEing. r? @lcnr
2 parents 7501dcf + a2f80c9 commit 5e7672a

3 files changed

Lines changed: 61 additions & 7 deletions

File tree

compiler/rustc_type_ir/src/region_constraint.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,15 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling<
840840
escaping_outlives,
841841
I::BoundVarKinds::from_vars(infcx.cx(), bound_vars),
842842
);
843-
candidates.push(RegionConstraint::AliasTyOutlivesViaEnv(bound_outlives));
843+
let candidate = RegionConstraint::AliasTyOutlivesViaEnv(bound_outlives);
844+
if max_universe(infcx, candidate.clone()) < u {
845+
candidates.push(candidate);
846+
} else {
847+
// `PlaceholderReplacer` only folds regions. A non-lifetime binder can leave
848+
// a placeholder type in `u`, so this type-outlives constraint cannot be
849+
// handled by the region-outlives-only eager placeholder machinery.
850+
candidates.push(Ambiguity);
851+
}
844852
}
845853

846854
let assumptions = match assumptions {
@@ -885,12 +893,17 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling<
885893

886894
// while we did skip the binder, bound vars aren't in any universe so
887895
// this can't be an escaping bound var
888-
candidates.extend(
889-
regions_outliving(escaping_r, assumptions, infcx.cx())
890-
.filter(|r2| max_universe(infcx, *r2) < u)
891-
.map(|r2| AliasTyOutlivesViaEnv(bound_alias.map_bound(|alias| (alias, r2))))
892-
.collect::<Vec<_>>(),
893-
);
896+
for r2 in regions_outliving(escaping_r, assumptions, infcx.cx())
897+
.filter(|r2| max_universe(infcx, *r2) < u)
898+
{
899+
let candidate =
900+
AliasTyOutlivesViaEnv(bound_alias.map_bound(|alias| (alias, r2)));
901+
if max_universe(infcx, candidate.clone()) < u {
902+
candidates.push(candidate);
903+
} else {
904+
candidates.push(Ambiguity);
905+
}
906+
}
894907
}
895908

896909
// I'm not convinced our handling here is *complete* so for now
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ compile-flags: -Znext-solver -Zassumptions-on-binders
2+
3+
// Regression test for #157778.
4+
//
5+
// A non-lifetime binder (`for<T>`) introduces a placeholder *type* in universe `u`. The
6+
// resulting alias-outlives constraint `<!T as Trait>::Assoc: 'r` stays in `u` because the
7+
// region-only rewrite (`PlaceholderReplacer` only folds regions) cannot pull a type
8+
// placeholder out of `u`. This used to trip an `assert!(max_universe < u)` and ICE in
9+
// `pull_region_outlives_constraints_out_of_universe`. The assumptions-on-binders machinery
10+
// is region-outlives-only, so we now report ambiguity instead of panicking.
11+
12+
#![feature(non_lifetime_binders)]
13+
14+
trait Trait {
15+
type Assoc;
16+
type Ref //~ ERROR cannot satisfy `<T as Trait>::Assoc: 'static`
17+
where
18+
for<T> T: Trait<Assoc: 'static>;
19+
}
20+
21+
fn main() {}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0284]: type annotations needed: cannot satisfy `<T as Trait>::Assoc: 'static`
2+
--> $DIR/non_lifetime_binder_alias_outlives.rs:16:5
3+
|
4+
LL | / type Ref
5+
LL | | where
6+
LL | | for<T> T: Trait<Assoc: 'static>;
7+
| |________________________________________^ cannot satisfy `<T as Trait>::Assoc: 'static`
8+
|
9+
note: required by a bound in `Trait::Ref`
10+
--> $DIR/non_lifetime_binder_alias_outlives.rs:18:32
11+
|
12+
LL | type Ref
13+
| --- required by a bound in this associated type
14+
LL | where
15+
LL | for<T> T: Trait<Assoc: 'static>;
16+
| ^^^^^^^ required by this bound in `Trait::Ref`
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0284`.

0 commit comments

Comments
 (0)