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}