assume_specification
The assume_specification
directive tells Verus to use the given specification for the given function.
Verus assumes that this specification holds without proof.
It can be used with any exec
-mode function that Verus would otherwise be unaware of; for example,
any function marked external
or which is imported from an external crate.
It is similar to having a function which is external_body
; the difference is that when assume_specification
is used, the specification is separate from the function declaration
and body.
The assume_specification
declaration does NOT have to be in the same module or crate
as its corresponding function. However:
- The function must be visible to its
assume_specification
declaration - The
assume_specification
declaration must be visible wherever the function is visible.
The general form of this directive is:
assume_specification generics? [ function_path ] (args...) -> return_type_and_name?
where_clause?
requires_clause?
ensures_clause?
returns_clause?
invariants_clause?
unwind_clause?
;
It is intended to look like an ordinary Rust function signature with a Verus specification, except instead of having a name, it refers to a different function by path.
For associated functions and methods, the function_path
should have the form Type::method_name
,
using “turbofish syntax” for the type (e.g., Vec::<T>
).
For trait methods, the function_path
should use the “qualified self” form, <Type as Trait>::method_name
.
The signature must be the same as the function in question, including arguments, return type, generics, and trait bounds.
All arguments should be named and should not use self
.
Examples
To apply to an ordinary function:
pub assume_specification<T> [core::mem::swap::<T>] (a: &mut T, b: &mut T)
ensures
*a == *old(b),
*b == *old(a),
opens_invariants none
no_unwind;
To apply to an associated function of Vec
:
pub assume_specification<T>[Vec::<T>::new]() -> (v: Vec<T>)
ensures
v@ == Seq::<T>::empty();
To apply to an method of Vec
:
pub assume_specification<T, A: Allocator>[Vec::<T, A>::clear](vec: &mut Vec<T, A>)
ensures
vec@ == Seq::<T>::empty();
To apply to clone
for a specific type:
pub assume_specification [<bool as Clone>::clone](b: &bool) -> (res: bool)
ensures res == b;