@@ -5,11 +5,15 @@ use crate::{fmt, intrinsics, ptr, slice};
55
66/// A wrapper type to construct uninitialized instances of `T`.
77///
8+ /// A `MaybeUninit<T>` is like a `T`, but without the requirement that it is properly initialized as a `T`.
9+ /// Dropping a `MaybeUninit<T>` does nothing, even if properly initialized as a `T`, because
10+ /// the compiler relies on the type system to decide how to drop variables. Thus, if a `MaybeUninit<T>`
11+ /// should be dropped like a `T`, it should be converted to a `T` with `assume_init` or similar.
12+ ///
813/// # Initialization invariant
914///
10- /// The compiler, in general, assumes that a variable is properly initialized
11- /// according to the requirements of the variable's type. For example, a variable of
12- /// reference type must be aligned and non-null. This is an invariant that must
15+ /// Every variable must be properly initialized according to the requirements of its type.
16+ /// For example, a variable of reference type must be aligned and non-null. This is an invariant that must
1317/// *always* be upheld, even in unsafe code. As a consequence, zero-initializing a
1418/// variable of reference type causes instantaneous [undefined behavior][ub],
1519/// no matter whether that reference ever gets used to access memory:
@@ -392,7 +396,7 @@ impl<T> MaybeUninit<T> {
392396 MaybeUninit { value : ManuallyDrop :: new ( val) }
393397 }
394398
395- /// Creates a new `MaybeUninit<T>` in an uninitialized state .
399+ /// Creates a new uninitialized `MaybeUninit<T>`.
396400 ///
397401 /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
398402 /// It is your responsibility to make sure `T` gets dropped if it got initialized.
@@ -415,8 +419,7 @@ impl<T> MaybeUninit<T> {
415419 MaybeUninit { uninit : ( ) }
416420 }
417421
418- /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
419- /// filled with `0` bytes. It depends on `T` whether that already makes for
422+ /// Creates a new zero-filled `MaybeUninit<T>`. It depends on `T` whether that already makes for
420423 /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
421424 /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
422425 /// be null.
@@ -475,14 +478,11 @@ impl<T> MaybeUninit<T> {
475478 /// For your convenience, this also returns a mutable reference to the
476479 /// (now safely initialized) contents of `self`.
477480 ///
478- /// As the content is stored inside a `ManuallyDrop`, the destructor is not
479- /// run for the inner data if the MaybeUninit leaves scope without a call to
480- /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
481- /// the mutable reference returned by this function needs to keep this in
482- /// mind. The safety model of Rust regards leaks as safe, but they are
483- /// usually still undesirable. This being said, the mutable reference
484- /// behaves like any other mutable reference would, so assigning a new value
485- /// to it will drop the old content.
481+ /// Keep in mind, that the value, as it is wrapped in a `MaybeUninit`,
482+ /// will not be dropped when its wrapper is. You can make sure the value is dropped by unwrapping
483+ /// it with a call to [`assume_init`], or by dropping it directly with [`assume_init_drop`].
484+ /// While the value is also dropped when the returned mutable reference is assigned a new value,
485+ /// the new value is then subject to the same rules, as now the new value is wrapped in a `MaybeUninit`.
486486 ///
487487 /// [`assume_init`]: Self::assume_init
488488 /// [`assume_init_drop`]: Self::assume_init_drop
@@ -518,7 +518,7 @@ impl<T> MaybeUninit<T> {
518518 /// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
519519 /// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
520520 /// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
521- /// // This leaks the contained string:
521+ /// // This leaks the initialized string:
522522 /// x.write("hello".to_string());
523523 /// // x is initialized now:
524524 /// let s = unsafe { x.assume_init() };
@@ -593,7 +593,7 @@ impl<T> MaybeUninit<T> {
593593 /// ```
594594 ///
595595 /// (Notice that the rules around references to uninitialized data are not finalized yet, but
596- /// until they are, it is advisable to avoid them .)
596+ /// until they are, it is advisable to avoid references to uninitialized data .)
597597 #[ stable( feature = "maybe_uninit" , since = "1.36.0" ) ]
598598 #[ rustc_const_stable( feature = "const_maybe_uninit_as_ptr" , since = "1.59.0" ) ]
599599 #[ rustc_as_ptr]
@@ -645,16 +645,17 @@ impl<T> MaybeUninit<T> {
645645 self as * mut _ as * mut T
646646 }
647647
648- /// Extracts the value from the `MaybeUninit<T>` container . This is a great way
648+ /// Converts an initialized `MaybeUninit<T>` into a `T` . This is a great way
649649 /// to ensure that the data will get dropped, because the resulting `T` is
650650 /// subject to the usual drop handling.
651651 ///
652652 /// # Safety
653653 ///
654- /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
655- /// state. Calling this when the content is not yet fully initialized causes immediate undefined
656- /// behavior. The [type-level documentation][inv] contains more information about
657- /// this initialization invariant.
654+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
655+ /// before converting it into a `T`. Calling this when the `T` value of the `MaybeUninit<T>`
656+ /// is not yet fully initialized causes immediate undefined behavior.
657+ ///
658+ /// The [type-level documentation][inv] contains more information about this initialization invariant.
658659 ///
659660 /// [inv]: #initialization-invariant
660661 ///
@@ -706,17 +707,19 @@ impl<T> MaybeUninit<T> {
706707 }
707708 }
708709
709- /// Reads the value from the `MaybeUninit<T>` container . The resulting `T` is subject
710- /// to the usual drop handling.
710+ /// Reads the `T` value of the `MaybeUninit<T>`. The result is an ordinary `T` which,
711+ /// just like all `T` values, is subject to the usual drop handling.
711712 ///
712713 /// Whenever possible, it is preferable to use [`assume_init`] instead, which
713714 /// prevents duplicating the content of the `MaybeUninit<T>`.
714715 ///
715716 /// # Safety
716717 ///
717- /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
718- /// state. Calling this when the content is not yet fully initialized causes undefined
719- /// behavior. The [type-level documentation][inv] contains more information about
718+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
719+ /// before reading the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
720+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
721+ ///
722+ /// The [type-level documentation][inv] contains more information about
720723 /// this initialization invariant.
721724 ///
722725 /// Moreover, similar to the [`ptr::read`] function, this function creates a
@@ -776,16 +779,16 @@ impl<T> MaybeUninit<T> {
776779 }
777780 }
778781
779- /// Drops the contained value in place.
782+ /// Drops the `T` value of the `MaybeUninit<T>` in place, like [`ptr::drop_in_place`] .
780783 ///
781784 /// If you have ownership of the `MaybeUninit`, you can also use
782785 /// [`assume_init`] as an alternative.
783786 ///
784787 /// # Safety
785788 ///
786- /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is
787- /// in an initialized state . Calling this when the content is not yet fully
788- /// initialized causes undefined behavior.
789+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
790+ /// before dropping the `T` value of the `MaybeUninit<T>` . Calling this when the `T` value
791+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
789792 ///
790793 /// On top of that, all additional invariants of the type `T` must be
791794 /// satisfied, as the `Drop` implementation of `T` (or its members) may
@@ -817,9 +820,9 @@ impl<T> MaybeUninit<T> {
817820 ///
818821 /// # Safety
819822 ///
820- /// Calling this when the content is not yet fully initialized causes undefined
821- /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
822- /// is in an initialized state .
823+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
824+ /// before getting a reference to the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
825+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior .
823826 ///
824827 /// # Examples
825828 ///
@@ -884,10 +887,9 @@ impl<T> MaybeUninit<T> {
884887 ///
885888 /// # Safety
886889 ///
887- /// Calling this when the content is not yet fully initialized causes undefined
888- /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
889- /// is in an initialized state. For instance, `.assume_init_mut()` cannot be used to
890- /// initialize a `MaybeUninit`.
890+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
891+ /// before getting a mutable reference to the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
892+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
891893 ///
892894 /// # Examples
893895 ///
@@ -998,7 +1000,7 @@ impl<T> MaybeUninit<T> {
9981000 /// # Safety
9991001 ///
10001002 /// It is up to the caller to guarantee that all elements of the array are
1001- /// in an initialized state .
1003+ /// properly initialized.
10021004 ///
10031005 /// # Examples
10041006 ///
@@ -1035,8 +1037,7 @@ impl<T> MaybeUninit<T> {
10351037
10361038 /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
10371039 ///
1038- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1039- /// contain padding bytes which are left uninitialized.
1040+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
10401041 ///
10411042 /// # Examples
10421043 ///
@@ -1061,8 +1062,7 @@ impl<T> MaybeUninit<T> {
10611062 /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized
10621063 /// bytes.
10631064 ///
1064- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1065- /// contain padding bytes which are left uninitialized.
1065+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
10661066 ///
10671067 /// # Examples
10681068 ///
@@ -1108,8 +1108,8 @@ impl<T> MaybeUninit<T> {
11081108}
11091109
11101110impl < T > [ MaybeUninit < T > ] {
1111- /// Copies the elements from `src ` to `self`,
1112- /// returning a mutable reference to the now initialized contents of `self` .
1111+ /// Copies all elements from a `&[T] ` to this `[MaybeUninit<T>]`.
1112+ /// Returns a `&mut [T]` to the so initialized array .
11131113 ///
11141114 /// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead.
11151115 ///
@@ -1165,13 +1165,14 @@ impl<T> [MaybeUninit<T>] {
11651165 unsafe { self . assume_init_mut ( ) }
11661166 }
11671167
1168- /// Clones the elements from `src ` to `self`,
1169- /// returning a mutable reference to the now initialized contents of `self` .
1168+ /// Clones all elements from a `&[T] ` to this `[MaybeUninit<T>]`.
1169+ /// Returns a `&mut [T]` to the so initialized array .
11701170 /// Any already initialized elements will not be dropped.
11711171 ///
11721172 /// If `T` implements `Copy`, use [`write_copy_of_slice`] instead.
11731173 ///
1174- /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1174+ /// This is similar to [`slice::clone_from_slice`] but cannot drop existing `MaybeUninit<T>`,
1175+ /// as it cannot know if any of them was initialized.
11751176 ///
11761177 /// # Panics
11771178 ///
@@ -1403,8 +1404,7 @@ impl<T> [MaybeUninit<T>] {
14031404
14041405 /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
14051406 ///
1406- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1407- /// contain padding bytes which are left uninitialized.
1407+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
14081408 ///
14091409 /// # Examples
14101410 ///
@@ -1430,8 +1430,7 @@ impl<T> [MaybeUninit<T>] {
14301430 /// Returns the contents of this `MaybeUninit` slice as a mutable slice of potentially
14311431 /// uninitialized bytes.
14321432 ///
1433- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1434- /// contain padding bytes which are left uninitialized.
1433+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
14351434 ///
14361435 /// # Examples
14371436 ///
@@ -1460,13 +1459,13 @@ impl<T> [MaybeUninit<T>] {
14601459 }
14611460 }
14621461
1463- /// Drops the contained values in place.
1462+ /// Assumes all elements have been fully initialized and drops them in place, like [`ptr::drop_in_place`] .
14641463 ///
14651464 /// # Safety
14661465 ///
1467- /// It is up to the caller to guarantee that every `MaybeUninit<T>` in the slice
1468- /// really is in an initialized state . Calling this when the content is not yet
1469- /// fully initialized causes undefined behavior.
1466+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
1467+ /// before calling . Calling this when any of the `T` elements of the `[MaybeUninit<T>]`
1468+ /// has not yet been fully initialized causes immediate undefined behavior.
14701469 ///
14711470 /// On top of that, all additional invariants of the type `T` must be
14721471 /// satisfied, as the `Drop` implementation of `T` (or its members) may
@@ -1495,9 +1494,9 @@ impl<T> [MaybeUninit<T>] {
14951494 ///
14961495 /// # Safety
14971496 ///
1498- /// Calling this when the content is not yet fully initialized causes undefined
1497+ /// Calling this when the elements have not been fully initialized causes undefined
14991498 /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
1500- /// the slice really is in an initialized state .
1499+ /// the slice really is properly initialized.
15011500 #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
15021501 #[ inline( always) ]
15031502 pub const unsafe fn assume_init_ref ( & self ) -> & [ T ] {
@@ -1512,9 +1511,9 @@ impl<T> [MaybeUninit<T>] {
15121511 ///
15131512 /// # Safety
15141513 ///
1515- /// Calling this when the content is not yet fully initialized causes undefined
1514+ /// Calling this when the elements have not been fully initialized causes undefined
15161515 /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
1517- /// slice really is in an initialized state . For instance, `.assume_init_mut()` cannot
1516+ /// slice really is properly initialized. For instance, `.assume_init_mut()` cannot
15181517 /// be used to initialize a `MaybeUninit` slice.
15191518 #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
15201519 #[ inline( always) ]
0 commit comments