Skip to content

Commit 12912b9

Browse files
committed
fix universes in the NLL type tests
In the NLL code, we were not accommodating universes in the `type_test` logic. This led to issue 98095.
1 parent b7b3d2c commit 12912b9

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

compiler/rustc_borrowck/src/region_infer/mod.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
13421342
let sub_region_scc = self.constraint_sccs.scc(sub_region);
13431343
let sup_region_scc = self.constraint_sccs.scc(sup_region);
13441344

1345+
// If we are checking that `'sup: 'sub`, and `'sub` contains
1346+
// some placeholder that `'sup` cannot name, then this is only
1347+
// true if `'sup` outlives static.
1348+
if !self.universe_compatible(sub_region_scc, sup_region_scc) {
1349+
debug!(
1350+
"eval_outlives: sub universe `{sub_region_scc:?}` is not nameable \
1351+
by super `{sup_region_scc:?}`, promoting to static",
1352+
);
1353+
1354+
return self.eval_outlives(sup_region, self.universal_regions.fr_static);
1355+
}
1356+
13451357
// Both the `sub_region` and `sup_region` consist of the union
13461358
// of some number of universal regions (along with the union
13471359
// of various points in the CFG; ignore those points for
@@ -1356,6 +1368,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
13561368
});
13571369

13581370
if !universal_outlives {
1371+
debug!(
1372+
"eval_outlives: returning false because sub region contains a universal region not present in super"
1373+
);
13591374
return false;
13601375
}
13611376

@@ -1364,10 +1379,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
13641379

13651380
if self.universal_regions.is_universal_region(sup_region) {
13661381
// Micro-opt: universal regions contain all points.
1382+
debug!(
1383+
"eval_outlives: returning true because super is universal and hence contains all points"
1384+
);
13671385
return true;
13681386
}
13691387

1370-
self.scc_values.contains_points(sup_region_scc, sub_region_scc)
1388+
let result = self.scc_values.contains_points(sup_region_scc, sub_region_scc);
1389+
debug!(
1390+
"eval_outlives: returning {} because of comparison between points in sup/sub",
1391+
result
1392+
);
1393+
result
13711394
}
13721395

13731396
/// Once regions have been propagated, this method is used to see

src/test/ui/nll/type-test-universe.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Regression test for #98095: make sure that
2+
// we detect that S needs to outlive 'static.
3+
4+
fn outlives_forall<T>()
5+
where
6+
for<'u> T: 'u,
7+
{
8+
}
9+
10+
fn test1<S>() {
11+
outlives_forall::<S>();
12+
//~^ ERROR `S` does not live long enough
13+
}
14+
15+
struct Value<'a>(&'a ());
16+
fn test2<'a>() {
17+
outlives_forall::<Value<'a>>();
18+
//~^ ERROR lifetime may not live long enough
19+
}
20+
21+
fn main() {}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: `S` does not live long enough
2+
--> $DIR/type-test-universe.rs:11:5
3+
|
4+
LL | outlives_forall::<S>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: lifetime may not live long enough
8+
--> $DIR/type-test-universe.rs:17:5
9+
|
10+
LL | fn test2<'a>() {
11+
| -- lifetime `'a` defined here
12+
LL | outlives_forall::<Value<'a>>();
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)