@@ -799,6 +799,51 @@ impl<T, const N: usize> [T; N] {
799799 }
800800}
801801
802+ impl < T , const N : usize > [ MaybeUninit < T > ; N ] {
803+ /// Extracts the values from an array of [`MaybeUninit<T>`] containers.
804+ ///
805+ /// This is essentially `.map(MaybeUninit::assume_init)`, but in a way
806+ /// that's *much* clearer to the optimizer how to do efficiently.
807+ ///
808+ /// # Safety
809+ ///
810+ /// It is up to the caller to guarantee that all elements of the array are
811+ /// in an initialized state.
812+ ///
813+ /// # Examples
814+ ///
815+ /// ```
816+ /// #![feature(inline_const)]
817+ /// #![feature(array_maybe_uninit_assume_init)]
818+ /// use std::mem::MaybeUninit;
819+ ///
820+ /// let mut array = [const { MaybeUninit::<i32>::uninit() }; 3];
821+ /// array[0].write(0);
822+ /// array[1].write(1);
823+ /// array[2].write(2);
824+ ///
825+ /// // SAFETY: we initialised all three elements
826+ /// let array = unsafe { array.assume_init() };
827+ ///
828+ /// assert_eq!(array, [0, 1, 2]);
829+ /// ```
830+ #[ unstable( feature = "array_maybe_uninit_assume_init" , issue = "96097" ) ]
831+ #[ rustc_const_unstable( feature = "const_array_maybe_uninit_assume_init" , issue = "96097" ) ]
832+ #[ inline( always) ]
833+ #[ track_caller]
834+ pub const unsafe fn assume_init ( self ) -> [ T ; N ] {
835+ // SAFETY:
836+ // * The caller guarantees that all elements of the array are initialized
837+ // * `MaybeUninit<T>` and T are guaranteed to have the same layout
838+ // * `MaybeUninit` does not drop, so there are no double-frees
839+ // And thus the conversion is safe
840+ unsafe {
841+ crate :: intrinsics:: assert_inhabited :: < [ T ; N ] > ( ) ;
842+ mem:: transmute_copy ( & mem:: ManuallyDrop :: new ( self ) )
843+ }
844+ }
845+ }
846+
802847/// Pulls `N` items from `iter` and returns them as an array. If the iterator
803848/// yields fewer than `N` items, this function exhibits undefined behavior.
804849///
@@ -896,7 +941,7 @@ where
896941
897942 mem:: forget ( guard) ;
898943 // SAFETY: All elements of the array were populated in the loop above.
899- let output = unsafe { array. transpose ( ) . assume_init ( ) } ;
944+ let output = unsafe { array. assume_init ( ) } ;
900945 Ok ( Try :: from_output ( output) )
901946}
902947
0 commit comments