pub struct Ghost<T: ?Sized>(/* private fields */);Expand description
A type that can be used in ghost! context.
This type may be used to make more complicated proofs possible. In particular, some proof may need a notion of non-duplicable token to carry around.
Conceptually, a Ghost<T> is an object of type T that resides in a special “ghost”
heap. This heap is inaccessible from normal code, and Ghost values cannot be used
to influence the behavior of normal code.
This box can be accessed in a ghost! block:
let b: Ghost<i32> = Ghost::new(1);
ghost! {
let value: i32 = b.into_inner();
// use value here
}
let value: i32 = b.into_inner(); // compile error !Implementations§
Source§impl<T: ?Sized> Ghost<T>
impl<T: ?Sized> Ghost<T>
Sourcepub fn borrow(&self) -> Ghost<&T>
pub fn borrow(&self) -> Ghost<&T>
Transforms a &Ghost<T> into Ghost<&T>
erasure
_terminates
ghost
ensures
**result == **selfSourcepub fn borrow_mut(&mut self) -> Ghost<&mut T>
pub fn borrow_mut(&mut self) -> Ghost<&mut T>
Transforms a &mut Ghost<T> into a Ghost<&mut T>.
erasure
_terminates
ghost
ensures
*result == &mut **selfSourcepub fn conjure() -> Self
pub fn conjure() -> Self
Conjures a Ghost<T> out of thin air.
This would be unsound in verified code, hence the false precondition.
This function is nevertheless useful to create a Ghost in “trusted”
contexts, when axiomatizing an API that is believed to be sound for
external reasons.
erasure
_terminates
ghost
requires
falseSource§impl<T: ?Sized> Ghost<T>
impl<T: ?Sized> Ghost<T>
Sourcepub fn new(x: T) -> Selfwhere
T: Sized,
pub fn new(x: T) -> Selfwhere
T: Sized,
Creates a new ghost variable.
This function can only be called in ghost! code.
terminates
ghost
ensures
*result == xSourcepub fn into_inner(self) -> Twhere
T: Sized,
pub fn into_inner(self) -> Twhere
T: Sized,
Returns the inner value of the Ghost.
This function can only be called in ghost! context.
terminates
ghost
ensures
result == *selfSourcepub fn inner_logic(self) -> Twhere
T: Sized,
pub fn inner_logic(self) -> Twhere
T: Sized,
Returns the inner value of the Ghost.
You should prefer the dereference operator * instead.
⚠
Trait Implementations§
Source§impl<'a, L> LocalInvariantExt<'a> for &'a Ghost<L>
impl<'a, L> LocalInvariantExt<'a> for &'a Ghost<L>
Source§fn open<A, F>(self, tokens: Ghost<Tokens<'a>>, f: F) -> A
fn open<A, F>(self, tokens: Ghost<Tokens<'a>>, f: F) -> A
requires
<Ghost<&'a L> as LocalInvariantExt<'a>>::open.precondition((Ghost::new_logic(&**self), tokens, f))
ensures
<Ghost<&'a L> as LocalInvariantExt<'a>>::open.postcondition((Ghost::new_logic(&**self), tokens, f), result)
type Inner = <Ghost<&'a L> as LocalInvariantExt<'a>>::Inner
Source§impl<'a, T: Protocol> LocalInvariantExt<'a> for Ghost<&'a LocalInvariant<T>>
impl<'a, T: Protocol> LocalInvariantExt<'a> for Ghost<&'a LocalInvariant<T>>
Source§fn open<A, F>(self, tokens: Ghost<Tokens<'a>>, f: F) -> A
fn open<A, F>(self, tokens: Ghost<Tokens<'a>>, f: F) -> A
requires
tokens.contains(self.namespace())requires
forall<t: Ghost<&mut T>> (**t).protocol(self.public()) && inv(t) ==> f.precondition((t,)) && // f must restore the invariant (forall<res: A> f.postcondition_once((t,), res) ==> (^t).protocol(self.public()))
ensures
exists<t: Ghost<&mut T>> t.protocol(self.public()) && f.postcondition_once((t,), result)
type Inner = T
Source§impl<'a, T> LocalInvariantExt<'a> for Ghost<&'a T>
impl<'a, T> LocalInvariantExt<'a> for Ghost<&'a T>
Source§fn open<A, F>(self, tokens: Ghost<Tokens<'a>>, f: F) -> A
fn open<A, F>(self, tokens: Ghost<Tokens<'a>>, f: F) -> A
requires
T::deref.precondition((*self,))requires
forall<this> T::deref.postcondition((*self,), this) ==> <Ghost<&'a T::Target> as LocalInvariantExt<'a>>::open.precondition((Ghost::new_logic(this), tokens, f))
ensures
exists<this> T::deref.postcondition((*self,), this) && <Ghost<&'a T::Target> as LocalInvariantExt<'a>>::open.postcondition((Ghost::new_logic(this), tokens, f), result)