Source code
Revision control
Copy as Markdown
Other Tools
use core::marker::PhantomData;
/// a mutable "slice" (bundle of pointer and length). The main goal of this type is passing MIRI
/// with stacked borrows. In particular, storing a standard slice in data structures violates the
/// stacked borrows rule when that slice is deallocated. By only materializing the slice when
/// needed for data access, hence bounding the lifetime more tightly, this restriction is circumvented.
#[derive(Debug)]
pub(crate) struct WeakSliceMut<'a, T> {
ptr: *mut T,
len: usize,
_marker: PhantomData<&'a mut [T]>,
}
impl<'a, T> WeakSliceMut<'a, T> {
/// # Safety
///
/// The arguments must satisfy the requirements of [`core::slice::from_raw_parts_mut`]. The
/// difference versus a slice is that the slice requirements are only enforced when a slice is
/// needed, so in practice we mostly get the bounds checking and other convenient slice APIs,
/// without the exact correctness constraints of a rust core/std slice.
pub(crate) unsafe fn from_raw_parts_mut(ptr: *mut T, len: usize) -> Self {
Self {
ptr,
len,
_marker: PhantomData,
}
}
pub(crate) fn into_raw_parts(self) -> (*mut T, usize) {
(self.ptr, self.len)
}
pub(crate) fn as_slice(&self) -> &'a [T] {
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
}
pub(crate) fn as_mut_slice(&mut self) -> &'a mut [T] {
unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
}
pub(crate) fn as_ptr(&self) -> *const T {
self.ptr
}
pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
self.ptr
}
pub(crate) fn len(&self) -> usize {
self.len
}
pub(crate) fn is_empty(&self) -> bool {
self.len() == 0
}
pub(crate) fn empty() -> Self {
let buf = &mut [];
Self {
ptr: buf.as_mut_ptr(),
len: buf.len(),
_marker: PhantomData,
}
}
}
#[derive(Debug)]
pub(crate) struct WeakArrayMut<'a, T, const N: usize> {
ptr: *mut [T; N],
_marker: PhantomData<&'a mut [T; N]>,
}
impl<'a, T, const N: usize> WeakArrayMut<'a, T, N> {
/// # Safety
///
/// The pointer must be [convertable to a reference](https://doc.rust-lang.org/std/ptr/index.html#pointer-to-reference-conversion).
pub(crate) unsafe fn from_ptr(ptr: *mut [T; N]) -> Self {
Self {
ptr,
_marker: PhantomData,
}
}
pub(crate) fn as_slice(&self) -> &'a [T] {
unsafe { core::slice::from_raw_parts(self.ptr.cast(), N) }
}
pub(crate) fn as_mut_slice(&mut self) -> &'a mut [T] {
unsafe { core::slice::from_raw_parts_mut(self.ptr.cast(), N) }
}
pub(crate) fn as_mut_ptr(&mut self) -> *mut [T; N] {
self.ptr
}
}