uninit_tools/traits.rs
1use core::mem::MaybeUninit;
2
3use crate::wrappers::AssertInit;
4
5#[cfg(feature = "alloc")]
6use alloc::{boxed::Box, rc::Rc, string::String, sync::Arc, vec::Vec};
7
8/// A trait for mutable initializable slices, that provide access to all the data required for
9/// initialization, before the data can be assumed to be fully initialized.
10///
11/// # Safety
12///
13/// This trait is unsafe to implement since whatever slices are returned from the casts here,
14/// __must have the same length and point to the same memory as before__. This is to allow safer
15/// abstractions to assume that there are has not unexpectedly appeared additional items that must
16/// be initialized.
17pub unsafe trait Initialize {
18 type Item;
19
20 /// Retrieve an immutable slice pointing to possibly uninitialized memory. __This must be
21 /// exactly the same slice as the one from [`as_maybe_uninit_slice_mut`], or the trait
22 /// implementation as a whole, gets incorrect.__
23 ///
24 /// [`as_maybe_uninit_slice_mut`]: Self::as_maybe_uninit_slice_mut
25 fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<Self::Item>];
26
27 /// Retrieve a mutable slice pointing to possibly uninitialized memory. __This must always
28 /// point to the same slice as with previous invocations__.
29 ///
30 /// # Safety
31 ///
32 /// The caller must not use the resulting slice to de-initialize the data.
33 unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<Self::Item>];
34}
35
36/// A trait for slices (or owned memory) that contain possibly uninitialized slices themselves.
37/// That is, the [`Initialize`] trait but for singly-indirect slices.
38///
39/// # Safety
40///
41/// For this trait to be implemented correctly, [`as_maybe_uninit_vectors`] and
42/// [`as_maybe_uninit_vectors_mut`] must always return the same slices (albeit with different
43/// aliasing rules as they take `&self` and `&mut self` respectively).
44///
45/// [`as_maybe_uninit_vectors`]: InitializeVectored::as_maybe_uninit_vectors
46/// [`as_maybe_uninit_vectors_mut`]: InitializeVectored::as_maybe_uninit_vectors_mut
47pub unsafe trait InitializeVectored {
48 /// The possibly uninitialized vector type, which must implement [`Initialize`]. Note that this
49 /// does not necessarily need to deref into [`MaybeUninit<Item>`], but can be anything that is
50 /// convertible to it.
51 type UninitVector: Initialize;
52
53 /// Get the uninitialized version of all vectors. This slice must always be exactly equal to
54 /// the slice returned by
55 /// [`as_maybe_uninit_vectors_mut`](InitializeVectored::as_maybe_uninit_vectors_mut), except
56 /// being borrowed differently, or the trait is unsoundly implemented.
57 ///
58 /// [`as_maybe_uninit_slice_mut`]: InitializeVectored::as_maybe_uninit_slice_mut
59 fn as_maybe_uninit_vectors(&self) -> &[Self::UninitVector];
60
61 /// Get the uninitialized version of all vectors, mutably. This slice must always be exactly
62 /// equal to the slice returned by [`as_maybe_uninit_vectors`](Self::as_maybe_uninit_vectors),
63 /// or the trait is unsoundly implemented.
64 ///
65 /// # Safety
66 ///
67 /// For the user of this trait, the resulting slice returned from this method _must not_ be
68 /// used to de-initialize the vectors by overwriting their contents with
69 /// [`MaybeUninit::uninit`] if they were already initialized.
70 ///
71 /// [`as_maybe_uninit_slice`]: InitializeVectored::as_maybe_uninit_slice
72 unsafe fn as_maybe_uninit_vectors_mut(&mut self) -> &mut [Self::UninitVector];
73}
74pub trait InitializeExt: private2::Sealed + Initialize + Sized {
75 /// Assume that the type is already initialized. This is equivalent of calling
76 /// [`AssertInit::new_unchecked`].
77 ///
78 /// # Safety
79 ///
80 /// The initialization invariant must be upheld for this to be safe.
81 unsafe fn assume_init(self) -> AssertInit<Self> {
82 AssertInit::new_unchecked(self)
83 }
84}
85mod private2 {
86 pub trait Sealed {}
87}
88mod private3 {
89 pub trait Sealed {}
90}
91mod private4 {
92 pub trait Sealed {}
93}
94mod private5 {
95 pub trait Sealed {}
96}
97
98impl<T> private2::Sealed for T where T: Initialize {}
99impl<T> InitializeExt for T where T: Initialize {}
100
101unsafe impl<'a, T> Initialize for &'a mut [MaybeUninit<T>] {
102 type Item = T;
103
104 #[inline]
105 fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>] {
106 self
107 }
108 #[inline]
109 unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
110 self
111 }
112}
113impl<'a, T> From<AssertInit<&'a mut [MaybeUninit<T>]>> for &'a mut [T] {
114 #[inline]
115 fn from(init_slice: AssertInit<&'a mut [MaybeUninit<T>]>) -> &'a mut [T] {
116 unsafe { crate::cast_uninit_to_init_slice_mut(init_slice.into_inner()) }
117 }
118}
119/*unsafe impl<T> InitializeVectored for T
120where
121 T: Initialize,
122{
123 type UninitVector = Self;
124
125 #[inline]
126 fn as_maybe_uninit_vectors(&self) -> &[Self::UninitVector] {
127 core::slice::from_ref(self)
128 }
129 #[inline]
130 unsafe fn as_maybe_uninit_vectors_mut(&mut self) -> &mut [Self::UninitVector] {
131 core::slice::from_mut(self)
132 }
133}*/
134unsafe impl<'a, 'b, T> InitializeVectored for &'a mut [&'b mut [MaybeUninit<T>]] {
135 type UninitVector = &'b mut [MaybeUninit<T>];
136
137 fn as_maybe_uninit_vectors(&self) -> &[Self::UninitVector] {
138 self
139 }
140 unsafe fn as_maybe_uninit_vectors_mut(&mut self) -> &mut [Self::UninitVector] {
141 self
142 }
143}
144#[cfg(feature = "alloc")]
145unsafe impl<T> Initialize for Box<[MaybeUninit<T>]> {
146 type Item = T;
147
148 #[inline]
149 fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>] {
150 self
151 }
152 #[inline]
153 unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
154 self
155 }
156}
157#[cfg(feature = "alloc")]
158impl<T> From<AssertInit<Box<[MaybeUninit<T>]>>> for Box<[T]> {
159 #[inline]
160 fn from(init_box: AssertInit<Box<[MaybeUninit<T>]>>) -> Box<[T]> {
161 #[cfg(feature = "nightly")]
162 unsafe {
163 #[forbid(unconditional_recursion)]
164 Box::<[MaybeUninit<T>]>::assume_init(init_box.into_inner())
165 }
166 #[cfg(not(feature = "nightly"))]
167 unsafe {
168 let slice_ptr = Box::into_raw(init_box.into_inner());
169 Box::from_raw(crate::cast_uninit_to_init_slice_mut(&mut *slice_ptr))
170 }
171 }
172}
173/*
174#[cfg(feature = "alloc")]
175unsafe impl Initialize for Vec<Item> {
176 #[inline]
177 fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<u8>] {
178 crate::cast_init_to_uninit_slice(&*self)
179 }
180 #[inline]
181 unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<u8>] {
182 // TODO: Give the whole allocation, and not just the length set? With MaybeUninit, calling
183 // set_len is safe.
184 crate::cast_init_to_uninit_slice_mut(&mut *self)
185 }
186}
187#[cfg(feature = "alloc")]
188unsafe impl Initialize for Vec<MaybeUninit<u8>> {
189 #[inline]
190 fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<u8>] {
191 &*self
192 }
193 #[inline]
194 unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<u8>] {
195 &mut *self
196 }
197}*/
198#[cfg(feature = "alloc")]
199impl<T> From<AssertInit<Vec<MaybeUninit<T>>>> for Vec<T> {
200 #[inline]
201 fn from(init_vec: AssertInit<Vec<MaybeUninit<T>>>) -> Vec<T> {
202 unsafe {
203 let mut vec = init_vec.into_inner();
204 //let (ptr, cap, len) = Vec::into_raw_parts(self);
205
206 let (ptr, cap, len) = {
207 let ptr = vec.as_mut_ptr();
208 let cap = vec.capacity();
209 let len = vec.len();
210
211 core::mem::forget(vec);
212
213 (ptr, cap, len)
214 };
215
216 Vec::from_raw_parts(ptr as *mut T, cap, len)
217 }
218 }
219}
220unsafe impl<T, const N: usize> Initialize for [MaybeUninit<T>; N] {
221 type Item = T;
222
223 #[inline]
224 fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>] {
225 self
226 }
227 #[inline]
228 unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
229 self
230 }
231}
232impl<T, const N: usize> From<AssertInit<[MaybeUninit<T>; N]>> for [T; N] {
233 #[inline]
234 fn from(init: AssertInit<[MaybeUninit<T>; N]>) -> [T; N] {
235 #[cfg(feature = "nightly")]
236 unsafe {
237 MaybeUninit::array_assume_init(init.into_inner())
238 }
239 #[cfg(not(feature = "nightly"))]
240 unsafe {
241 let inner = init.into_inner();
242 let init: [T; N] = core::mem::transmute_copy(&inner);
243 init
244 }
245 }
246}
247
248/// A marker trait for implementations of [`Deref`](core::ops::Deref) that come with the additional
249/// guarantee that:
250///
251/// 1. The [`Deref::deref`] method will always return a slice with the same length, if the
252/// dereference target happens to a slice (`[T]`);
253/// 2. The [`DerefMut::deref_mut`] method, like [`Deref::deref`] will also always return a slice
254/// with the same length, and that it cannot change the length in any way when calling this
255/// trait method;
256/// 3. The target slice must always point to the same memory, although the address is allowed to
257/// change. In other words, any modifications to the target type, must be visible when calling
258/// the dereference methods again.
259///
260/// This is implemented for most of the familiar types in the standard library, e.g. [`Box`],
261/// [`Vec`], [`Ref`], etc.
262///
263/// This comes with some exceptions: for example do note that this only affects the [`Deref`] and
264/// [`DerefMut`] trait methods. There can still be ways to modify the length of the slice, either
265/// via interior mutability or via mutable references, accessible to safe code, so long as this
266/// is not in the dereference traits.
267///
268/// The aim of this trait is to force that when using whatever slice a [`BufferInitializer`] backs,
269/// it can be confident that the initializedness counter it stores will always be equal to the
270/// total length when the initializer is full. A [`Deref`] implementation that lacks the guarantee
271/// of this trait, would cause Undefined Behavior in the very building blocks of this library,
272/// otherwise.
273///
274/// Note that this is also fully orthogonal to `StableDeref`. So long as [`BufferInitializer`] can
275/// make assumptions about the length always being correct, the actual address of the memory is of
276/// no importance. However, implementing `StableDeref` means that invariant 3 is always upheld, but
277/// it is not clear at the moment whether that also applies to invariant 1 and 2.
278pub unsafe trait TrustedDeref: core::ops::Deref {}
279
280// TODO: Respect the allocator type of must liballoc collections, at least under #[cfg(feature =
281// "nightly")].
282
283// SAFETY: Deref for references is always a no-op, and always returns `self`. Unless the caller
284// changes the length of it beforehand, nothing bad will happen.
285unsafe impl<'a, T: ?Sized> TrustedDeref for &'a T {}
286
287// SAFETY: DerefMut for references is always a no-op.
288unsafe impl<'a, T: ?Sized> TrustedDeref for &'a mut T {}
289
290// SAFETY: The resulting slice is determined by the internal `len` field of the vector. The
291// dereference impls will not change this.
292#[cfg(feature = "alloc")]
293unsafe impl<T> TrustedDeref for Vec<T> {}
294
295// SAFETY: Deref and DerefMut are implemented as a raw pointer dereference by Box. No side effects.
296#[cfg(feature = "alloc")]
297unsafe impl<T: ?Sized> TrustedDeref for Box<T> {}
298
299// SAFETY: Arc is not particularly interesting as it cannot implement DerefMut, but it still
300// upholds the guarantee for Deref.
301#[cfg(feature = "alloc")]
302unsafe impl<T: ?Sized> TrustedDeref for Arc<T> {}
303
304// SAFETY: Same goes for Rc.
305#[cfg(feature = "alloc")]
306unsafe impl<T: ?Sized> TrustedDeref for Rc<T> {}
307
308// SAFETY: While RefCell allows inner types to utilize interior mutability, the actual RAII guard
309// will not do anything wrong.
310unsafe impl<'a, T: ?Sized> TrustedDeref for core::cell::Ref<'a, T> {}
311
312// SAFETY: Same goes for RefMut.
313unsafe impl<'a, T: ?Sized> TrustedDeref for core::cell::RefMut<'a, T> {}
314
315// SAFETY: Same goes for all lock guards.
316#[cfg(feature = "std")]
317unsafe impl<'a, T: ?Sized> TrustedDeref for std::sync::MutexGuard<'a, T> {}
318
319#[cfg(feature = "std")]
320unsafe impl<'a, T: ?Sized> TrustedDeref for std::sync::RwLockReadGuard<'a, T> {}
321
322#[cfg(feature = "std")]
323unsafe impl<'a, T: ?Sized> TrustedDeref for std::sync::RwLockWriteGuard<'a, T> {}
324
325#[cfg(feature = "alloc")]
326unsafe impl TrustedDeref for String {}
327
328// TODO: These are correct, right? Explain why.
329#[cfg(feature = "std")]
330unsafe impl TrustedDeref for std::ffi::CString {}
331#[cfg(feature = "std")]
332unsafe impl TrustedDeref for std::ffi::OsString {}
333#[cfg(feature = "std")]
334unsafe impl TrustedDeref for std::path::PathBuf {}
335
336// SAFETY: As Pin is merely a thin wrapper that in a way works like StableDeref, it will not have
337// any side effects.
338unsafe impl<T: core::ops::Deref> TrustedDeref for core::pin::Pin<T> {}
339
340// SAFETY: While Cow is allowed to change its Deref address, as it will copy when made mutable, its
341// Deref impl will only match the enum and propagate the dereference.
342#[cfg(feature = "alloc")]
343unsafe impl<'a, T: alloc::borrow::ToOwned> TrustedDeref for alloc::borrow::Cow<'a, T> {}
344
345// TODO: binary_heap PeekMut, Lazy, VaList, ManuallyDrop, AssertUnwindSafe, SyncLazy, std ioslices.
346
347/// A marker trait which indicates that two different implementations of [`Initialize`] have the
348/// same memory layout, and behave equivalently with respect to their implementations of
349/// [`Initialize`] and [`AssertInit`].
350///
351/// A usecase for this, is e.g. if you need [`InitializeVectored`]`<Item = IoSliceMut>` for system
352/// call ABI reasons, but you have a different type which still has the same layout, e.g.
353/// [`SingleVector`](crate::wrappers::SingleVector)`<`[`AsUninit`](crate::wrappers::AsUninit)`<IoSliceMut>>`.
354/// In general, it also allows changing the inner T, while still tracking the initializedness
355/// properly. For single-buffer I/O, this allows converting between any [`Equivalent`] types, where
356/// for vectored I/O, it allows a more restricted type of conversion, where they also need to be
357/// slice-castable.
358pub unsafe trait Equivalent<T>
359where
360 T: Initialize,
361 Self: Initialize<Item = <T as Initialize>::Item>,
362{
363}