Skip to main content

BrandedCell

Struct BrandedCell 

Source
pub struct BrandedCell<'brand, T>
where T: ?Sized,
{ /* private fields */ }
Expand description

A GhostCell-style shared container allowing interior mutability.

Permits shared read access and exclusive write access mediated by a Melinoe ReadPermit or WritePermit. Thread-confined heaps use super::ThreadLocalToken; super::SyncRegionToken enables an explicit cross-thread handoff for Send payloads.

§Variance

BrandedCell<'brand, T> is invariant in T (and in 'brand). This is a soundness requirement, not a convenience: the cell is Copy and writable through borrow_mut, so a covariant cell would allow a safe lifetime-shortening coercion of one copy (e.g. BrandedCell<'brand, &'static str> → BrandedCell<'brand, &'a str>), a write of a short-lived &'a str through the coerced copy, and a read of the original copy as &'static str — a dangling reference with no unsafe at the call site. This is exactly why GhostCell wraps its payload in the invariant core::cell::UnsafeCell; here the payload lives behind a (covariant) NonNull, so invariance is pinned explicitly by the PhantomData<*mut T> field.

§Examples

Token-mediated shared reads and exclusive writes across Copy handles:

use mnemosyne_core::StandardPolicy;
use mnemosyne_backend::MemoryBackendWrapper;
use mnemosyne_heap::{scope, BrandedCell};

scope::<StandardPolicy, MemoryBackendWrapper, _, _>(|heap, mut token| {
    let block = heap.alloc_init(&token, 41).expect("cell allocation failed");
    // SAFETY: `alloc_init` returned a block holding an initialized value.
    let cell = unsafe { BrandedCell::from_block(block) };
    let copy = cell; // `Copy`: multiple shared handles to one value
    *cell.borrow_mut(&mut token) += 1;
    assert_eq!(*copy.borrow(&token), 42);
    // SAFETY: `cell`/`copy` are the only handles and neither is used again.
    heap.free(&mut token, unsafe { cell.into_block() });
});

The covariant coercion described above fails to compile — the invariance marker rejects shortening the lifetime inside T:

ⓘ
use mnemosyne_heap::BrandedCell;

fn shorten<'brand, 'a>(
    cell: BrandedCell<'brand, &'static str>,
) -> BrandedCell<'brand, &'a str> {
    cell // ERROR: `BrandedCell` is invariant in `T`
}

Implementations§

Source§

impl<'brand, T> BrandedCell<'brand, T>
where T: ?Sized,

Source

pub unsafe fn from_block( block: BrandedBlock<'brand, T>, ) -> BrandedCell<'brand, T>

Creates a new BrandedCell from a BrandedBlock.

§Safety

The block must be initialized.

Source

pub fn as_ptr(&self) -> *mut T

Returns the raw pointer to the cell’s managed memory.

Source

pub unsafe fn into_block(self) -> BrandedBlock<'brand, T>

Consumes the BrandedCell (by copy) and reconstructs the BrandedBlock.

§Safety

The caller must ensure that this is the only active reference to the cell, and that no other copies of this BrandedCell will be used to access the memory.

Source

pub fn borrow<'a, P>(&'a self, _permit: P) -> &'a T
where P: ReadPermit<'brand> + 'a,

Accesses the value immutably using a Melinoe read permit.

Source

pub fn borrow_mut<'a, P>(&self, _permit: &'a mut P) -> &'a mut T
where &'permit mut P: for<'permit> WritePermit<'brand>,

Accesses the value mutably using a Melinoe write permit.

Source

pub fn borrow_mut_2<'a, U, P>( cell1: &'a BrandedCell<'brand, T>, cell2: &'a BrandedCell<'brand, U>, _permit: &'a mut P, ) -> (&'a mut T, &'a mut U)
where &'permit mut P: for<'permit> WritePermit<'brand>, U: ?Sized,

Mutably borrows two distinct cells at the same time.

§Panics

Panics if the two cells point to the same memory block.

Source

pub fn borrow_mut_3<'a, U, V, P>( cell1: &'a BrandedCell<'brand, T>, cell2: &'a BrandedCell<'brand, U>, cell3: &'a BrandedCell<'brand, V>, _permit: &'a mut P, ) -> (&'a mut T, &'a mut U, &'a mut V)
where &'permit mut P: for<'permit> WritePermit<'brand>, U: ?Sized, V: ?Sized,

Mutably borrows three distinct cells at the same time.

§Panics

Panics if any of the cells point to the same memory block.

Trait Implementations§

Source§

impl<'brand, T> Clone for BrandedCell<'brand, T>
where T: ?Sized,

Source§

fn clone(&self) -> BrandedCell<'brand, T>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'brand, T> Copy for BrandedCell<'brand, T>
where T: ?Sized,

Source§

impl<'brand, T> Debug for BrandedCell<'brand, T>
where T: ?Sized,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'brand, T> Eq for BrandedCell<'brand, T>
where T: ?Sized,

Source§

impl<'brand, T> Hash for BrandedCell<'brand, T>
where T: ?Sized,

Source§

fn hash<H>(&self, state: &mut H)
where H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'brand, T> PartialEq for BrandedCell<'brand, T>
where T: ?Sized,

Source§

fn eq(&self, other: &BrandedCell<'brand, T>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<'brand, T> Send for BrandedCell<'brand, T>
where T: Send + ?Sized,

Source§

impl<'brand, T> Sync for BrandedCell<'brand, T>
where T: Send + Sync + ?Sized,

Auto Trait Implementations§

§

impl<'brand, T> Freeze for BrandedCell<'brand, T>

§

impl<'brand, T> RefUnwindSafe for BrandedCell<'brand, T>

§

impl<'brand, T> Unpin for BrandedCell<'brand, T>

§

impl<'brand, T> UnsafeUnpin for BrandedCell<'brand, T>

§

impl<'brand, T> UnwindSafe for BrandedCell<'brand, T>

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.