Skip to main content

Guarded

Struct Guarded 

Source
#[repr(transparent)]
pub struct Guarded<T, G: Guard<T>> { pub inner: T, /* private fields */ }
Expand description

Guarded is a wrapper around an object of type T, which makes sure that a guard (a predicate on T) is satisfied when the guarded object disappears. It works by making the guard part of the type invariant of Guarded, and uses some internal Creusot machinery to ensure that the guard never changes during the lifetime of the Guarded object.

As such, the guard can be broken locally, but it must be restored before the Guarded object is dropped, passed as a parameter, returned or when a borrow of the Guarded is resolved.

The guard is represented by a value guard: G whose type implements the trait Guard<T>. The relation guard.guards(inner, initial) is the property that must be satisfied when the guarded object disappears, where inner is the current value of the guarded object, and initial is its initial value when the Guarded object is created. The initial value is used to guarantee that the guarded object is not replaced with another (it may be mutated, but not replaced with another) using e.g., std::mem::swap.

Guarded is typically used with a T mutable borrow. In this case, Guard<&mut T> guarantees that the prophecies never change, and the guard typically guarantees that the final value of the borrow satisfies some property. Other uses include types that behave like mutable borrows, such as FullBorrow.

§Example

use creusot_std::prelude::*;
use creusot_std::invariant::Guarded;

#[ensures(^b == 0i32)]
fn breaks_inv(b: &mut i32) { *b = 0; }

let mut x = 1;
let guarded = Guarded::new_m(&mut x, snapshot!(|x: i32| x == 1i32));
// break the guard...
breaks_inv(&mut *guarded.inner);
// but restore it before we are done
*guarded.inner = 1;

Fields§

§inner: T

Payload of this Guarded value.

Implementations§

Source§

impl<T, G: Guard<T>> Guarded<T, G>

Source

pub fn guard(self) -> G

logic(open, inline)

*self._guard

Source§

impl<'a, T, G: GuardRef<T>> Guarded<&'a mut T, G>

Source

pub fn new(borrow: &'a mut T, guard: Snapshot<G>) -> Self

Create a new guarded borrow.

The borrow contained in the result is guaranteed to satisfy the guard at the end of its lifetime. Thus, we get the guard for its prophecy.

Note that the type of the second argument may not be inferred during compilation with rustc if it is directly constructed using the snapshot! macro. You may want to spell out the first type argument of Guarded, or use Guarded::new_m if the guard is a Mapping.

requires

guard.guards_ref(*borrow)

ensures

result.inner == borrow

ensures

result.guard() == *guard

ensures

guard.guards_ref(^borrow)

ghost

Source§

impl<'a, T> Guarded<&'a mut T, Mapping<T, bool>>

Source

pub fn new_m(borrow: &'a mut T, guard: Snapshot<Mapping<T, bool>>) -> Self

Variant of Guarded::new specialized with Mapping as the guard.

requires

guard.guards_ref(*borrow)

ensures

result.inner == borrow

ensures

result.guard() == *guard

ensures

guard.guards_ref(^borrow)

ghost

Source§

impl<'a, T> Guarded<&'a mut Option<T>, IsSome>

Source

pub fn some(borrow: Ghost<&'a mut T>) -> Ghost<Self>

ghost

ensures

*result.inner == Some(**borrow)

ensures

^result.inner == Some(^borrow)

Trait Implementations§

Source§

impl<T, G: Guard<T>> Invariant for Guarded<T, G>

Source§

fn invariant(self) -> bool

logic(open, prophetic, inline)

(*self._guard).guards(*self._initial, self.inner)

Auto Trait Implementations§

§

impl<T, G> Freeze for Guarded<T, G>
where T: Freeze, Snapshot<G>: Freeze, Snapshot<T>: Freeze,

§

impl<T, G> Objective for Guarded<T, G>

§

impl<T, G> RefUnwindSafe for Guarded<T, G>

§

impl<T, G> Send for Guarded<T, G>
where T: Send, Snapshot<G>: Send, Snapshot<T>: Send,

§

impl<T, G> Sync for Guarded<T, G>
where T: Sync, Snapshot<G>: Sync, Snapshot<T>: Sync,

§

impl<T, G> Unpin for Guarded<T, G>
where T: Unpin, Snapshot<G>: Unpin, Snapshot<T>: Unpin,

§

impl<T, G> UnsafeUnpin for Guarded<T, G>

§

impl<T, G> UnwindSafe for Guarded<T, G>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.