Coercion with as #
Syntax #
V@[as_expr] ::= V@[spec_expr] as R@[type]
Coercions on integer types and char #
Any of the following types may be coerced to any of the other types:
i8,i16,i32,i64,i128,isizeu8,u16,u32,u64,u128,usizeintnatchar
Note that this is more permissive than as in Rust exec code. For example, Rust does
not permit using as to cast from a u16 to a char, but this is allowed in Verus
spec code.
Definition #
Verus defines as-casting as follows:
- Casting to an
intis always defined and does not require truncation. - Casting to a
natis unspecified if the input value is negative. - Casting to a
charis unspecified if the input value is outside the allowedcharvalues. - Casting to any other finite-size integer type is defined as truncation — taking the lower N bits for the appropriate N, then interpreting the result as a signed or unsigned integer.
Reasoning about truncation #
The definition of truncation is not exported in Verus's default prover mode (i.e., it behaves as if it is unspecified). To reason about truncation, use the bit-vector solver or the compute solver.
Also note that the value of N for usize and isize may be configured with the global directive.
Coercions on pointers #
Pointers to integers #
You can coerce any pointer to any integer type. For a pointer ptr: *mut T or ptr: *const T,
the expression ptr as INT_TYPE is equivalent to ptr.addr() as INT_TYPE.
Note
Using ptr.addr() explicitly is often clearer than an as-cast.
Note
Verus does not support casting an integer to a pointer using as. Instead, use a function like with_addr or with_exposed_provenance.
Pointers to pointers #
Verus supports some pointer-to-pointer coercions, including between *const and *mut pointers:
*mut Tto*const T(identity function)*const Tto*mut T(identity function)
And other kinds of coercions:
*mut Tto*mut Sfor anyS: Sized(spec)*mut [T; N]to*mut [T](spec)*mut [T]to*mut [U](spec)*mut [T]to*mut str(spec)*mut strto*mut [T](spec)
And the equivalent set of casts for *const pointers.