Skip to content

Commit 826bc36

Browse files
committed
Implement MaybeUninit::array_assume_init
1 parent 206ee1e commit 826bc36

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

library/core/src/mem/maybe_uninit.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,55 @@ impl<T> MaybeUninit<T> {
804804
}
805805
}
806806

807+
/// Extracts the values from an array of `MaybeUninit` containers.
808+
///
809+
/// # Safety
810+
///
811+
/// It is up to the caller to guarantee that all elements of the array are
812+
/// in an initialized state.
813+
///
814+
/// # Examples
815+
///
816+
/// ```
817+
/// #![feature(maybe_uninit_uninit_array)]
818+
/// #![feature(maybe_uninit_array_assume_init)]
819+
/// use std::mem::MaybeUninit;
820+
///
821+
/// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
822+
/// array[0] = MaybeUninit::new(0);
823+
/// array[1] = MaybeUninit::new(1);
824+
/// array[2] = MaybeUninit::new(2);
825+
///
826+
/// // SAFETY: Now safe as we initialised all elements
827+
/// let array = unsafe {
828+
/// MaybeUninit::array_assume_init(array)
829+
/// };
830+
///
831+
/// assert_eq!(array, [0, 1, 2]);
832+
/// ```
833+
#[unstable(feature = "maybe_uninit_array_assume_init", issue = "none")]
834+
#[inline(always)]
835+
pub unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] {
836+
// Convert using a union because mem::transmute does not support const_generics
837+
union ArrayInit<T, const N: usize> {
838+
maybe_uninit: ManuallyDrop<[MaybeUninit<T>; N]>,
839+
init: ManuallyDrop<[T; N]>,
840+
}
841+
842+
// SAFETY:
843+
// * The caller guarantees that all elements of the array are initialized,
844+
// * `MaybeUninit<T>` and T are guaranteed to have the same layout,
845+
// Therefore the conversion is safe
846+
unsafe {
847+
intrinsics::assert_inhabited::<T>();
848+
849+
let array = ArrayInit {
850+
maybe_uninit: ManuallyDrop::new(array),
851+
};
852+
ManuallyDrop::into_inner(array.init)
853+
}
854+
}
855+
807856
/// Assuming all the elements are initialized, get a slice to them.
808857
///
809858
/// # Safety

0 commit comments

Comments
 (0)