@@ -804,6 +804,55 @@ impl<T> MaybeUninit<T> {
804
804
}
805
805
}
806
806
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
+
807
856
/// Assuming all the elements are initialized, get a slice to them.
808
857
///
809
858
/// # Safety
0 commit comments