@@ -799,6 +799,51 @@ impl<T, const N: usize> [T; N] {
799
799
}
800
800
}
801
801
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
+
802
847
/// Pulls `N` items from `iter` and returns them as an array. If the iterator
803
848
/// yields fewer than `N` items, this function exhibits undefined behavior.
804
849
///
@@ -896,7 +941,7 @@ where
896
941
897
942
mem:: forget ( guard) ;
898
943
// 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 ( ) } ;
900
945
Ok ( Try :: from_output ( output) )
901
946
}
902
947
0 commit comments