Tokens

Struct Tokens 

Source
pub struct Tokens<'a>(/* private fields */);
Expand description

Invariant tokens.

This is given at the start of the program, and must be passed along to LocalInvariant::open to prevent opening invariant reentrantly.

§Tokens and open

Tokens are used to avoid reentrency in open. To ensure this, Tokens acts as a special kind of mutable borrow : only one may exist at a given point in the program, preventing multiple calls to open with the same namespace. This is the reason this type has a lifetime attached to it.

Note that after the execution of open, the token that was used is restored. Because of this, we never need to talk about the ‘final’ value of this borrow, because it never differs from the current value (in places where we can use it).

To help passing it into functions, it may be reborrowed, similarly to a normal borrow.

Implementations§

Source§

impl Tokens<'_>

Source

pub fn namespaces(self) -> Set<Namespace>

Get the underlying set of namespaces of this token.

Also accessible via the view (@) operator.

(opaque)

Source

pub fn new() -> Ghost<Self>

Get the tokens for all the namespaces.

This is only callable once, in main.

ensures

forall<ns: Namespace> result.contains(ns)

terminates

ghost

Source

pub fn reborrow<'a>(&'a mut self) -> Tokens<'a>

Reborrow the token, allowing it to be reused later.

§Example
fn foo(tokens: Ghost<Tokens>) {}
fn bar(tokens: Ghost<Tokens>) {}
fn baz(mut tokens: Ghost<Tokens>) {
    foo(ghost!(tokens.reborrow()));
    bar(tokens);
}

ensures

result == *self && ^self == *self

terminates

ghost

Source

pub fn split<'a>( &'a mut self, ns: Snapshot<Namespace>, ) -> (Tokens<'a>, Tokens<'a>)

Split the tokens in two, so that it can be used to access independant invariants.

§Example
declare_namespace! { FOO }
declare_namespace! { BAR }

// the lifetime 'locks' the namespace
#[requires(tokens.contains(FOO()))]
fn foo<'a>(tokens: Ghost<Tokens<'a>>) -> &'a i32 {
    // access some invariant to get the reference
}
#[requires(tokens.contains(BAR()))]
fn bar(tokens: Ghost<Tokens>) {}

#[requires(tokens.contains(FOO()) && tokens.contains(BAR()))]
fn baz(mut tokens: Ghost<Tokens>) -> i32 {
     let (ns_foo, ns_bar) = ghost!(tokens.split(snapshot!(FOO()))).split();
     let x = foo(ns_foo);
     bar(ns_bar);
     *x
}

requires

self.contains(*ns)

ensures

^self == *self

ensures

result.0.contains(*ns)

ensures

result.1.namespaces() == self.namespaces().remove(*ns)

terminates

ghost

Source

pub fn contains(self, namespace: Namespace) -> bool

(open)

self.namespaces().contains(namespace)

Trait Implementations§

Source§

impl View for Tokens<'_>

Source§

fn view(self) -> Set<Namespace>

(open, inline)

self.namespaces()

Source§

type ViewTy = Set<Namespace>

Auto Trait Implementations§

§

impl<'a> Freeze for Tokens<'a>

§

impl<'a> RefUnwindSafe for Tokens<'a>

§

impl<'a> Send for Tokens<'a>

§

impl<'a> Sync for Tokens<'a>

§

impl<'a> Unpin for Tokens<'a>

§

impl<'a> UnwindSafe for Tokens<'a>

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.