core/mem/
maybe_uninit.rs

1use crate::any::type_name;
2use crate::mem::ManuallyDrop;
3use crate::{fmt, intrinsics, ptr, slice};
4
5/// A wrapper type to construct uninitialized instances of `T`.
6///
7/// # Initialization invariant
8///
9/// The compiler, in general, assumes that a variable is properly initialized
10/// according to the requirements of the variable's type. For example, a variable of
11/// reference type must be aligned and non-null. This is an invariant that must
12/// *always* be upheld, even in unsafe code. As a consequence, zero-initializing a
13/// variable of reference type causes instantaneous [undefined behavior][ub],
14/// no matter whether that reference ever gets used to access memory:
15///
16/// ```rust,no_run
17/// # #![allow(invalid_value)]
18/// use std::mem::{self, MaybeUninit};
19///
20/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! ⚠️
21/// // The equivalent code with `MaybeUninit<&i32>`:
22/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior! ⚠️
23/// ```
24///
25/// This is exploited by the compiler for various optimizations, such as eliding
26/// run-time checks and optimizing `enum` layout.
27///
28/// Similarly, entirely uninitialized memory may have any content, while a `bool` must
29/// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
30///
31/// ```rust,no_run
32/// # #![allow(invalid_value)]
33/// use std::mem::{self, MaybeUninit};
34///
35/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! ⚠️
36/// // The equivalent code with `MaybeUninit<bool>`:
37/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
38/// ```
39///
40/// Moreover, uninitialized memory is special in that it does not have a fixed value ("fixed"
41/// meaning "it won't change without being written to"). Reading the same uninitialized byte
42/// multiple times can give different results. This makes it undefined behavior to have
43/// uninitialized data in a variable even if that variable has an integer type, which otherwise can
44/// hold any *fixed* bit pattern:
45///
46/// ```rust,no_run
47/// # #![allow(invalid_value)]
48/// use std::mem::{self, MaybeUninit};
49///
50/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! ⚠️
51/// // The equivalent code with `MaybeUninit<i32>`:
52/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
53/// ```
54/// On top of that, remember that most types have additional invariants beyond merely
55/// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
56/// is considered initialized (under the current implementation; this does not constitute
57/// a stable guarantee) because the only requirement the compiler knows about it
58/// is that the data pointer must be non-null. Creating such a `Vec<T>` does not cause
59/// *immediate* undefined behavior, but will cause undefined behavior with most
60/// safe operations (including dropping it).
61///
62/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
63///
64/// # Examples
65///
66/// `MaybeUninit<T>` serves to enable unsafe code to deal with uninitialized data.
67/// It is a signal to the compiler indicating that the data here might *not*
68/// be initialized:
69///
70/// ```rust
71/// use std::mem::MaybeUninit;
72///
73/// // Create an explicitly uninitialized reference. The compiler knows that data inside
74/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
75/// let mut x = MaybeUninit::<&i32>::uninit();
76/// // Set it to a valid value.
77/// x.write(&0);
78/// // Extract the initialized data -- this is only allowed *after* properly
79/// // initializing `x`!
80/// let x = unsafe { x.assume_init() };
81/// ```
82///
83/// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
84///
85/// You can think of `MaybeUninit<T>` as being a bit like `Option<T>` but without
86/// any of the run-time tracking and without any of the safety checks.
87///
88/// ## out-pointers
89///
90/// You can use `MaybeUninit<T>` to implement "out-pointers": instead of returning data
91/// from a function, pass it a pointer to some (uninitialized) memory to put the
92/// result into. This can be useful when it is important for the caller to control
93/// how the memory the result is stored in gets allocated, and you want to avoid
94/// unnecessary moves.
95///
96/// ```
97/// use std::mem::MaybeUninit;
98///
99/// unsafe fn make_vec(out: *mut Vec<i32>) {
100///     // `write` does not drop the old contents, which is important.
101///     unsafe { out.write(vec![1, 2, 3]); }
102/// }
103///
104/// let mut v = MaybeUninit::uninit();
105/// unsafe { make_vec(v.as_mut_ptr()); }
106/// // Now we know `v` is initialized! This also makes sure the vector gets
107/// // properly dropped.
108/// let v = unsafe { v.assume_init() };
109/// assert_eq!(&v, &[1, 2, 3]);
110/// ```
111///
112/// ## Initializing an array element-by-element
113///
114/// `MaybeUninit<T>` can be used to initialize a large array element-by-element:
115///
116/// ```
117/// use std::mem::{self, MaybeUninit};
118///
119/// let data = {
120///     // Create an uninitialized array of `MaybeUninit`.
121///     let mut data: [MaybeUninit<Vec<u32>>; 1000] = [const { MaybeUninit::uninit() }; 1000];
122///
123///     // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
124///     // we have a memory leak, but there is no memory safety issue.
125///     for elem in &mut data[..] {
126///         elem.write(vec![42]);
127///     }
128///
129///     // Everything is initialized. Transmute the array to the
130///     // initialized type.
131///     unsafe { mem::transmute::<_, [Vec<u32>; 1000]>(data) }
132/// };
133///
134/// assert_eq!(&data[0], &[42]);
135/// ```
136///
137/// You can also work with partially initialized arrays, which could
138/// be found in low-level datastructures.
139///
140/// ```
141/// use std::mem::MaybeUninit;
142///
143/// // Create an uninitialized array of `MaybeUninit`.
144/// let mut data: [MaybeUninit<String>; 1000] = [const { MaybeUninit::uninit() }; 1000];
145/// // Count the number of elements we have assigned.
146/// let mut data_len: usize = 0;
147///
148/// for elem in &mut data[0..500] {
149///     elem.write(String::from("hello"));
150///     data_len += 1;
151/// }
152///
153/// // For each item in the array, drop if we allocated it.
154/// for elem in &mut data[0..data_len] {
155///     unsafe { elem.assume_init_drop(); }
156/// }
157/// ```
158///
159/// ## Initializing a struct field-by-field
160///
161/// You can use `MaybeUninit<T>`, and the [`std::ptr::addr_of_mut`] macro, to initialize structs field by field:
162///
163/// ```rust
164/// use std::mem::MaybeUninit;
165/// use std::ptr::addr_of_mut;
166///
167/// #[derive(Debug, PartialEq)]
168/// pub struct Foo {
169///     name: String,
170///     list: Vec<u8>,
171/// }
172///
173/// let foo = {
174///     let mut uninit: MaybeUninit<Foo> = MaybeUninit::uninit();
175///     let ptr = uninit.as_mut_ptr();
176///
177///     // Initializing the `name` field
178///     // Using `write` instead of assignment via `=` to not call `drop` on the
179///     // old, uninitialized value.
180///     unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); }
181///
182///     // Initializing the `list` field
183///     // If there is a panic here, then the `String` in the `name` field leaks.
184///     unsafe { addr_of_mut!((*ptr).list).write(vec![0, 1, 2]); }
185///
186///     // All the fields are initialized, so we call `assume_init` to get an initialized Foo.
187///     unsafe { uninit.assume_init() }
188/// };
189///
190/// assert_eq!(
191///     foo,
192///     Foo {
193///         name: "Bob".to_string(),
194///         list: vec![0, 1, 2]
195///     }
196/// );
197/// ```
198/// [`std::ptr::addr_of_mut`]: crate::ptr::addr_of_mut
199/// [ub]: ../../reference/behavior-considered-undefined.html
200///
201/// # Layout
202///
203/// `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as `T`:
204///
205/// ```rust
206/// use std::mem::MaybeUninit;
207/// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
208/// assert_eq!(align_of::<MaybeUninit<u64>>(), align_of::<u64>());
209/// ```
210///
211/// However remember that a type *containing* a `MaybeUninit<T>` is not necessarily the same
212/// layout; Rust does not in general guarantee that the fields of a `Foo<T>` have the same order as
213/// a `Foo<U>` even if `T` and `U` have the same size and alignment. Furthermore because any bit
214/// value is valid for a `MaybeUninit<T>` the compiler can't apply non-zero/niche-filling
215/// optimizations, potentially resulting in a larger size:
216///
217/// ```rust
218/// # use std::mem::MaybeUninit;
219/// assert_eq!(size_of::<Option<bool>>(), 1);
220/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
221/// ```
222///
223/// If `T` is FFI-safe, then so is `MaybeUninit<T>`.
224///
225/// While `MaybeUninit` is `#[repr(transparent)]` (indicating it guarantees the same size,
226/// alignment, and ABI as `T`), this does *not* change any of the previous caveats. `Option<T>` and
227/// `Option<MaybeUninit<T>>` may still have different sizes, and types containing a field of type
228/// `T` may be laid out (and sized) differently than if that field were `MaybeUninit<T>`.
229/// `MaybeUninit` is a union type, and `#[repr(transparent)]` on unions is unstable (see [the
230/// tracking issue](https://github.com/rust-lang/rust/issues/60405)). Over time, the exact
231/// guarantees of `#[repr(transparent)]` on unions may evolve, and `MaybeUninit` may or may not
232/// remain `#[repr(transparent)]`. That said, `MaybeUninit<T>` will *always* guarantee that it has
233/// the same size, alignment, and ABI as `T`; it's just that the way `MaybeUninit` implements that
234/// guarantee may evolve.
235///
236/// Note that even though `T` and `MaybeUninit<T>` are ABI compatible it is still unsound to
237/// transmute `&mut T` to `&mut MaybeUninit<T>` and expose that to safe code because it would allow
238/// safe code to access uninitialized memory:
239///
240/// ```rust,no_run
241/// use core::mem::MaybeUninit;
242///
243/// fn unsound_transmute<T>(val: &mut T) -> &mut MaybeUninit<T> {
244///     unsafe { core::mem::transmute(val) }
245/// }
246///
247/// fn main() {
248///     let mut code = 0;
249///     let code = &mut code;
250///     let code2 = unsound_transmute(code);
251///     *code2 = MaybeUninit::uninit();
252///     std::process::exit(*code); // UB! Accessing uninitialized memory.
253/// }
254/// ```
255#[stable(feature = "maybe_uninit", since = "1.36.0")]
256// Lang item so we can wrap other types in it. This is useful for coroutines.
257#[lang = "maybe_uninit"]
258#[derive(Copy)]
259#[repr(transparent)]
260#[rustc_pub_transparent]
261pub union MaybeUninit<T> {
262    uninit: (),
263    value: ManuallyDrop<T>,
264}
265
266#[stable(feature = "maybe_uninit", since = "1.36.0")]
267impl<T: Copy> Clone for MaybeUninit<T> {
268    #[inline(always)]
269    fn clone(&self) -> Self {
270        // Not calling `T::clone()`, we cannot know if we are initialized enough for that.
271        *self
272    }
273}
274
275#[stable(feature = "maybe_uninit_debug", since = "1.41.0")]
276impl<T> fmt::Debug for MaybeUninit<T> {
277    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
278        // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("MaybeUninit<{..}>").
279        let full_name = type_name::<Self>();
280        let prefix_len = full_name.find("MaybeUninit").unwrap();
281        f.pad(&full_name[prefix_len..])
282    }
283}
284
285impl<T> MaybeUninit<T> {
286    /// Creates a new `MaybeUninit<T>` initialized with the given value.
287    /// It is safe to call [`assume_init`] on the return value of this function.
288    ///
289    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
290    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
291    ///
292    /// # Example
293    ///
294    /// ```
295    /// use std::mem::MaybeUninit;
296    ///
297    /// let v: MaybeUninit<Vec<u8>> = MaybeUninit::new(vec![42]);
298    /// # // Prevent leaks for Miri
299    /// # unsafe { let _ = MaybeUninit::assume_init(v); }
300    /// ```
301    ///
302    /// [`assume_init`]: MaybeUninit::assume_init
303    #[stable(feature = "maybe_uninit", since = "1.36.0")]
304    #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")]
305    #[must_use = "use `forget` to avoid running Drop code"]
306    #[inline(always)]
307    pub const fn new(val: T) -> MaybeUninit<T> {
308        MaybeUninit { value: ManuallyDrop::new(val) }
309    }
310
311    /// Creates a new `MaybeUninit<T>` in an uninitialized state.
312    ///
313    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
314    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
315    ///
316    /// See the [type-level documentation][MaybeUninit] for some examples.
317    ///
318    /// # Example
319    ///
320    /// ```
321    /// use std::mem::MaybeUninit;
322    ///
323    /// let v: MaybeUninit<String> = MaybeUninit::uninit();
324    /// ```
325    #[stable(feature = "maybe_uninit", since = "1.36.0")]
326    #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")]
327    #[must_use]
328    #[inline(always)]
329    #[rustc_diagnostic_item = "maybe_uninit_uninit"]
330    pub const fn uninit() -> MaybeUninit<T> {
331        MaybeUninit { uninit: () }
332    }
333
334    /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
335    /// filled with `0` bytes. It depends on `T` whether that already makes for
336    /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
337    /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
338    /// be null.
339    ///
340    /// Note that if `T` has padding bytes, those bytes are *not* preserved when the
341    /// `MaybeUninit<T>` value is returned from this function, so those bytes will *not* be zeroed.
342    ///
343    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
344    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
345    ///
346    /// # Example
347    ///
348    /// Correct usage of this function: initializing a struct with zero, where all
349    /// fields of the struct can hold the bit-pattern 0 as a valid value.
350    ///
351    /// ```rust
352    /// use std::mem::MaybeUninit;
353    ///
354    /// let x = MaybeUninit::<(u8, bool)>::zeroed();
355    /// let x = unsafe { x.assume_init() };
356    /// assert_eq!(x, (0, false));
357    /// ```
358    ///
359    /// This can be used in const contexts, such as to indicate the end of static arrays for
360    /// plugin registration.
361    ///
362    /// *Incorrect* usage of this function: calling `x.zeroed().assume_init()`
363    /// when `0` is not a valid bit-pattern for the type:
364    ///
365    /// ```rust,no_run
366    /// use std::mem::MaybeUninit;
367    ///
368    /// enum NotZero { One = 1, Two = 2 }
369    ///
370    /// let x = MaybeUninit::<(u8, NotZero)>::zeroed();
371    /// let x = unsafe { x.assume_init() };
372    /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
373    /// // This is undefined behavior. ⚠️
374    /// ```
375    #[inline]
376    #[must_use]
377    #[rustc_diagnostic_item = "maybe_uninit_zeroed"]
378    #[stable(feature = "maybe_uninit", since = "1.36.0")]
379    #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")]
380    pub const fn zeroed() -> MaybeUninit<T> {
381        let mut u = MaybeUninit::<T>::uninit();
382        // SAFETY: `u.as_mut_ptr()` points to allocated memory.
383        unsafe { u.as_mut_ptr().write_bytes(0u8, 1) };
384        u
385    }
386
387    /// Sets the value of the `MaybeUninit<T>`.
388    ///
389    /// This overwrites any previous value without dropping it, so be careful
390    /// not to use this twice unless you want to skip running the destructor.
391    /// For your convenience, this also returns a mutable reference to the
392    /// (now safely initialized) contents of `self`.
393    ///
394    /// As the content is stored inside a `MaybeUninit`, the destructor is not
395    /// run for the inner data if the MaybeUninit leaves scope without a call to
396    /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
397    /// the mutable reference returned by this function needs to keep this in
398    /// mind. The safety model of Rust regards leaks as safe, but they are
399    /// usually still undesirable. This being said, the mutable reference
400    /// behaves like any other mutable reference would, so assigning a new value
401    /// to it will drop the old content.
402    ///
403    /// [`assume_init`]: Self::assume_init
404    /// [`assume_init_drop`]: Self::assume_init_drop
405    ///
406    /// # Examples
407    ///
408    /// Correct usage of this method:
409    ///
410    /// ```rust
411    /// use std::mem::MaybeUninit;
412    ///
413    /// let mut x = MaybeUninit::<Vec<u8>>::uninit();
414    ///
415    /// {
416    ///     let hello = x.write((&b"Hello, world!").to_vec());
417    ///     // Setting hello does not leak prior allocations, but drops them
418    ///     *hello = (&b"Hello").to_vec();
419    ///     hello[0] = 'h' as u8;
420    /// }
421    /// // x is initialized now:
422    /// let s = unsafe { x.assume_init() };
423    /// assert_eq!(b"hello", s.as_slice());
424    /// ```
425    ///
426    /// This usage of the method causes a leak:
427    ///
428    /// ```rust
429    /// use std::mem::MaybeUninit;
430    ///
431    /// let mut x = MaybeUninit::<String>::uninit();
432    ///
433    /// x.write("Hello".to_string());
434    /// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
435    /// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
436    /// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
437    /// // This leaks the contained string:
438    /// x.write("hello".to_string());
439    /// // x is initialized now:
440    /// let s = unsafe { x.assume_init() };
441    /// ```
442    ///
443    /// This method can be used to avoid unsafe in some cases. The example below
444    /// shows a part of an implementation of a fixed sized arena that lends out
445    /// pinned references.
446    /// With `write`, we can avoid the need to write through a raw pointer:
447    ///
448    /// ```rust
449    /// use core::pin::Pin;
450    /// use core::mem::MaybeUninit;
451    ///
452    /// struct PinArena<T> {
453    ///     memory: Box<[MaybeUninit<T>]>,
454    ///     len: usize,
455    /// }
456    ///
457    /// impl <T> PinArena<T> {
458    ///     pub fn capacity(&self) -> usize {
459    ///         self.memory.len()
460    ///     }
461    ///     pub fn push(&mut self, val: T) -> Pin<&mut T> {
462    ///         if self.len >= self.capacity() {
463    ///             panic!("Attempted to push to a full pin arena!");
464    ///         }
465    ///         let ref_ = self.memory[self.len].write(val);
466    ///         self.len += 1;
467    ///         unsafe { Pin::new_unchecked(ref_) }
468    ///     }
469    /// }
470    /// ```
471    #[inline(always)]
472    #[stable(feature = "maybe_uninit_write", since = "1.55.0")]
473    #[rustc_const_stable(feature = "const_maybe_uninit_write", since = "1.85.0")]
474    pub const fn write(&mut self, val: T) -> &mut T {
475        *self = MaybeUninit::new(val);
476        // SAFETY: We just initialized this value.
477        unsafe { self.assume_init_mut() }
478    }
479
480    /// Gets a pointer to the contained value. Reading from this pointer or turning it
481    /// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
482    /// Writing to memory that this pointer (non-transitively) points to is undefined behavior
483    /// (except inside an `UnsafeCell<T>`).
484    ///
485    /// # Examples
486    ///
487    /// Correct usage of this method:
488    ///
489    /// ```rust
490    /// use std::mem::MaybeUninit;
491    ///
492    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
493    /// x.write(vec![0, 1, 2]);
494    /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
495    /// let x_vec = unsafe { &*x.as_ptr() };
496    /// assert_eq!(x_vec.len(), 3);
497    /// # // Prevent leaks for Miri
498    /// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
499    /// ```
500    ///
501    /// *Incorrect* usage of this method:
502    ///
503    /// ```rust,no_run
504    /// use std::mem::MaybeUninit;
505    ///
506    /// let x = MaybeUninit::<Vec<u32>>::uninit();
507    /// let x_vec = unsafe { &*x.as_ptr() };
508    /// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
509    /// ```
510    ///
511    /// (Notice that the rules around references to uninitialized data are not finalized yet, but
512    /// until they are, it is advisable to avoid them.)
513    #[stable(feature = "maybe_uninit", since = "1.36.0")]
514    #[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")]
515    #[rustc_as_ptr]
516    #[inline(always)]
517    pub const fn as_ptr(&self) -> *const T {
518        // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
519        self as *const _ as *const T
520    }
521
522    /// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
523    /// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
524    ///
525    /// # Examples
526    ///
527    /// Correct usage of this method:
528    ///
529    /// ```rust
530    /// use std::mem::MaybeUninit;
531    ///
532    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
533    /// x.write(vec![0, 1, 2]);
534    /// // Create a reference into the `MaybeUninit<Vec<u32>>`.
535    /// // This is okay because we initialized it.
536    /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
537    /// x_vec.push(3);
538    /// assert_eq!(x_vec.len(), 4);
539    /// # // Prevent leaks for Miri
540    /// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
541    /// ```
542    ///
543    /// *Incorrect* usage of this method:
544    ///
545    /// ```rust,no_run
546    /// use std::mem::MaybeUninit;
547    ///
548    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
549    /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
550    /// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
551    /// ```
552    ///
553    /// (Notice that the rules around references to uninitialized data are not finalized yet, but
554    /// until they are, it is advisable to avoid them.)
555    #[stable(feature = "maybe_uninit", since = "1.36.0")]
556    #[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")]
557    #[rustc_as_ptr]
558    #[inline(always)]
559    pub const fn as_mut_ptr(&mut self) -> *mut T {
560        // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
561        self as *mut _ as *mut T
562    }
563
564    /// Extracts the value from the `MaybeUninit<T>` container. This is a great way
565    /// to ensure that the data will get dropped, because the resulting `T` is
566    /// subject to the usual drop handling.
567    ///
568    /// # Safety
569    ///
570    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
571    /// state. Calling this when the content is not yet fully initialized causes immediate undefined
572    /// behavior. The [type-level documentation][inv] contains more information about
573    /// this initialization invariant.
574    ///
575    /// [inv]: #initialization-invariant
576    ///
577    /// On top of that, remember that most types have additional invariants beyond merely
578    /// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
579    /// is considered initialized (under the current implementation; this does not constitute
580    /// a stable guarantee) because the only requirement the compiler knows about it
581    /// is that the data pointer must be non-null. Creating such a `Vec<T>` does not cause
582    /// *immediate* undefined behavior, but will cause undefined behavior with most
583    /// safe operations (including dropping it).
584    ///
585    /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
586    ///
587    /// # Examples
588    ///
589    /// Correct usage of this method:
590    ///
591    /// ```rust
592    /// use std::mem::MaybeUninit;
593    ///
594    /// let mut x = MaybeUninit::<bool>::uninit();
595    /// x.write(true);
596    /// let x_init = unsafe { x.assume_init() };
597    /// assert_eq!(x_init, true);
598    /// ```
599    ///
600    /// *Incorrect* usage of this method:
601    ///
602    /// ```rust,no_run
603    /// use std::mem::MaybeUninit;
604    ///
605    /// let x = MaybeUninit::<Vec<u32>>::uninit();
606    /// let x_init = unsafe { x.assume_init() };
607    /// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
608    /// ```
609    #[stable(feature = "maybe_uninit", since = "1.36.0")]
610    #[rustc_const_stable(feature = "const_maybe_uninit_assume_init_by_value", since = "1.59.0")]
611    #[inline(always)]
612    #[rustc_diagnostic_item = "assume_init"]
613    #[track_caller]
614    pub const unsafe fn assume_init(self) -> T {
615        // SAFETY: the caller must guarantee that `self` is initialized.
616        // This also means that `self` must be a `value` variant.
617        unsafe {
618            intrinsics::assert_inhabited::<T>();
619            ManuallyDrop::into_inner(self.value)
620        }
621    }
622
623    /// Reads the value from the `MaybeUninit<T>` container. The resulting `T` is subject
624    /// to the usual drop handling.
625    ///
626    /// Whenever possible, it is preferable to use [`assume_init`] instead, which
627    /// prevents duplicating the content of the `MaybeUninit<T>`.
628    ///
629    /// # Safety
630    ///
631    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
632    /// state. Calling this when the content is not yet fully initialized causes undefined
633    /// behavior. The [type-level documentation][inv] contains more information about
634    /// this initialization invariant.
635    ///
636    /// Moreover, similar to the [`ptr::read`] function, this function creates a
637    /// bitwise copy of the contents, regardless whether the contained type
638    /// implements the [`Copy`] trait or not. When using multiple copies of the
639    /// data (by calling `assume_init_read` multiple times, or first calling
640    /// `assume_init_read` and then [`assume_init`]), it is your responsibility
641    /// to ensure that data may indeed be duplicated.
642    ///
643    /// [inv]: #initialization-invariant
644    /// [`assume_init`]: MaybeUninit::assume_init
645    ///
646    /// # Examples
647    ///
648    /// Correct usage of this method:
649    ///
650    /// ```rust
651    /// use std::mem::MaybeUninit;
652    ///
653    /// let mut x = MaybeUninit::<u32>::uninit();
654    /// x.write(13);
655    /// let x1 = unsafe { x.assume_init_read() };
656    /// // `u32` is `Copy`, so we may read multiple times.
657    /// let x2 = unsafe { x.assume_init_read() };
658    /// assert_eq!(x1, x2);
659    ///
660    /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
661    /// x.write(None);
662    /// let x1 = unsafe { x.assume_init_read() };
663    /// // Duplicating a `None` value is okay, so we may read multiple times.
664    /// let x2 = unsafe { x.assume_init_read() };
665    /// assert_eq!(x1, x2);
666    /// ```
667    ///
668    /// *Incorrect* usage of this method:
669    ///
670    /// ```rust,no_run
671    /// use std::mem::MaybeUninit;
672    ///
673    /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
674    /// x.write(Some(vec![0, 1, 2]));
675    /// let x1 = unsafe { x.assume_init_read() };
676    /// let x2 = unsafe { x.assume_init_read() };
677    /// // We now created two copies of the same vector, leading to a double-free ⚠️ when
678    /// // they both get dropped!
679    /// ```
680    #[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
681    #[rustc_const_stable(feature = "const_maybe_uninit_assume_init_read", since = "1.75.0")]
682    #[inline(always)]
683    #[track_caller]
684    pub const unsafe fn assume_init_read(&self) -> T {
685        // SAFETY: the caller must guarantee that `self` is initialized.
686        // Reading from `self.as_ptr()` is safe since `self` should be initialized.
687        unsafe {
688            intrinsics::assert_inhabited::<T>();
689            self.as_ptr().read()
690        }
691    }
692
693    /// Drops the contained value in place.
694    ///
695    /// If you have ownership of the `MaybeUninit`, you can also use
696    /// [`assume_init`] as an alternative.
697    ///
698    /// # Safety
699    ///
700    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is
701    /// in an initialized state. Calling this when the content is not yet fully
702    /// initialized causes undefined behavior.
703    ///
704    /// On top of that, all additional invariants of the type `T` must be
705    /// satisfied, as the `Drop` implementation of `T` (or its members) may
706    /// rely on this. For example, setting a `Vec<T>` to an invalid but
707    /// non-null address makes it initialized (under the current implementation;
708    /// this does not constitute a stable guarantee), because the only
709    /// requirement the compiler knows about it is that the data pointer must be
710    /// non-null. Dropping such a `Vec<T>` however will cause undefined
711    /// behavior.
712    ///
713    /// [`assume_init`]: MaybeUninit::assume_init
714    #[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
715    pub unsafe fn assume_init_drop(&mut self) {
716        // SAFETY: the caller must guarantee that `self` is initialized and
717        // satisfies all invariants of `T`.
718        // Dropping the value in place is safe if that is the case.
719        unsafe { ptr::drop_in_place(self.as_mut_ptr()) }
720    }
721
722    /// Gets a shared reference to the contained value.
723    ///
724    /// This can be useful when we want to access a `MaybeUninit` that has been
725    /// initialized but don't have ownership of the `MaybeUninit` (preventing the use
726    /// of `.assume_init()`).
727    ///
728    /// # Safety
729    ///
730    /// Calling this when the content is not yet fully initialized causes undefined
731    /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
732    /// is in an initialized state.
733    ///
734    /// # Examples
735    ///
736    /// ### Correct usage of this method:
737    ///
738    /// ```rust
739    /// use std::mem::MaybeUninit;
740    ///
741    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
742    /// # let mut x_mu = x;
743    /// # let mut x = &mut x_mu;
744    /// // Initialize `x`:
745    /// x.write(vec![1, 2, 3]);
746    /// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
747    /// // create a shared reference to it:
748    /// let x: &Vec<u32> = unsafe {
749    ///     // SAFETY: `x` has been initialized.
750    ///     x.assume_init_ref()
751    /// };
752    /// assert_eq!(x, &vec![1, 2, 3]);
753    /// # // Prevent leaks for Miri
754    /// # unsafe { MaybeUninit::assume_init_drop(&mut x_mu); }
755    /// ```
756    ///
757    /// ### *Incorrect* usages of this method:
758    ///
759    /// ```rust,no_run
760    /// use std::mem::MaybeUninit;
761    ///
762    /// let x = MaybeUninit::<Vec<u32>>::uninit();
763    /// let x_vec: &Vec<u32> = unsafe { x.assume_init_ref() };
764    /// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
765    /// ```
766    ///
767    /// ```rust,no_run
768    /// use std::{cell::Cell, mem::MaybeUninit};
769    ///
770    /// let b = MaybeUninit::<Cell<bool>>::uninit();
771    /// // Initialize the `MaybeUninit` using `Cell::set`:
772    /// unsafe {
773    ///     b.assume_init_ref().set(true);
774    ///    // ^^^^^^^^^^^^^^^
775    ///    // Reference to an uninitialized `Cell<bool>`: UB!
776    /// }
777    /// ```
778    #[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
779    #[rustc_const_stable(feature = "const_maybe_uninit_assume_init_ref", since = "1.59.0")]
780    #[inline(always)]
781    pub const unsafe fn assume_init_ref(&self) -> &T {
782        // SAFETY: the caller must guarantee that `self` is initialized.
783        // This also means that `self` must be a `value` variant.
784        unsafe {
785            intrinsics::assert_inhabited::<T>();
786            &*self.as_ptr()
787        }
788    }
789
790    /// Gets a mutable (unique) reference to the contained value.
791    ///
792    /// This can be useful when we want to access a `MaybeUninit` that has been
793    /// initialized but don't have ownership of the `MaybeUninit` (preventing the use
794    /// of `.assume_init()`).
795    ///
796    /// # Safety
797    ///
798    /// Calling this when the content is not yet fully initialized causes undefined
799    /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
800    /// is in an initialized state. For instance, `.assume_init_mut()` cannot be used to
801    /// initialize a `MaybeUninit`.
802    ///
803    /// # Examples
804    ///
805    /// ### Correct usage of this method:
806    ///
807    /// ```rust
808    /// # #![allow(unexpected_cfgs)]
809    /// use std::mem::MaybeUninit;
810    ///
811    /// # unsafe extern "C" fn initialize_buffer(buf: *mut [u8; 1024]) { unsafe { *buf = [0; 1024] } }
812    /// # #[cfg(FALSE)]
813    /// extern "C" {
814    ///     /// Initializes *all* the bytes of the input buffer.
815    ///     fn initialize_buffer(buf: *mut [u8; 1024]);
816    /// }
817    ///
818    /// let mut buf = MaybeUninit::<[u8; 1024]>::uninit();
819    ///
820    /// // Initialize `buf`:
821    /// unsafe { initialize_buffer(buf.as_mut_ptr()); }
822    /// // Now we know that `buf` has been initialized, so we could `.assume_init()` it.
823    /// // However, using `.assume_init()` may trigger a `memcpy` of the 1024 bytes.
824    /// // To assert our buffer has been initialized without copying it, we upgrade
825    /// // the `&mut MaybeUninit<[u8; 1024]>` to a `&mut [u8; 1024]`:
826    /// let buf: &mut [u8; 1024] = unsafe {
827    ///     // SAFETY: `buf` has been initialized.
828    ///     buf.assume_init_mut()
829    /// };
830    ///
831    /// // Now we can use `buf` as a normal slice:
832    /// buf.sort_unstable();
833    /// assert!(
834    ///     buf.windows(2).all(|pair| pair[0] <= pair[1]),
835    ///     "buffer is sorted",
836    /// );
837    /// ```
838    ///
839    /// ### *Incorrect* usages of this method:
840    ///
841    /// You cannot use `.assume_init_mut()` to initialize a value:
842    ///
843    /// ```rust,no_run
844    /// use std::mem::MaybeUninit;
845    ///
846    /// let mut b = MaybeUninit::<bool>::uninit();
847    /// unsafe {
848    ///     *b.assume_init_mut() = true;
849    ///     // We have created a (mutable) reference to an uninitialized `bool`!
850    ///     // This is undefined behavior. ⚠️
851    /// }
852    /// ```
853    ///
854    /// For instance, you cannot [`Read`] into an uninitialized buffer:
855    ///
856    /// [`Read`]: ../../std/io/trait.Read.html
857    ///
858    /// ```rust,no_run
859    /// use std::{io, mem::MaybeUninit};
860    ///
861    /// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
862    /// {
863    ///     let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
864    ///     reader.read_exact(unsafe { buffer.assume_init_mut() })?;
865    ///                             // ^^^^^^^^^^^^^^^^^^^^^^^^
866    ///                             // (mutable) reference to uninitialized memory!
867    ///                             // This is undefined behavior.
868    ///     Ok(unsafe { buffer.assume_init() })
869    /// }
870    /// ```
871    ///
872    /// Nor can you use direct field access to do field-by-field gradual initialization:
873    ///
874    /// ```rust,no_run
875    /// use std::{mem::MaybeUninit, ptr};
876    ///
877    /// struct Foo {
878    ///     a: u32,
879    ///     b: u8,
880    /// }
881    ///
882    /// let foo: Foo = unsafe {
883    ///     let mut foo = MaybeUninit::<Foo>::uninit();
884    ///     ptr::write(&mut foo.assume_init_mut().a as *mut u32, 1337);
885    ///                  // ^^^^^^^^^^^^^^^^^^^^^
886    ///                  // (mutable) reference to uninitialized memory!
887    ///                  // This is undefined behavior.
888    ///     ptr::write(&mut foo.assume_init_mut().b as *mut u8, 42);
889    ///                  // ^^^^^^^^^^^^^^^^^^^^^
890    ///                  // (mutable) reference to uninitialized memory!
891    ///                  // This is undefined behavior.
892    ///     foo.assume_init()
893    /// };
894    /// ```
895    #[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
896    #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.84.0")]
897    #[inline(always)]
898    pub const unsafe fn assume_init_mut(&mut self) -> &mut T {
899        // SAFETY: the caller must guarantee that `self` is initialized.
900        // This also means that `self` must be a `value` variant.
901        unsafe {
902            intrinsics::assert_inhabited::<T>();
903            &mut *self.as_mut_ptr()
904        }
905    }
906
907    /// Extracts the values from an array of `MaybeUninit` containers.
908    ///
909    /// # Safety
910    ///
911    /// It is up to the caller to guarantee that all elements of the array are
912    /// in an initialized state.
913    ///
914    /// # Examples
915    ///
916    /// ```
917    /// #![feature(maybe_uninit_array_assume_init)]
918    /// use std::mem::MaybeUninit;
919    ///
920    /// let mut array: [MaybeUninit<i32>; 3] = [MaybeUninit::uninit(); 3];
921    /// array[0].write(0);
922    /// array[1].write(1);
923    /// array[2].write(2);
924    ///
925    /// // SAFETY: Now safe as we initialised all elements
926    /// let array = unsafe {
927    ///     MaybeUninit::array_assume_init(array)
928    /// };
929    ///
930    /// assert_eq!(array, [0, 1, 2]);
931    /// ```
932    #[unstable(feature = "maybe_uninit_array_assume_init", issue = "96097")]
933    #[inline(always)]
934    #[track_caller]
935    pub const unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] {
936        // SAFETY:
937        // * The caller guarantees that all elements of the array are initialized
938        // * `MaybeUninit<T>` and T are guaranteed to have the same layout
939        // * `MaybeUninit` does not drop, so there are no double-frees
940        // And thus the conversion is safe
941        unsafe {
942            intrinsics::assert_inhabited::<[T; N]>();
943            intrinsics::transmute_unchecked(array)
944        }
945    }
946
947    /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
948    ///
949    /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
950    /// contain padding bytes which are left uninitialized.
951    ///
952    /// # Examples
953    ///
954    /// ```
955    /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
956    /// use std::mem::MaybeUninit;
957    ///
958    /// let val = 0x12345678_i32;
959    /// let uninit = MaybeUninit::new(val);
960    /// let uninit_bytes = uninit.as_bytes();
961    /// let bytes = unsafe { uninit_bytes.assume_init_ref() };
962    /// assert_eq!(bytes, val.to_ne_bytes());
963    /// ```
964    #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
965    pub const fn as_bytes(&self) -> &[MaybeUninit<u8>] {
966        // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
967        unsafe {
968            slice::from_raw_parts(self.as_ptr().cast::<MaybeUninit<u8>>(), super::size_of::<T>())
969        }
970    }
971
972    /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized
973    /// bytes.
974    ///
975    /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
976    /// contain padding bytes which are left uninitialized.
977    ///
978    /// # Examples
979    ///
980    /// ```
981    /// #![feature(maybe_uninit_as_bytes)]
982    /// use std::mem::MaybeUninit;
983    ///
984    /// let val = 0x12345678_i32;
985    /// let mut uninit = MaybeUninit::new(val);
986    /// let uninit_bytes = uninit.as_bytes_mut();
987    /// if cfg!(target_endian = "little") {
988    ///     uninit_bytes[0].write(0xcd);
989    /// } else {
990    ///     uninit_bytes[3].write(0xcd);
991    /// }
992    /// let val2 = unsafe { uninit.assume_init() };
993    /// assert_eq!(val2, 0x123456cd);
994    /// ```
995    #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
996    pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
997        // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
998        unsafe {
999            slice::from_raw_parts_mut(
1000                self.as_mut_ptr().cast::<MaybeUninit<u8>>(),
1001                super::size_of::<T>(),
1002            )
1003        }
1004    }
1005
1006    /// Deprecated version of [`slice::assume_init_ref`].
1007    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1008    #[deprecated(
1009        note = "replaced by inherent assume_init_ref method; will eventually be removed",
1010        since = "1.83.0"
1011    )]
1012    pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
1013        // SAFETY: Same for both methods.
1014        unsafe { slice.assume_init_ref() }
1015    }
1016
1017    /// Deprecated version of [`slice::assume_init_mut`].
1018    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1019    #[deprecated(
1020        note = "replaced by inherent assume_init_mut method; will eventually be removed",
1021        since = "1.83.0"
1022    )]
1023    pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
1024        // SAFETY: Same for both methods.
1025        unsafe { slice.assume_init_mut() }
1026    }
1027
1028    /// Gets a pointer to the first element of the array.
1029    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1030    #[inline(always)]
1031    pub const fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
1032        this.as_ptr() as *const T
1033    }
1034
1035    /// Gets a mutable pointer to the first element of the array.
1036    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1037    #[inline(always)]
1038    pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
1039        this.as_mut_ptr() as *mut T
1040    }
1041
1042    /// Deprecated version of [`slice::write_copy_of_slice`].
1043    #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
1044    #[deprecated(
1045        note = "replaced by inherent write_copy_of_slice method; will eventually be removed",
1046        since = "1.83.0"
1047    )]
1048    pub fn copy_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
1049    where
1050        T: Copy,
1051    {
1052        this.write_copy_of_slice(src)
1053    }
1054
1055    /// Deprecated version of [`slice::write_clone_of_slice`].
1056    #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
1057    #[deprecated(
1058        note = "replaced by inherent write_clone_of_slice method; will eventually be removed",
1059        since = "1.83.0"
1060    )]
1061    pub fn clone_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
1062    where
1063        T: Clone,
1064    {
1065        this.write_clone_of_slice(src)
1066    }
1067
1068    /// Deprecated version of [`slice::write_filled`].
1069    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1070    #[deprecated(
1071        note = "replaced by inherent write_filled method; will eventually be removed",
1072        since = "1.83.0"
1073    )]
1074    pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
1075    where
1076        T: Clone,
1077    {
1078        this.write_filled(value)
1079    }
1080
1081    /// Deprecated version of [`slice::write_with`].
1082    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1083    #[deprecated(
1084        note = "replaced by inherent write_with method; will eventually be removed",
1085        since = "1.83.0"
1086    )]
1087    pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], mut f: F) -> &'a mut [T]
1088    where
1089        F: FnMut() -> T,
1090    {
1091        this.write_with(|_| f())
1092    }
1093
1094    /// Deprecated version of [`slice::write_iter`].
1095    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1096    #[deprecated(
1097        note = "replaced by inherent write_iter method; will eventually be removed",
1098        since = "1.83.0"
1099    )]
1100    pub fn fill_from<'a, I>(
1101        this: &'a mut [MaybeUninit<T>],
1102        it: I,
1103    ) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
1104    where
1105        I: IntoIterator<Item = T>,
1106    {
1107        this.write_iter(it)
1108    }
1109
1110    /// Deprecated version of [`slice::as_bytes`].
1111    #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
1112    #[deprecated(
1113        note = "replaced by inherent as_bytes method; will eventually be removed",
1114        since = "1.83.0"
1115    )]
1116    pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>] {
1117        this.as_bytes()
1118    }
1119
1120    /// Deprecated version of [`slice::as_bytes_mut`].
1121    #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
1122    #[deprecated(
1123        note = "replaced by inherent as_bytes_mut method; will eventually be removed",
1124        since = "1.83.0"
1125    )]
1126    pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>] {
1127        this.as_bytes_mut()
1128    }
1129}
1130
1131impl<T> [MaybeUninit<T>] {
1132    /// Copies the elements from `src` to `self`,
1133    /// returning a mutable reference to the now initialized contents of `self`.
1134    ///
1135    /// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead.
1136    ///
1137    /// This is similar to [`slice::copy_from_slice`].
1138    ///
1139    /// # Panics
1140    ///
1141    /// This function will panic if the two slices have different lengths.
1142    ///
1143    /// # Examples
1144    ///
1145    /// ```
1146    /// #![feature(maybe_uninit_write_slice)]
1147    /// use std::mem::MaybeUninit;
1148    ///
1149    /// let mut dst = [MaybeUninit::uninit(); 32];
1150    /// let src = [0; 32];
1151    ///
1152    /// let init = dst.write_copy_of_slice(&src);
1153    ///
1154    /// assert_eq!(init, src);
1155    /// ```
1156    ///
1157    /// ```
1158    /// #![feature(maybe_uninit_write_slice)]
1159    ///
1160    /// let mut vec = Vec::with_capacity(32);
1161    /// let src = [0; 16];
1162    ///
1163    /// vec.spare_capacity_mut()[..src.len()].write_copy_of_slice(&src);
1164    ///
1165    /// // SAFETY: we have just copied all the elements of len into the spare capacity
1166    /// // the first src.len() elements of the vec are valid now.
1167    /// unsafe {
1168    ///     vec.set_len(src.len());
1169    /// }
1170    ///
1171    /// assert_eq!(vec, src);
1172    /// ```
1173    ///
1174    /// [`write_clone_of_slice`]: slice::write_clone_of_slice
1175    #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
1176    pub const fn write_copy_of_slice(&mut self, src: &[T]) -> &mut [T]
1177    where
1178        T: Copy,
1179    {
1180        // SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
1181        let uninit_src: &[MaybeUninit<T>] = unsafe { super::transmute(src) };
1182
1183        self.copy_from_slice(uninit_src);
1184
1185        // SAFETY: Valid elements have just been copied into `self` so it is initialized
1186        unsafe { self.assume_init_mut() }
1187    }
1188
1189    /// Clones the elements from `src` to `self`,
1190    /// returning a mutable reference to the now initialized contents of `self`.
1191    /// Any already initialized elements will not be dropped.
1192    ///
1193    /// If `T` implements `Copy`, use [`write_copy_of_slice`] instead.
1194    ///
1195    /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1196    ///
1197    /// # Panics
1198    ///
1199    /// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics.
1200    ///
1201    /// If there is a panic, the already cloned elements will be dropped.
1202    ///
1203    /// # Examples
1204    ///
1205    /// ```
1206    /// #![feature(maybe_uninit_write_slice)]
1207    /// use std::mem::MaybeUninit;
1208    ///
1209    /// let mut dst = [const { MaybeUninit::uninit() }; 5];
1210    /// let src = ["wibbly", "wobbly", "timey", "wimey", "stuff"].map(|s| s.to_string());
1211    ///
1212    /// let init = dst.write_clone_of_slice(&src);
1213    ///
1214    /// assert_eq!(init, src);
1215    ///
1216    /// # // Prevent leaks for Miri
1217    /// # unsafe { std::ptr::drop_in_place(init); }
1218    /// ```
1219    ///
1220    /// ```
1221    /// #![feature(maybe_uninit_write_slice)]
1222    ///
1223    /// let mut vec = Vec::with_capacity(32);
1224    /// let src = ["rust", "is", "a", "pretty", "cool", "language"].map(|s| s.to_string());
1225    ///
1226    /// vec.spare_capacity_mut()[..src.len()].write_clone_of_slice(&src);
1227    ///
1228    /// // SAFETY: we have just cloned all the elements of len into the spare capacity
1229    /// // the first src.len() elements of the vec are valid now.
1230    /// unsafe {
1231    ///     vec.set_len(src.len());
1232    /// }
1233    ///
1234    /// assert_eq!(vec, src);
1235    /// ```
1236    ///
1237    /// [`write_copy_of_slice`]: slice::write_copy_of_slice
1238    #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
1239    pub fn write_clone_of_slice(&mut self, src: &[T]) -> &mut [T]
1240    where
1241        T: Clone,
1242    {
1243        // unlike copy_from_slice this does not call clone_from_slice on the slice
1244        // this is because `MaybeUninit<T: Clone>` does not implement Clone.
1245
1246        assert_eq!(self.len(), src.len(), "destination and source slices have different lengths");
1247
1248        // NOTE: We need to explicitly slice them to the same length
1249        // for bounds checking to be elided, and the optimizer will
1250        // generate memcpy for simple cases (for example T = u8).
1251        let len = self.len();
1252        let src = &src[..len];
1253
1254        // guard is needed b/c panic might happen during a clone
1255        let mut guard = Guard { slice: self, initialized: 0 };
1256
1257        for i in 0..len {
1258            guard.slice[i].write(src[i].clone());
1259            guard.initialized += 1;
1260        }
1261
1262        super::forget(guard);
1263
1264        // SAFETY: Valid elements have just been written into `self` so it is initialized
1265        unsafe { self.assume_init_mut() }
1266    }
1267
1268    /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1269    /// initialized contents of the slice.
1270    /// Any previously initialized elements will not be dropped.
1271    ///
1272    /// This is similar to [`slice::fill`].
1273    ///
1274    /// # Panics
1275    ///
1276    /// This function will panic if any call to `Clone` panics.
1277    ///
1278    /// If such a panic occurs, any elements previously initialized during this operation will be
1279    /// dropped.
1280    ///
1281    /// # Examples
1282    ///
1283    /// ```
1284    /// #![feature(maybe_uninit_fill)]
1285    /// use std::mem::MaybeUninit;
1286    ///
1287    /// let mut buf = [const { MaybeUninit::uninit() }; 10];
1288    /// let initialized = buf.write_filled(1);
1289    /// assert_eq!(initialized, &mut [1; 10]);
1290    /// ```
1291    #[doc(alias = "memset")]
1292    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1293    pub fn write_filled(&mut self, value: T) -> &mut [T]
1294    where
1295        T: Clone,
1296    {
1297        SpecFill::spec_fill(self, value);
1298        // SAFETY: Valid elements have just been filled into `self` so it is initialized
1299        unsafe { self.assume_init_mut() }
1300    }
1301
1302    /// Fills a slice with elements returned by calling a closure for each index.
1303    ///
1304    /// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1305    /// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
1306    /// pass [`|_| Default::default()`][Default::default] as the argument.
1307    ///
1308    /// # Panics
1309    ///
1310    /// This function will panic if any call to the provided closure panics.
1311    ///
1312    /// If such a panic occurs, any elements previously initialized during this operation will be
1313    /// dropped.
1314    ///
1315    /// # Examples
1316    ///
1317    /// ```
1318    /// #![feature(maybe_uninit_fill)]
1319    /// use std::mem::MaybeUninit;
1320    ///
1321    /// let mut buf = [const { MaybeUninit::<usize>::uninit() }; 5];
1322    /// let initialized = buf.write_with(|idx| idx + 1);
1323    /// assert_eq!(initialized, &mut [1, 2, 3, 4, 5]);
1324    /// ```
1325    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1326    pub fn write_with<F>(&mut self, mut f: F) -> &mut [T]
1327    where
1328        F: FnMut(usize) -> T,
1329    {
1330        let mut guard = Guard { slice: self, initialized: 0 };
1331
1332        for (idx, element) in guard.slice.iter_mut().enumerate() {
1333            element.write(f(idx));
1334            guard.initialized += 1;
1335        }
1336
1337        super::forget(guard);
1338
1339        // SAFETY: Valid elements have just been written into `this` so it is initialized
1340        unsafe { self.assume_init_mut() }
1341    }
1342
1343    /// Fills a slice with elements yielded by an iterator until either all elements have been
1344    /// initialized or the iterator is empty.
1345    ///
1346    /// Returns two slices. The first slice contains the initialized portion of the original slice.
1347    /// The second slice is the still-uninitialized remainder of the original slice.
1348    ///
1349    /// # Panics
1350    ///
1351    /// This function panics if the iterator's `next` function panics.
1352    ///
1353    /// If such a panic occurs, any elements previously initialized during this operation will be
1354    /// dropped.
1355    ///
1356    /// # Examples
1357    ///
1358    /// Completely filling the slice:
1359    ///
1360    /// ```
1361    /// #![feature(maybe_uninit_fill)]
1362    /// use std::mem::MaybeUninit;
1363    ///
1364    /// let mut buf = [const { MaybeUninit::uninit() }; 5];
1365    ///
1366    /// let iter = [1, 2, 3].into_iter().cycle();
1367    /// let (initialized, remainder) = buf.write_iter(iter);
1368    ///
1369    /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
1370    /// assert_eq!(remainder.len(), 0);
1371    /// ```
1372    ///
1373    /// Partially filling the slice:
1374    ///
1375    /// ```
1376    /// #![feature(maybe_uninit_fill)]
1377    /// use std::mem::MaybeUninit;
1378    ///
1379    /// let mut buf = [const { MaybeUninit::uninit() }; 5];
1380    /// let iter = [1, 2];
1381    /// let (initialized, remainder) = buf.write_iter(iter);
1382    ///
1383    /// assert_eq!(initialized, &mut [1, 2]);
1384    /// assert_eq!(remainder.len(), 3);
1385    /// ```
1386    ///
1387    /// Checking an iterator after filling a slice:
1388    ///
1389    /// ```
1390    /// #![feature(maybe_uninit_fill)]
1391    /// use std::mem::MaybeUninit;
1392    ///
1393    /// let mut buf = [const { MaybeUninit::uninit() }; 3];
1394    /// let mut iter = [1, 2, 3, 4, 5].into_iter();
1395    /// let (initialized, remainder) = buf.write_iter(iter.by_ref());
1396    ///
1397    /// assert_eq!(initialized, &mut [1, 2, 3]);
1398    /// assert_eq!(remainder.len(), 0);
1399    /// assert_eq!(iter.as_slice(), &[4, 5]);
1400    /// ```
1401    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1402    pub fn write_iter<I>(&mut self, it: I) -> (&mut [T], &mut [MaybeUninit<T>])
1403    where
1404        I: IntoIterator<Item = T>,
1405    {
1406        let iter = it.into_iter();
1407        let mut guard = Guard { slice: self, initialized: 0 };
1408
1409        for (element, val) in guard.slice.iter_mut().zip(iter) {
1410            element.write(val);
1411            guard.initialized += 1;
1412        }
1413
1414        let initialized_len = guard.initialized;
1415        super::forget(guard);
1416
1417        // SAFETY: guard.initialized <= self.len()
1418        let (initted, remainder) = unsafe { self.split_at_mut_unchecked(initialized_len) };
1419
1420        // SAFETY: Valid elements have just been written into `init`, so that portion
1421        // of `this` is initialized.
1422        (unsafe { initted.assume_init_mut() }, remainder)
1423    }
1424
1425    /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
1426    ///
1427    /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1428    /// contain padding bytes which are left uninitialized.
1429    ///
1430    /// # Examples
1431    ///
1432    /// ```
1433    /// #![feature(maybe_uninit_as_bytes, maybe_uninit_write_slice, maybe_uninit_slice)]
1434    /// use std::mem::MaybeUninit;
1435    ///
1436    /// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)];
1437    /// let uninit_bytes = uninit.as_bytes();
1438    /// let bytes = unsafe { uninit_bytes.assume_init_ref() };
1439    /// let val1 = u16::from_ne_bytes(bytes[0..2].try_into().unwrap());
1440    /// let val2 = u16::from_ne_bytes(bytes[2..4].try_into().unwrap());
1441    /// assert_eq!(&[val1, val2], &[0x1234u16, 0x5678u16]);
1442    /// ```
1443    #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
1444    pub const fn as_bytes(&self) -> &[MaybeUninit<u8>] {
1445        // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
1446        unsafe {
1447            slice::from_raw_parts(self.as_ptr().cast::<MaybeUninit<u8>>(), super::size_of_val(self))
1448        }
1449    }
1450
1451    /// Returns the contents of this `MaybeUninit` slice as a mutable slice of potentially
1452    /// uninitialized bytes.
1453    ///
1454    /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1455    /// contain padding bytes which are left uninitialized.
1456    ///
1457    /// # Examples
1458    ///
1459    /// ```
1460    /// #![feature(maybe_uninit_as_bytes, maybe_uninit_write_slice, maybe_uninit_slice)]
1461    /// use std::mem::MaybeUninit;
1462    ///
1463    /// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()];
1464    /// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit);
1465    /// uninit_bytes.write_copy_of_slice(&[0x12, 0x34, 0x56, 0x78]);
1466    /// let vals = unsafe { uninit.assume_init_ref() };
1467    /// if cfg!(target_endian = "little") {
1468    ///     assert_eq!(vals, &[0x3412u16, 0x7856u16]);
1469    /// } else {
1470    ///     assert_eq!(vals, &[0x1234u16, 0x5678u16]);
1471    /// }
1472    /// ```
1473    #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
1474    pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
1475        // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
1476        unsafe {
1477            slice::from_raw_parts_mut(
1478                self.as_mut_ptr() as *mut MaybeUninit<u8>,
1479                super::size_of_val(self),
1480            )
1481        }
1482    }
1483
1484    /// Drops the contained values in place.
1485    ///
1486    /// # Safety
1487    ///
1488    /// It is up to the caller to guarantee that every `MaybeUninit<T>` in the slice
1489    /// really is in an initialized state. Calling this when the content is not yet
1490    /// fully initialized causes undefined behavior.
1491    ///
1492    /// On top of that, all additional invariants of the type `T` must be
1493    /// satisfied, as the `Drop` implementation of `T` (or its members) may
1494    /// rely on this. For example, setting a `Vec<T>` to an invalid but
1495    /// non-null address makes it initialized (under the current implementation;
1496    /// this does not constitute a stable guarantee), because the only
1497    /// requirement the compiler knows about it is that the data pointer must be
1498    /// non-null. Dropping such a `Vec<T>` however will cause undefined
1499    /// behaviour.
1500    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1501    #[inline(always)]
1502    pub unsafe fn assume_init_drop(&mut self) {
1503        if !self.is_empty() {
1504            // SAFETY: the caller must guarantee that every element of `self`
1505            // is initialized and satisfies all invariants of `T`.
1506            // Dropping the value in place is safe if that is the case.
1507            unsafe { ptr::drop_in_place(self as *mut [MaybeUninit<T>] as *mut [T]) }
1508        }
1509    }
1510
1511    /// Gets a shared reference to the contained value.
1512    ///
1513    /// # Safety
1514    ///
1515    /// Calling this when the content is not yet fully initialized causes undefined
1516    /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
1517    /// the slice really is in an initialized state.
1518    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1519    #[inline(always)]
1520    pub const unsafe fn assume_init_ref(&self) -> &[T] {
1521        // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
1522        // `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
1523        // The pointer obtained is valid since it refers to memory owned by `slice` which is a
1524        // reference and thus guaranteed to be valid for reads.
1525        unsafe { &*(self as *const Self as *const [T]) }
1526    }
1527
1528    /// Gets a mutable (unique) reference to the contained value.
1529    ///
1530    /// # Safety
1531    ///
1532    /// Calling this when the content is not yet fully initialized causes undefined
1533    /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
1534    /// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot
1535    /// be used to initialize a `MaybeUninit` slice.
1536    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1537    #[inline(always)]
1538    pub const unsafe fn assume_init_mut(&mut self) -> &mut [T] {
1539        // SAFETY: similar to safety notes for `slice_get_ref`, but we have a
1540        // mutable reference which is also guaranteed to be valid for writes.
1541        unsafe { &mut *(self as *mut Self as *mut [T]) }
1542    }
1543}
1544
1545impl<T, const N: usize> MaybeUninit<[T; N]> {
1546    /// Transposes a `MaybeUninit<[T; N]>` into a `[MaybeUninit<T>; N]`.
1547    ///
1548    /// # Examples
1549    ///
1550    /// ```
1551    /// #![feature(maybe_uninit_uninit_array_transpose)]
1552    /// # use std::mem::MaybeUninit;
1553    ///
1554    /// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().transpose();
1555    /// ```
1556    #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
1557    #[inline]
1558    pub const fn transpose(self) -> [MaybeUninit<T>; N] {
1559        // SAFETY: T and MaybeUninit<T> have the same layout
1560        unsafe { intrinsics::transmute_unchecked(self) }
1561    }
1562}
1563
1564impl<T, const N: usize> [MaybeUninit<T>; N] {
1565    /// Transposes a `[MaybeUninit<T>; N]` into a `MaybeUninit<[T; N]>`.
1566    ///
1567    /// # Examples
1568    ///
1569    /// ```
1570    /// #![feature(maybe_uninit_uninit_array_transpose)]
1571    /// # use std::mem::MaybeUninit;
1572    ///
1573    /// let data = [MaybeUninit::<u8>::uninit(); 1000];
1574    /// let data: MaybeUninit<[u8; 1000]> = data.transpose();
1575    /// ```
1576    #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
1577    #[inline]
1578    pub const fn transpose(self) -> MaybeUninit<[T; N]> {
1579        // SAFETY: T and MaybeUninit<T> have the same layout
1580        unsafe { intrinsics::transmute_unchecked(self) }
1581    }
1582}
1583
1584struct Guard<'a, T> {
1585    slice: &'a mut [MaybeUninit<T>],
1586    initialized: usize,
1587}
1588
1589impl<'a, T> Drop for Guard<'a, T> {
1590    fn drop(&mut self) {
1591        let initialized_part = &mut self.slice[..self.initialized];
1592        // SAFETY: this raw sub-slice will contain only initialized objects.
1593        unsafe {
1594            initialized_part.assume_init_drop();
1595        }
1596    }
1597}
1598
1599trait SpecFill<T> {
1600    fn spec_fill(&mut self, value: T);
1601}
1602
1603impl<T: Clone> SpecFill<T> for [MaybeUninit<T>] {
1604    default fn spec_fill(&mut self, value: T) {
1605        let mut guard = Guard { slice: self, initialized: 0 };
1606
1607        if let Some((last, elems)) = guard.slice.split_last_mut() {
1608            for el in elems {
1609                el.write(value.clone());
1610                guard.initialized += 1;
1611            }
1612
1613            last.write(value);
1614        }
1615        super::forget(guard);
1616    }
1617}
1618
1619impl<T: Copy> SpecFill<T> for [MaybeUninit<T>] {
1620    fn spec_fill(&mut self, value: T) {
1621        self.fill(MaybeUninit::new(value));
1622    }
1623}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy