Skip to content

Commit eba66ec

Browse files
committed
add NLL-like imprecision example
This test showcases the same imprecision as NLLs, unlike the datalog implementation, when using reachability as a liveness approximation.
1 parent 90e055a commit eba66ec

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/flow-sensitive-invariance.rs:20:17
3+
|
4+
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
5+
| -- -- lifetime `'b` defined here
6+
| |
7+
| lifetime `'a` defined here
8+
LL | let returned_value = create_invariant();
9+
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
10+
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
11+
|
12+
= help: consider adding the following bound: `'b: 'a`
13+
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
14+
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
15+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
16+
17+
error: lifetime may not live long enough
18+
--> $DIR/flow-sensitive-invariance.rs:20:45
19+
|
20+
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
21+
| -- -- lifetime `'b` defined here
22+
| |
23+
| lifetime `'a` defined here
24+
LL | let returned_value = create_invariant();
25+
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
26+
| ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
27+
|
28+
= help: consider adding the following bound: `'a: 'b`
29+
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
30+
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
31+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
32+
33+
help: `'a` and `'b` must be the same: replace one with the other
34+
35+
error: aborting due to 2 previous errors
36+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/flow-sensitive-invariance.rs:20:17
3+
|
4+
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
5+
| -- -- lifetime `'b` defined here
6+
| |
7+
| lifetime `'a` defined here
8+
LL | let returned_value = create_invariant();
9+
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
10+
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
11+
|
12+
= help: consider adding the following bound: `'b: 'a`
13+
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
14+
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
15+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
16+
17+
error: lifetime may not live long enough
18+
--> $DIR/flow-sensitive-invariance.rs:20:45
19+
|
20+
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
21+
| -- -- lifetime `'b` defined here
22+
| |
23+
| lifetime `'a` defined here
24+
LL | let returned_value = create_invariant();
25+
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
26+
| ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
27+
|
28+
= help: consider adding the following bound: `'a: 'b`
29+
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
30+
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
31+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
32+
33+
help: `'a` and `'b` must be the same: replace one with the other
34+
35+
error: aborting due to 2 previous errors
36+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// An example (from @steffahn) of reachability as an approximation of liveness where the polonius
2+
// alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation.
3+
4+
//@ ignore-compare-mode-polonius (explicit revisions)
5+
//@ revisions: nll polonius legacy
6+
//@ [polonius] compile-flags: -Z polonius=next
7+
//@ [legacy] check-pass
8+
//@ [legacy] compile-flags: -Z polonius=legacy
9+
10+
use std::cell::Cell;
11+
12+
struct Invariant<'l>(Cell<&'l ()>);
13+
14+
fn create_invariant<'l>() -> Invariant<'l> {
15+
Invariant(Cell::new(&()))
16+
}
17+
18+
fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
19+
let returned_value = create_invariant();
20+
if choice { Ok(returned_value) } else { Err(returned_value) }
21+
//[nll]~^ ERROR lifetime may not live long enough
22+
//[nll]~| ERROR lifetime may not live long enough
23+
//[polonius]~^^^ ERROR lifetime may not live long enough
24+
//[polonius]~| ERROR lifetime may not live long enough
25+
}
26+
27+
fn use_it_buth_its_the_same<'a: 'b, 'b: 'a>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
28+
let returned_value = create_invariant();
29+
if choice { Ok(returned_value) } else { Err(returned_value) }
30+
}
31+
32+
fn main() {}

0 commit comments

Comments
 (0)