Skip to content

Commit 124cd85

Browse files
committed
Clarify MaybeUninit docs
1 parent fd17dea commit 124cd85

File tree

1 file changed

+61
-61
lines changed

1 file changed

+61
-61
lines changed

library/core/src/mem/maybe_uninit.rs

Lines changed: 61 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -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

12461247
impl<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

Comments
 (0)