Skip to content

Commit d874a3c

Browse files
committed
support Result based on Chris's suggestion
1 parent a49e6b8 commit d874a3c

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

source/pervasive/std_specs/control_flow.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,26 @@ pub fn ex_option_from_residual<T>(option: Option<Infallible>) -> (option2: Optio
4747
Option::from_residual(option)
4848
}
4949

50+
pub spec fn spec_from<S, T>(value: T, ret: S) -> bool;
5051

52+
#[verifier::broadcast_forall]
53+
#[verifier::external_body]
54+
pub proof fn spec_from_blanket_identity<T>(t: T, s: T)
55+
ensures
56+
spec_from::<T, T>(t, s) ==> t == s
57+
{
58+
}
5159

52-
/*#[verifier::external_fn_specification]
53-
pub fn ex_result_from_residual<T, E>(result: Result<Convert::Infallible, E>)
54-
-> (cf: ControlFlow<<Result<T, E> as Try>::Residual, <Result<T, E> as Try>::Output>)
60+
#[verifier::external_fn_specification]
61+
pub fn ex_result_from_residual<T, E, F: From<E>>(result: Result<Infallible, E>)
62+
-> (result2: Result<T, F>)
5563
ensures
56-
cf === match result {
57-
Ok(v) => ControlFlow::Continue(v),
58-
Err(e) => ControlFlow::Break(Err(e)),
64+
match (result, result2) {
65+
(Err(e), Err(e2)) => spec_from::<F, E>(e, e2),
66+
_ => false,
5967
},
6068
{
61-
result.branch()
62-
}*/
63-
69+
Result::from_residual(result)
70+
}
6471

6572
}

source/rust_verify_test/tests/std.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,48 @@ test_verify_one_file! {
240240
}
241241
} => Err(err) => assert_fails(err, 2)
242242
}
243+
244+
test_verify_one_file! {
245+
#[test] question_mark_result verus_code! {
246+
use vstd::*;
247+
248+
fn test() -> (res: Result<u32, bool>)
249+
ensures res === Err(false),
250+
{
251+
let x: Result<u8, bool> = Err(false);
252+
let y = x?;
253+
254+
assert(false);
255+
return Err(true);
256+
}
257+
258+
fn test2() -> (res: Result<u32, bool>)
259+
{
260+
let x: Result<u8, bool> = Ok(5);
261+
let y = x?;
262+
263+
assert(false); // FAILS
264+
return Err(false);
265+
}
266+
267+
fn test3() -> (res: Result<u32, bool>)
268+
ensures res.is_ok(),
269+
{
270+
let x: Result<u8, bool> = Err(false);
271+
let y = x?; // FAILS
272+
273+
return Ok(13);
274+
}
275+
276+
fn test4() -> (res: Result<u32, bool>)
277+
ensures false,
278+
{
279+
let x: Result<u8, bool> = Ok(12);
280+
let y = x?;
281+
282+
assert(y == 12);
283+
284+
loop { }
285+
}
286+
} => Err(err) => assert_fails(err, 2)
287+
}

0 commit comments

Comments
 (0)