Trait LocalAllocLeakExt

Source
pub trait LocalAllocLeakExt<'alloc>: LocalAlloc<'alloc> {
    // Provided methods
    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§

Source

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.

Source

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);
Source

fn boxed<V>(&'alloc self, val: V) -> Option<Box<'alloc, V>>

Allocate a Box.

This will allocate some memory with the correct layout for a Box, then place the provided value into the allocation by constructing an Box.

Source

fn fixed_vec<V>(&'alloc self, capacity: usize) -> Option<FixedVec<'alloc, V>>

Allocate a FixedVec.

This will allocate some memory with the correct layout for a FixedVec of the given capacity (in elements) and wrap it. Returns None if it is not possible to allocate the layout.

Source

fn rc<V>(&'alloc self, val: V) -> Option<Rc<'alloc, V>>

Allocate an Rc.

This will allocate some memory with the correct layout for an Rc, then place the provided value into the allocation by constructing an Rc.

Source

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);
Source

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);
Source

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");

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<'alloc, T> LocalAllocLeakExt<'alloc> for T
where T: LocalAlloc<'alloc>,