summaryrefslogtreecommitdiffstats
path: root/library/core/src/mem/maybe_uninit.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/core/src/mem/maybe_uninit.rs54
1 files changed, 43 insertions, 11 deletions
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index b4ea53608..7757c95de 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -54,9 +54,6 @@ use crate::slice;
/// // The equivalent code with `MaybeUninit<i32>`:
/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
/// ```
-/// (Notice that the rules around uninitialized integers are not finalized yet, but
-/// until they are, it is advisable to avoid them.)
-///
/// On top of that, remember that most types have additional invariants beyond merely
/// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
/// is considered initialized (under the current implementation; this does not constitute
@@ -130,11 +127,8 @@ use crate::slice;
/// MaybeUninit::uninit().assume_init()
/// };
///
-/// // Dropping a `MaybeUninit` does nothing. Thus using raw pointer
-/// // assignment instead of `ptr::write` does not cause the old
-/// // uninitialized value to be dropped. Also if there is a panic during
-/// // this loop, we have a memory leak, but there is no memory safety
-/// // issue.
+/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
+/// // we have a memory leak, but there is no memory safety issue.
/// for elem in &mut data[..] {
/// elem.write(vec![42]);
/// }
@@ -152,7 +146,6 @@ use crate::slice;
///
/// ```
/// use std::mem::MaybeUninit;
-/// use std::ptr;
///
/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
/// // safe because the type we are claiming to have initialized here is a
@@ -168,7 +161,7 @@ use crate::slice;
///
/// // For each item in the array, drop if we allocated it.
/// for elem in &mut data[0..data_len] {
-/// unsafe { ptr::drop_in_place(elem.as_mut_ptr()); }
+/// unsafe { elem.assume_init_drop(); }
/// }
/// ```
///
@@ -653,7 +646,7 @@ impl<T> MaybeUninit<T> {
/// implements the [`Copy`] trait or not. When using multiple copies of the
/// data (by calling `assume_init_read` multiple times, or first calling
/// `assume_init_read` and then [`assume_init`]), it is your responsibility
- /// to ensure that that data may indeed be duplicated.
+ /// to ensure that data may indeed be duplicated.
///
/// [inv]: #initialization-invariant
/// [`assume_init`]: MaybeUninit::assume_init
@@ -1290,3 +1283,42 @@ impl<T> MaybeUninit<T> {
}
}
}
+
+impl<T, const N: usize> MaybeUninit<[T; N]> {
+ /// Transposes a `MaybeUninit<[T; N]>` into a `[MaybeUninit<T>; N]`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(maybe_uninit_uninit_array_transpose)]
+ /// # use std::mem::MaybeUninit;
+ ///
+ /// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().transpose();
+ /// ```
+ #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
+ #[inline]
+ pub const fn transpose(self) -> [MaybeUninit<T>; N] {
+ // SAFETY: T and MaybeUninit<T> have the same layout
+ unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
+ }
+}
+
+impl<T, const N: usize> [MaybeUninit<T>; N] {
+ /// Transposes a `[MaybeUninit<T>; N]` into a `MaybeUninit<[T; N]>`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(maybe_uninit_uninit_array_transpose)]
+ /// # use std::mem::MaybeUninit;
+ ///
+ /// let data = [MaybeUninit::<u8>::uninit(); 1000];
+ /// let data: MaybeUninit<[u8; 1000]> = data.transpose();
+ /// ```
+ #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
+ #[inline]
+ pub const fn transpose(self) -> MaybeUninit<[T; N]> {
+ // SAFETY: T and MaybeUninit<T> have the same layout
+ unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
+ }
+}