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,
impl<'brand, T> BrandedCell<'brand, T>where
T: ?Sized,
Sourcepub unsafe fn from_block(
block: BrandedBlock<'brand, T>,
) -> BrandedCell<'brand, T>
pub unsafe fn from_block( block: BrandedBlock<'brand, T>, ) -> BrandedCell<'brand, T>
Sourcepub unsafe fn into_block(self) -> BrandedBlock<'brand, T>
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.
Sourcepub fn borrow<'a, P>(&'a self, _permit: P) -> &'a Twhere
P: ReadPermit<'brand> + 'a,
pub fn borrow<'a, P>(&'a self, _permit: P) -> &'a Twhere
P: ReadPermit<'brand> + 'a,
Accesses the value immutably using a Melinoe read permit.
Sourcepub fn borrow_mut<'a, P>(&self, _permit: &'a mut P) -> &'a mut Twhere
&'permit mut P: for<'permit> WritePermit<'brand>,
pub fn borrow_mut<'a, P>(&self, _permit: &'a mut P) -> &'a mut Twhere
&'permit mut P: for<'permit> WritePermit<'brand>,
Accesses the value mutably using a Melinoe write permit.
Sourcepub 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)
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)
Mutably borrows two distinct cells at the same time.
§Panics
Panics if the two cells point to the same memory block.
Sourcepub 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)
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)
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,
impl<'brand, T> Clone for BrandedCell<'brand, T>where
T: ?Sized,
Source§fn clone(&self) -> BrandedCell<'brand, T>
fn clone(&self) -> BrandedCell<'brand, T>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more