Adding a semantically unreachable guarded match arm
_ if false => unreachable!(),
to a match expression changes Prusti’s verification behavior.
Without the guarded arm, Prusti correctly reports a failing assertion.
With the unreachable guarded arm added, Prusti instead fails with:
[Prusti: unsupported feature] unsupported creation of shallow borrows (implicitly created when lowering matches)
and no longer reports the assertion failure.
The additional guarded arm is semantically unreachable and does not change the program’s behavior. However, it changes the set and nature of verification diagnostics.
Reproduction
#![feature(nll)]
#![feature(box_patterns)]
use prusti_contracts::*;
enum List {
Nil,
Const { val: i32, next: Box<List> },
}
fn tail(list: List) -> Option<List> {
let ret = match list {
List::Nil => None,
List::Const { val: _, box next } => Some(next),
// Uncommenting the next line triggers the unsupported feature error
// and prevents the assertion failure from being reported.
// _ if false => unreachable!(),
};
assert!(false);
ret
}
fn main() {}
Actual Behavior
Without _ if false:
error: [Prusti: verification error] the asserted expression might not hold
With _ if false:
[Prusti: unsupported feature] unsupported creation of shallow borrows (implicitly created when lowering matches)
- The assertion failure is no longer reported.
Adding a semantically unreachable guarded match arm
to a
matchexpression changes Prusti’s verification behavior.Without the guarded arm, Prusti correctly reports a failing assertion.
With the unreachable guarded arm added, Prusti instead fails with:
and no longer reports the assertion failure.
The additional guarded arm is semantically unreachable and does not change the program’s behavior. However, it changes the set and nature of verification diagnostics.
Reproduction
Actual Behavior
Without
_ if false:With
_ if false: