Trait without_alloc::alloc::LocalAllocLeakExt
source · [−]pub trait LocalAllocLeakExt<'alloc>: LocalAlloc<'alloc> {
fn alloc_layout(
&'alloc self,
layout: NonZeroLayout
) -> Option<LeakedAllocation<'alloc>> { ... }
fn alloc_t<V>(&'alloc self) -> Option<LeakedAllocation<'alloc, V>> { ... }
fn boxed<V>(&'alloc self, val: V) -> Option<Box<'alloc, V>> { ... }
fn fixed_vec<V>(&'alloc self, capacity: usize) -> Option<FixedVec<'alloc, V>> { ... }
fn rc<V>(&'alloc self, val: V) -> Option<Rc<'alloc, V>> { ... }
fn copy_slice<T: Copy>(&'alloc self, slice: &[T]) -> Option<&'alloc mut [T]> { ... }
fn copy_str(&'alloc self, st: &str) -> Option<&'alloc str> { ... }
unsafe fn copy_dst<T: ?Sized>(
&'alloc self,
val: &ManuallyDrop<T>
) -> Option<&'alloc mut T> { ... }
}
Expand description
Leak allocations into uninit regions.
Provided Methods
sourcefn alloc_layout(
&'alloc self,
layout: NonZeroLayout
) -> Option<LeakedAllocation<'alloc>>
fn alloc_layout(
&'alloc self,
layout: NonZeroLayout
) -> Option<LeakedAllocation<'alloc>>
Leak an allocation with detailed layout.
Provides an Uninit
wrapping several aspects of initialization in a safe interface,
bound by the lifetime of the reference to the allocator.
sourcefn alloc_t<V>(&'alloc self) -> Option<LeakedAllocation<'alloc, V>>
fn alloc_t<V>(&'alloc self) -> Option<LeakedAllocation<'alloc, V>>
Leak an allocation for a specific type.
It is not yet initialized but provides a safe interface for that initialization. Note that the type can be a ZST in which case a dangling pointer is substituted for the true allocation.
Usage
use core::cell::{Ref, RefCell};
let slab: Bump<[Ref<'static, usize>; 1]> = Bump::uninit();
let data = RefCell::new(0xff);
// We can place a `Ref` here but we did not yet.
let alloc = slab.alloc_t::<Ref<usize>>().unwrap();
let cell_ref = alloc.uninit.init(data.borrow());
assert_eq!(**cell_ref, 0xff);
sourcefn copy_slice<T: Copy>(&'alloc self, slice: &[T]) -> Option<&'alloc mut [T]>
fn copy_slice<T: Copy>(&'alloc self, slice: &[T]) -> Option<&'alloc mut [T]>
Allocate a slice of a copyable type.
This will allocate some memory with the same layout as required by the slice, then copy all values into the new allocation via a byte copy.
let slab: Bump<[usize; 16]> = Bump::uninit();
let data: &[u8] = b"Hello, World!";
let slice = slab.copy_slice(data).unwrap();
assert_eq!(data, slice);
sourcefn copy_str(&'alloc self, st: &str) -> Option<&'alloc str>
fn copy_str(&'alloc self, st: &str) -> Option<&'alloc str>
Allocate a dynamically sized string.
This will allocate some memory with the same layout as required by the string, then copy all characters into the new allocation via a byte copy.
let slab: Bump<[u8; 16]> = Bump::uninit();
let data: &str = "Hello, World!";
let slice = slab.copy_str(data).unwrap();
assert_eq!(data, slice);
sourceunsafe fn copy_dst<T: ?Sized>(
&'alloc self,
val: &ManuallyDrop<T>
) -> Option<&'alloc mut T>
unsafe fn copy_dst<T: ?Sized>(
&'alloc self,
val: &ManuallyDrop<T>
) -> Option<&'alloc mut T>
Allocate a copy of a generic dynamically sized type.
This method takes a ManuallyDrop<T>
wrapper instead of a T
directly. These types are of
course layout compatible and you may soundly cast one reference type to the other. However
this choice forces acknowledgment that the value must not be dropped by the caller
afterwards and makes this reasonably more safe in case of panics.
Note further that mutable access is however explicitly not required in contrast to
ManuallyDrop::take
. Otherwise, the caller would have to ensure that the value is not
aliased and actually mutable. Keeping these guarantees often involves moving the value into
a new stack slot which is obviously not possible for dynamically sized values. This
interfaces promises not to overwrite any byte which does not restrict its functionality.
Safety
This is quite unsafe and relies on the nightly set_ptr_value
feature. Furthermore this
method does not require that T
is in fact Copy
as doing so would not be possible for
dynamically sized values. You must either require this bound on the expose interface or
must ensure the source value behind the pointer is not used further, not dropped and
basically discarded. You should act as if take
had been called on the supplied value.
Example
use core::fmt::Debug;
use core::mem::ManuallyDrop;
let slab: Bump<[u8; 16]> = Bump::uninit();
let debuggable = ManuallyDrop::new(1usize);
let debug = unsafe {
slab.copy_dst::<dyn Debug>(&debuggable).unwrap()
};
assert_eq!(format!("{:?}", debug), "1");