add NLL-like imprecision example

This test showcases the same imprecision as NLLs, unlike the datalog
implementation, when using reachability as a liveness approximation.
This commit is contained in:
Rémy Rakic 2025-06-26 15:27:23 +00:00
parent b172980d5c
commit 48ebae9cef
3 changed files with 106 additions and 0 deletions

View file

@ -0,0 +1,36 @@
error: lifetime may not live long enough
--> $DIR/flow-sensitive-invariance.rs:20:17
|
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let returned_value = create_invariant();
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> $DIR/flow-sensitive-invariance.rs:20:45
|
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let returned_value = create_invariant();
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
| ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors

View file

@ -0,0 +1,36 @@
error: lifetime may not live long enough
--> $DIR/flow-sensitive-invariance.rs:20:17
|
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let returned_value = create_invariant();
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> $DIR/flow-sensitive-invariance.rs:20:45
|
LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let returned_value = create_invariant();
LL | if choice { Ok(returned_value) } else { Err(returned_value) }
| ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Invariant<'l>` is invariant over the parameter `'l`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors

View file

@ -0,0 +1,34 @@
// An example (from @steffahn) of reachability as an approximation of liveness where the polonius
// alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation.
//@ ignore-compare-mode-polonius (explicit revisions)
//@ revisions: nll polonius legacy
//@ [polonius] compile-flags: -Z polonius=next
//@ [legacy] check-pass
//@ [legacy] compile-flags: -Z polonius=legacy
use std::cell::Cell;
struct Invariant<'l>(Cell<&'l ()>);
fn create_invariant<'l>() -> Invariant<'l> {
Invariant(Cell::new(&()))
}
fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> {
let returned_value = create_invariant();
if choice { Ok(returned_value) } else { Err(returned_value) }
//[nll]~^ ERROR lifetime may not live long enough
//[nll]~| ERROR lifetime may not live long enough
//[polonius]~^^^ ERROR lifetime may not live long enough
//[polonius]~| ERROR lifetime may not live long enough
}
fn use_it_but_its_the_same_region<'a: 'b, 'b: 'a>(
choice: bool,
) -> Result<Invariant<'a>, Invariant<'b>> {
let returned_value = create_invariant();
if choice { Ok(returned_value) } else { Err(returned_value) }
}
fn main() {}