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.
This commit is contained in:
parent
b7b3d2cee0
commit
12912b9cde
@ -1342,6 +1342,18 @@ fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
|
||||
let sub_region_scc = self.constraint_sccs.scc(sub_region);
|
||||
let sup_region_scc = self.constraint_sccs.scc(sup_region);
|
||||
|
||||
// If we are checking that `'sup: 'sub`, and `'sub` contains
|
||||
// some placeholder that `'sup` cannot name, then this is only
|
||||
// true if `'sup` outlives static.
|
||||
if !self.universe_compatible(sub_region_scc, sup_region_scc) {
|
||||
debug!(
|
||||
"eval_outlives: sub universe `{sub_region_scc:?}` is not nameable \
|
||||
by super `{sup_region_scc:?}`, promoting to static",
|
||||
);
|
||||
|
||||
return self.eval_outlives(sup_region, self.universal_regions.fr_static);
|
||||
}
|
||||
|
||||
// Both the `sub_region` and `sup_region` consist of the union
|
||||
// of some number of universal regions (along with the union
|
||||
// of various points in the CFG; ignore those points for
|
||||
@ -1356,6 +1368,9 @@ fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
|
||||
});
|
||||
|
||||
if !universal_outlives {
|
||||
debug!(
|
||||
"eval_outlives: returning false because sub region contains a universal region not present in super"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1364,10 +1379,18 @@ fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
|
||||
|
||||
if self.universal_regions.is_universal_region(sup_region) {
|
||||
// Micro-opt: universal regions contain all points.
|
||||
debug!(
|
||||
"eval_outlives: returning true because super is universal and hence contains all points"
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
self.scc_values.contains_points(sup_region_scc, sub_region_scc)
|
||||
let result = self.scc_values.contains_points(sup_region_scc, sub_region_scc);
|
||||
debug!(
|
||||
"eval_outlives: returning {} because of comparison between points in sup/sub",
|
||||
result
|
||||
);
|
||||
result
|
||||
}
|
||||
|
||||
/// Once regions have been propagated, this method is used to see
|
||||
|
21
src/test/ui/nll/type-test-universe.rs
Normal file
21
src/test/ui/nll/type-test-universe.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Regression test for #98095: make sure that
|
||||
// we detect that S needs to outlive 'static.
|
||||
|
||||
fn outlives_forall<T>()
|
||||
where
|
||||
for<'u> T: 'u,
|
||||
{
|
||||
}
|
||||
|
||||
fn test1<S>() {
|
||||
outlives_forall::<S>();
|
||||
//~^ ERROR `S` does not live long enough
|
||||
}
|
||||
|
||||
struct Value<'a>(&'a ());
|
||||
fn test2<'a>() {
|
||||
outlives_forall::<Value<'a>>();
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
16
src/test/ui/nll/type-test-universe.stderr
Normal file
16
src/test/ui/nll/type-test-universe.stderr
Normal file
@ -0,0 +1,16 @@
|
||||
error: `S` does not live long enough
|
||||
--> $DIR/type-test-universe.rs:11:5
|
||||
|
|
||||
LL | outlives_forall::<S>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-test-universe.rs:17:5
|
||||
|
|
||||
LL | fn test2<'a>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | outlives_forall::<Value<'a>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user