@@ -4,11 +4,15 @@ use crate::{fmt, intrinsics, ptr, slice};
44
55/// A wrapper type to construct uninitialized instances of `T`.
66///
7+ /// A `MaybeUninit<T>` is like a `T`, but without the requirement that it is properly initialized as a `T`.
8+ /// Dropping a `MaybeUninit<T>` does nothing, even if properly initialized as a `T`, because
9+ /// the compiler relies on the type system to decide how to drop variables. Thus, if a `MaybeUninit<T>`
10+ /// should be dropped like a `T`, it should be converted to a `T` with `assume_init` or similar.
11+ ///
712/// # Initialization invariant
813///
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
14+ /// Every variable must be properly initialized according to the requirements of its type.
15+ /// For example, a variable of reference type must be aligned and non-null. This is an invariant that must
1216/// *always* be upheld, even in unsafe code. As a consequence, zero-initializing a
1317/// variable of reference type causes instantaneous [undefined behavior][ub],
1418/// no matter whether that reference ever gets used to access memory:
@@ -308,7 +312,7 @@ impl<T> MaybeUninit<T> {
308312 MaybeUninit { value : ManuallyDrop :: new ( val) }
309313 }
310314
311- /// Creates a new `MaybeUninit<T>` in an uninitialized state .
315+ /// Creates a new uninitialized `MaybeUninit<T>`.
312316 ///
313317 /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
314318 /// It is your responsibility to make sure `T` gets dropped if it got initialized.
@@ -331,8 +335,7 @@ impl<T> MaybeUninit<T> {
331335 MaybeUninit { uninit : ( ) }
332336 }
333337
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
338+ /// Creates a new zero-filled `MaybeUninit<T>`. It depends on `T` whether that already makes for
336339 /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
337340 /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
338341 /// be null.
@@ -391,14 +394,11 @@ impl<T> MaybeUninit<T> {
391394 /// For your convenience, this also returns a mutable reference to the
392395 /// (now safely initialized) contents of `self`.
393396 ///
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.
397+ /// Keep in mind, that the value, as it is wrapped in a `MaybeUninit`,
398+ /// will not be dropped when its wrapper is. You can make sure the value is dropped by unwrapping
399+ /// it with a call to [`assume_init`], or by dropping it directly with [`assume_init_drop`].
400+ /// While the value is also dropped when the returned mutable reference is assigned a new value,
401+ /// the new value is then subject to the same rules, as now the new value is wrapped in a `MaybeUninit`.
402402 ///
403403 /// [`assume_init`]: Self::assume_init
404404 /// [`assume_init_drop`]: Self::assume_init_drop
@@ -434,7 +434,7 @@ impl<T> MaybeUninit<T> {
434434 /// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
435435 /// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
436436 /// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
437- /// // This leaks the contained string:
437+ /// // This leaks the initialized string:
438438 /// x.write("hello".to_string());
439439 /// // x is initialized now:
440440 /// let s = unsafe { x.assume_init() };
@@ -509,7 +509,7 @@ impl<T> MaybeUninit<T> {
509509 /// ```
510510 ///
511511 /// (Notice that the rules around references to uninitialized data are not finalized yet, but
512- /// until they are, it is advisable to avoid them .)
512+ /// until they are, it is advisable to avoid references to uninitialized data .)
513513 #[ stable( feature = "maybe_uninit" , since = "1.36.0" ) ]
514514 #[ rustc_const_stable( feature = "const_maybe_uninit_as_ptr" , since = "1.59.0" ) ]
515515 #[ rustc_as_ptr]
@@ -561,16 +561,17 @@ impl<T> MaybeUninit<T> {
561561 self as * mut _ as * mut T
562562 }
563563
564- /// Extracts the value from the `MaybeUninit<T>` container . This is a great way
564+ /// Converts an initialized `MaybeUninit<T>` into a `T` . This is a great way
565565 /// to ensure that the data will get dropped, because the resulting `T` is
566566 /// subject to the usual drop handling.
567567 ///
568568 /// # Safety
569569 ///
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.
570+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
571+ /// before converting it into a `T`. Calling this when the `T` value of the `MaybeUninit<T>`
572+ /// is not yet fully initialized causes immediate undefined behavior.
573+ ///
574+ /// The [type-level documentation][inv] contains more information about this initialization invariant.
574575 ///
575576 /// [inv]: #initialization-invariant
576577 ///
@@ -620,17 +621,19 @@ impl<T> MaybeUninit<T> {
620621 }
621622 }
622623
623- /// Reads the value from the `MaybeUninit<T>` container . The resulting `T` is subject
624- /// to the usual drop handling.
624+ /// Reads the `T` value of the `MaybeUninit<T>`. The result is an ordinary `T` which,
625+ /// just like all `T` values, is subject to the usual drop handling.
625626 ///
626627 /// Whenever possible, it is preferable to use [`assume_init`] instead, which
627628 /// prevents duplicating the content of the `MaybeUninit<T>`.
628629 ///
629630 /// # Safety
630631 ///
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
632+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
633+ /// before reading the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
634+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
635+ ///
636+ /// The [type-level documentation][inv] contains more information about
634637 /// this initialization invariant.
635638 ///
636639 /// Moreover, similar to the [`ptr::read`] function, this function creates a
@@ -690,16 +693,16 @@ impl<T> MaybeUninit<T> {
690693 }
691694 }
692695
693- /// Drops the contained value in place.
696+ /// Drops the `T` value of the `MaybeUninit<T>` in place, like [`ptr::drop_in_place`] .
694697 ///
695698 /// If you have ownership of the `MaybeUninit`, you can also use
696699 /// [`assume_init`] as an alternative.
697700 ///
698701 /// # Safety
699702 ///
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+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
704+ /// before dropping the `T` value of the `MaybeUninit<T>` . Calling this when the `T` value
705+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
703706 ///
704707 /// On top of that, all additional invariants of the type `T` must be
705708 /// satisfied, as the `Drop` implementation of `T` (or its members) may
@@ -727,9 +730,9 @@ impl<T> MaybeUninit<T> {
727730 ///
728731 /// # Safety
729732 ///
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+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
734+ /// before getting a reference to the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
735+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior .
733736 ///
734737 /// # Examples
735738 ///
@@ -795,10 +798,9 @@ impl<T> MaybeUninit<T> {
795798 ///
796799 /// # Safety
797800 ///
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`.
801+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
802+ /// before getting a mutable reference to the `T` value of the `MaybeUninit<T>`. Calling this when the `T` value
803+ /// of the `MaybeUninit<T>` is not yet fully initialized causes immediate undefined behavior.
802804 ///
803805 /// # Examples
804806 ///
@@ -909,7 +911,7 @@ impl<T> MaybeUninit<T> {
909911 /// # Safety
910912 ///
911913 /// It is up to the caller to guarantee that all elements of the array are
912- /// in an initialized state .
914+ /// properly initialized.
913915 ///
914916 /// # Examples
915917 ///
@@ -946,8 +948,7 @@ impl<T> MaybeUninit<T> {
946948
947949 /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
948950 ///
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+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
951952 ///
952953 /// # Examples
953954 ///
@@ -972,8 +973,7 @@ impl<T> MaybeUninit<T> {
972973 /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized
973974 /// bytes.
974975 ///
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.
976+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
977977 ///
978978 /// # Examples
979979 ///
@@ -1065,8 +1065,9 @@ impl<T> MaybeUninit<T> {
10651065 this. write_clone_of_slice ( src)
10661066 }
10671067
1068- /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
1069- /// initialized contents of the slice.
1068+ /// Fills a `&mut [MaybeUninit<T>]` with clones of the given value of type `T`.
1069+ /// Returns a `&mut [T]` to the so initialized slice.
1070+ ///
10701071 /// Any previously initialized elements will not be dropped.
10711072 ///
10721073 /// This is similar to [`slice::fill`].
@@ -1244,8 +1245,8 @@ impl<T> MaybeUninit<T> {
12441245}
12451246
12461247impl < T > [ MaybeUninit < T > ] {
1247- /// Copies the elements from `src ` to `self`,
1248- /// returning a mutable reference to the now initialized contents of `self` .
1248+ /// Copies all elements from a `&[T] ` to this `[MaybeUninit<T>]`.
1249+ /// Returns a `&mut [T]` to the so initialized array .
12491250 ///
12501251 /// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead.
12511252 ///
@@ -1301,13 +1302,14 @@ impl<T> [MaybeUninit<T>] {
13011302 unsafe { self . assume_init_mut ( ) }
13021303 }
13031304
1304- /// Clones the elements from `src ` to `self`,
1305- /// returning a mutable reference to the now initialized contents of `self` .
1305+ /// Clones all elements from a `&[T] ` to this `[MaybeUninit<T>]`.
1306+ /// Returns a `&mut [T]` to the so initialized array .
13061307 /// Any already initialized elements will not be dropped.
13071308 ///
13081309 /// If `T` implements `Copy`, use [`write_copy_of_slice`] instead.
13091310 ///
1310- /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1311+ /// This is similar to [`slice::clone_from_slice`] but cannot drop existing `MaybeUninit<T>`,
1312+ /// as it cannot know if any of them was initialized.
13111313 ///
13121314 /// # Panics
13131315 ///
@@ -1382,8 +1384,7 @@ impl<T> [MaybeUninit<T>] {
13821384
13831385 /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
13841386 ///
1385- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1386- /// contain padding bytes which are left uninitialized.
1387+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
13871388 ///
13881389 /// # Examples
13891390 ///
@@ -1409,8 +1410,7 @@ impl<T> [MaybeUninit<T>] {
14091410 /// Returns the contents of this `MaybeUninit` slice as a mutable slice of potentially
14101411 /// uninitialized bytes.
14111412 ///
1412- /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
1413- /// contain padding bytes which are left uninitialized.
1413+ /// Note that a value may still contain uninitialized padding bytes even if it has been fully initialized.
14141414 ///
14151415 /// # Examples
14161416 ///
@@ -1439,13 +1439,13 @@ impl<T> [MaybeUninit<T>] {
14391439 }
14401440 }
14411441
1442- /// Drops the contained values in place.
1442+ /// Assumes all elements have been fully initialized and drops them in place, like [`ptr::drop_in_place`] .
14431443 ///
14441444 /// # Safety
14451445 ///
1446- /// It is up to the caller to guarantee that every `MaybeUninit<T>` in the slice
1447- /// really is in an initialized state . Calling this when the content is not yet
1448- /// fully initialized causes undefined behavior.
1446+ /// It is up to the caller to ensure that the `MaybeUninit<T>` has been fully initialized,
1447+ /// before calling . Calling this when any of the `T` elements of the `[MaybeUninit<T>]`
1448+ /// has not yet been fully initialized causes immediate undefined behavior.
14491449 ///
14501450 /// On top of that, all additional invariants of the type `T` must be
14511451 /// satisfied, as the `Drop` implementation of `T` (or its members) may
@@ -1470,9 +1470,9 @@ impl<T> [MaybeUninit<T>] {
14701470 ///
14711471 /// # Safety
14721472 ///
1473- /// Calling this when the content is not yet fully initialized causes undefined
1473+ /// Calling this when the elements have not been fully initialized causes undefined
14741474 /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
1475- /// the slice really is in an initialized state .
1475+ /// the slice really is properly initialized.
14761476 #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
14771477 #[ inline( always) ]
14781478 pub const unsafe fn assume_init_ref ( & self ) -> & [ T ] {
@@ -1487,9 +1487,9 @@ impl<T> [MaybeUninit<T>] {
14871487 ///
14881488 /// # Safety
14891489 ///
1490- /// Calling this when the content is not yet fully initialized causes undefined
1490+ /// Calling this when the elements have not been fully initialized causes undefined
14911491 /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
1492- /// slice really is in an initialized state . For instance, `.assume_init_mut()` cannot
1492+ /// slice really is properly initialized. For instance, `.assume_init_mut()` cannot
14931493 /// be used to initialize a `MaybeUninit` slice.
14941494 #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
14951495 #[ inline( always) ]
0 commit comments