pub struct Uninit<'a, T: ?Sized> { /* private fields */ }
Expand description

Points to an uninitialized place but would otherwise be a valid reference.

This is a &mut-like struct that is somewhat of a pendant to MaybeUninit. It makes it possible to deal with uninitialized allocations without requiring an unsafe block initializing them and offers a much safer interface for partial initialization and layout calculations than raw pointers.

Note that it also supports slices which means it does not use MaybeUninit internally but offers conversion where necessary.

Usage

The basic usage is also interacting with MaybeUninit:

use core::mem::MaybeUninit;
use without_alloc::Uninit;

let mut alloc: MaybeUninit<MyStruct> = MaybeUninit::uninit();
let uninit = Uninit::from_maybe_uninit(&mut alloc);

// notice: no unsafe
let instance: &mut MyStruct = uninit.init(MyStruct::default());

But since we are working on arbitrary uninitialized memory it is also possible to reuse the structure for completely arbitrary other types. Just note that there is no integrated mechanis for calling Drop.

use core::mem::MaybeUninit;
use without_alloc::Uninit;

// Just a generic buffer.
let mut alloc: MaybeUninit<[u32; 1024]> = MaybeUninit::uninit();
let uninit = Uninit::from_maybe_uninit(&mut alloc);

// Now use the first `u32` for a counter:
let mut counter = uninit.cast().unwrap();
let mut tail = counter.split_to_fit();
let counter: &mut u32 = counter.init(0);

// And some more for a few `u64`.
// Note that these are not trivially aligned, but `Uninit` does that for us.
let mut values = tail.split_cast().unwrap();
// No more use, so don't bother with `split_to_fit` and just `init`.
let values: &mut [u64; 2] = values.init([0xdead, 0xbeef]);

Implementations

Create a uninit pointer from raw memory.

Safety

A valid allocation must exist at the pointer with length at least len. There must be no references aliasing the memory location, and it must be valid to write uninitialized bytes into arbitrary locations of the region.

In particular, it is UB to create this from a reference to a variable of a type for which a completely uninitialized content is not valid. The standard type for avoiding the UB is core::mem::MaybeUninit.

When in doubt, refactor code such that utilization of from_maybe_uninit is possible.

Split so that the second part fits the layout.

Return Ok if this is possible in-bounds and Err if it is not.

Split so that the tail is aligned and valid for a U.

Return Ok if this is possible in-bounds (aligned and enough room for at least one U) and Err if it is not. The first tuple element is the Uninit pointing to the skipped memory.

Split so that the tail is aligned for a slice [U].

Return Ok if this is possible in-bounds and Err if it is not. The first tuple element is the Uninit pointing to the skipped memory.

The length of the slice is the arbitrary amount that fits into the tail of the allocation. Note that the length always fulfills the safety requirements for slice::from_raw_parts since the Uninit must be contained in a single allocation.

Invent a new uninit allocation for a zero-sized type (ZST).

Panics

This method panics when the type parameter is not a zero sized type.

Create an uninit from a view.

Safety

The caller must prove that the pointed-to memory is mutable and that it is unaliased.

Create an initializable pointer to the inner bytes of a MaybeUninit.

Split the uninit slice at a byte boundary.

Return Ok if the location is in-bounds and Err if it is out of bounds.

Try to cast to an Uninit for another type.

Return Ok if the current Uninit is suitably aligned and large enough to hold at least one U and Err if it is not. Note that the successful result points to unused remaining memory behind where the instance can be placed.

Use split_to_fit to get rid of surplus memory at the end.

Try to cast to an Uninit for a slice type.

Return Ok if the current Uninit is suitably aligned and large enough to hold at least one U and Err if it is not. Note that the successful result points to unused remaining memory behind where the instances can be placed.

Split off the tail that is not required for holding an instance of T.

This operation is idempotent.

Acquires the underlying *mut pointer.

Acquires the underlying pointer as a NonNull.

Dereferences the content.

The resulting lifetime is bound to self so this behaves “as if” it were actually an instance of T that is getting borrowed. If a longer lifetime is needed, use into_ref.

Safety

The pointee must have been initialized through other means.

Mutably dereferences the content.

The resulting lifetime is bound to self so this behaves “as if” it were actually an instance of T that is getting borrowed. If a longer lifetime is needed, use into_mut.

Safety

The pointee must have been initialized through other means.

Turn this into a reference to the content.

Safety

The pointee must have been initialized through other means.

Turn this into a mutable reference to the content.

Safety

The pointee must have been initialized through other means.

Initialize the place and return a reference to the value.

Turn this into a reference to standard MaybeUninit.

This is mainly useful for interfacing with other consumers which expect standard library types. It may also improve ergonomics for writing to the pointee partially initialized instances of T that are obtained via other means.

Note that the sequence from_maybe_uninit, into_maybe_uninit is a no-op. The converse is however not the case, as it will potentially discard unused padding present in the original Uninit.

Read a value from the uninit place without moving it.

The Uninit ensures that the inner pointer is correctly aligned, non-null, and points to a large enough region for reading a T.

Safety

Caller must ensure that the memory is initialized as a valid T. It must also avoid double Drop. Basically, a new instance is created.

Utilize this Uninit allocation for a boxed value.

Stores the value at the pointed-to location and utilizes the Box as a RAII-guard to properly drop the value when the box itself is dropped.

Creates a pointer to an empty slice.

Create an initializable pointer to the inner bytes of a MaybeUninit.

Get the pointer to the first element of the slice.

If the slice would be empty then the pointer may be the past-the-end pointer as well.

Calculate the theoretical capacity of a slice in the pointed-to allocation.

Split the slice at an index.

This is the pointer equivalent of slice::split_at.

Get the trailing bytes behind the slice.

The underlying allocation need not be a multiple of the slice element size which may leave unusable bytes. This splits these unusable bytes into an untyped Uninit which can be reused arbitrarily.

This operation is idempotent.

Split the first element from the slice.

This is the pointer equivalent of slice::split_first.

Split the last element from the slice.

This is the pointer equivalent of slice::split_last.

Turn this into a slice of standard MaybeUninits.

This is mainly useful for interfacing with other consumers which expect standard library types. It may also improve ergonomics for writing to the pointee partially initialized instances of T that are obtained via other means.

Note that the sequence from_maybe_uninit_slice, into_maybe_uninit_slice is a no-op. The converse is however not the case, as it will potentially discard unused padding present in the original Uninit.

Create a view to typed uninitialized memory.

It is given a capacity of memory to which it refers in bytes.

Safety

The ptr must describe a valid, sized region. Refer to Layout::for_value_raw for details. This criteria is trivially fulfilled for any sized T.

A valid allocation must exist at the pointer with length at least len.

In particular, it is UB to create this from a reference to a variable of a type for which a completely uninitialized content is not valid. The standard type for avoiding the UB is core::mem::MaybeUninit.

When in doubt, refactor code such that utilization of from_maybe_uninit is possible.

Return the number of bytes this may view.

Check if the view fits some layout.

The cast to a type of the provided layout will work without error.

View the same uninit as untyped memory.

Borrow a view of the Uninit region.

This is the equivalent of &*mut_ref as *const _ but never runs afoul of accidentally creating an actual reference.

Borrow the Uninit region for a shorter duration.

This is the equivalent of &mut *mut_ref as *mut _ but never runs afoul of accidentally creating an actual reference.

Get the byte size of the total allocation.

Trait Implementations

The type we point to. This influences which kinds of unsizing are possible. Read more
The output type when unsizing the pointee to U.
Get the raw inner pointer.
Replace the container inner pointer with an unsized version. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Convert a pointer, as if with unsize coercion. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.