Open
Description
Proposal
add an Allocator
impl for &mut A
when A: ?Sized + Allocator
that forwards to the underlying implementation
Problem statement
&mut A
currently doesn't impl Allocator
when A
does
Motivating examples or use cases
the current state of things makes it cumbersome to work with Send allocators (especially type erased dyn 'a + Send + Allocator
). examples of allocators that are Send, but not Sync are local allocators that wrap a RefCell
to satisfy the immutable ref api.
Solution sketch
we can just copy the &A
implementation
unsafe impl<A> Allocator for &mut A
where
A: Allocator + ?Sized,
{
#[inline]
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
(**self).allocate(layout)
}
#[inline]
fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
(**self).allocate_zeroed(layout)
}
#[inline]
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
// SAFETY: the safety contract must be upheld by the caller
unsafe { (**self).deallocate(ptr, layout) }
}
#[inline]
unsafe fn grow(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
// SAFETY: the safety contract must be upheld by the caller
unsafe { (**self).grow(ptr, old_layout, new_layout) }
}
#[inline]
unsafe fn grow_zeroed(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
// SAFETY: the safety contract must be upheld by the caller
unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) }
}
#[inline]
unsafe fn shrink(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
// SAFETY: the safety contract must be upheld by the caller
unsafe { (**self).shrink(ptr, old_layout, new_layout) }
}
}
Alternatives
an alternative solution is using a ByMut<A>
wrapper that's a thin wrapper over &mut A
, but this is an unnecessary hoop to make users jump through
Activity