Struct vstd::cell::PCell

source ·
pub struct PCell<V> { /* private fields */ }
Expand description

PCell<V> (which stands for “permissioned call”) is the primitive Verus Cell type.

Technically, it is a wrapper around core::cell::UnsafeCell<core::mem::MaybeUninit<V>>, and thus has the same runtime properties: there are no runtime checks (as there would be for Rust’s traditional core::cell::RefCell). Its data may be uninitialized.

Furthermore (and unlike both core::cell::Cell and core::cell::RefCell), a PCell<V> may be Sync (depending on V). Thanks to verification, Verus ensures that access to the cell is data-race-free.

PCell uses a ghost permission token similar to ptr::PPtr – see the ptr::PPtr documentation for the basics. For PCell, the associated type of the permission token is cell::PointsTo.

Differences from PPtr.

The key difference is that, whereas ptr::PPtr represents a fixed address in memory, a PCell has no fixed address because a PCell might be moved. As such, the pcell.id() does not correspond to a memory address; rather, it is a unique identifier that is fixed for a given cell, even when it is moved.

The arbitrary ID given by pcell.id() is of type CellId. Despite the fact that it is, in some ways, “like a pointer”, note that CellId does not support any meangingful arithmetic, has no concept of a “null ID”, and has no runtime representation.

Also note that the PCell might be dropped before the PointsTo token is dropped, although in that case it will no longer be possible to use the PointsTo in exec code to extract data from the cell.

Example (TODO)

Implementations§

source§

impl<V> PCell<V>

source

pub spec fn id(&self) -> CellId

A unique ID for the cell.

source

pub const exec fn empty() -> (PCell<V>, Tracked<PointsTo<V>>)

ensures
pt.1@@ === pcell_opt![pt.0.id() => Option::None],

Return an empty (“uninitialized”) cell.

source

pub const exec fn new(v: V) -> (PCell<V>, Tracked<PointsTo<V>>)

ensures
(pt.1@@
    === PointsToData {
        pcell: pt.0.id(),
        value: Option::Some(v),
    }),
source

pub exec fn put(&self, verus_tmp_perm: Tracked<&mut PointsTo<V>>, v: V)

requires
old(perm)@ === pcell_opt![self.id() => Option::None],
ensures
perm@ === pcell_opt![self.id() => Option::Some(v)],
source

pub exec fn take(&self, verus_tmp_perm: Tracked<&mut PointsTo<V>>) -> V

requires
self.id() === old(perm)@.pcell,
old(perm)@.value.is_Some(),
ensures
perm@.pcell === old(perm)@.pcell,
perm@.value === Option::None,
v === old(perm)@.value.get_Some_0(),
source

pub exec fn replace(&self, verus_tmp_perm: Tracked<&mut PointsTo<V>>, in_v: V) -> V

requires
self.id() === old(perm)@.pcell,
old(perm)@.value.is_Some(),
ensures
perm@.pcell === old(perm)@.pcell,
perm@.value === Option::Some(in_v),
out_v === old(perm)@.value.get_Some_0(),
source

pub exec fn borrow<'a>(&'a self, verus_tmp_perm: Tracked<&'a PointsTo<V>>) -> &'a V

requires
self.id() === perm@.pcell,
perm@.value.is_Some(),
ensures
*v === perm@.value.get_Some_0(),
source

pub exec fn into_inner(self, verus_tmp_perm: Tracked<PointsTo<V>>) -> V

requires
self.id() === perm@.pcell,
perm@.value.is_Some(),
ensures
v === perm@.value.get_Some_0(),
source§

impl<V: Copy> PCell<V>

source

pub exec fn write(&self, verus_tmp_perm: Tracked<&mut PointsTo<V>>, in_v: V)

requires
self.id() === old(perm)@.pcell,
old(perm)@.value.is_Some(),
ensures
perm@.pcell === old(perm)@.pcell,
perm@.value === Some(in_v),

Trait Implementations§

source§

impl<T> Send for PCell<T>

source§

impl<T> Sync for PCell<T>

Auto Trait Implementations§

§

impl<V> !RefUnwindSafe for PCell<V>

§

impl<V> Unpin for PCell<V>
where V: Unpin,

§

impl<V> UnwindSafe for PCell<V>
where V: UnwindSafe,

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>,

§

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>,

§

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.