noop_allocator/
owning_ref.rs

1//! Functions to produce an [`OwningRef<'_, T>`][OwningRef], a.k.a. a `Box<T,
2//! NoopAllocator<'_>>`, from a mutably borrowed `MaybeUninit<T>` or
3//! `ManuallyDrop<T>`.
4use core::{
5    marker::PhantomData,
6    mem::{ManuallyDrop, MaybeUninit},
7};
8
9use crate::NoopAllocator;
10use alloc::boxed::Box;
11
12/// An owning reference boorrowing a memory location but owning the value in it,
13/// implemented as `Box<T, NoopAllocator<'a>>`.
14pub type OwningRef<'a, T> = Box<T, NoopAllocator<'a>>;
15
16/// Create a `OwningRef<'a, T>` from a `&'a mut ManuallyDrop<T>>`.
17///
18/// # Safety
19///
20/// Dropping or moving out of the `OwningRef` leaves the borrowed `ManuallyDrop`
21/// semantically without a value; see [`ManuallyDrop::drop`] and
22/// [`ManuallyDrop::take`].
23///
24/// You must not use the `Box` in such a way that would violate the vailidity
25/// invariant of the `ManuallyDrop<T>`.
26pub unsafe fn from_manuallydrop<T: ?Sized>(slot: &mut ManuallyDrop<T>) -> OwningRef<'_, T> {
27    Box::from_raw_in(
28        slot as *mut ManuallyDrop<T> as *mut T,
29        NoopAllocator(PhantomData),
30    )
31}
32
33/// Create a `OwningRef<'a, T>` from a `&'a mut MaybeUninit<T>>`.
34///
35/// # Safety
36///
37/// The `T` must be initialized, see [`MaybeUninit::assume_init_mut`] and
38/// [`MaybeUninit::assume_init_drop`].
39pub unsafe fn from_maybeuninit<T>(slot: &mut MaybeUninit<T>) -> OwningRef<'_, T> {
40    Box::from_raw_in(slot.as_mut_ptr(), NoopAllocator(PhantomData))
41}
42
43/// Create a `OwningRef<'a, T>` from a `&'a mut MaybeUninit<T>>` by writing a
44/// value into it.
45///
46/// The `MaybeUninit<T>` will be overwritten with `value`.
47pub fn from_maybeuninit_write<T>(slot: &mut MaybeUninit<T>, value: T) -> OwningRef<'_, T> {
48    slot.write(value);
49    unsafe { Box::from_raw_in(slot.as_mut_ptr(), NoopAllocator(PhantomData)) }
50}
51
52/// Create a `OwningRef<'a, [T]>` from a `&'a mut [MaybeUninit<T>]>`.
53///
54/// # Safety
55///
56/// All slice elements must be initialized, see [`MaybeUninit::assume_init_mut`]
57/// and [`MaybeUninit::assume_init_drop`].
58pub unsafe fn from_maybeuninit_slice<T>(slot: &mut [MaybeUninit<T>]) -> OwningRef<'_, [T]> {
59    Box::from_raw_in(
60        slot as *mut [MaybeUninit<T>] as *mut [T],
61        NoopAllocator(PhantomData),
62    )
63}
64
65/// Create a `OwningRef<'a, T>` from a raw pointer.
66///
67/// # Safety
68///
69/// The memory behind `ptr` must be uniquely borrowed for `'a`.
70///
71/// The pointee must be initialized, see
72/// [`MaybeUninit::assume_init_mut`] and [`MaybeUninit::assume_init_drop`].
73pub unsafe fn from_raw<'a, T: ?Sized>(ptr: *mut T) -> OwningRef<'a, T> {
74    Box::from_raw_in(ptr, NoopAllocator(PhantomData))
75}