@@ -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