Requires and ensures with mutable references

If a function takes a mutable reference, say x: &mut T, as an argument, then function specification needs to be able to refer to two different value: the value behind the mutable reference before the function executes, and the value after.

More specifically, the requires clause will need to refer to the pre-value, while the ensures clause may need to refer to either (e.g., to specify how the value changes over the course of the function).

  • To refer to the pre-state, use *old(x)
  • To refer to the post-state, use *x.

(Note that this implies that in the requires clause, the mutable reference’s value can only be referred to by using old.)

Example

The following example shows how we can use the requires clause to constraint the input value, while the ensures clause relaets to the new value to the input value:

fn increment(a: &mut u32)
    requires *old(a) < u32::MAX,
    ensures *a == *old(a) + 1,
{
    *a = *a + 1;
}

fn caller()
{
    let mut z: u32 = 0;
    increment(&mut z);
    assert(z == 1);
}

In the increment function call, *old(a) refers to the dereferenced value of the mutable reference a at the beginning of the function call and *a in the ensures clause refers to the dereferenced value of the mutable reference a at the end of the function call.