@@ -916,7 +916,7 @@ where
916916///
917917/// To minimize indirection fields are still pub but callers should at least use
918918/// `push_unchecked` to signal that something unsafe is going on.
919- pub ( crate ) struct Guard < ' a , T , const N : usize > {
919+ pub ( crate ) struct Guard < ' a , T : ~ const Destruct , const N : usize > {
920920 /// The array to be initialized.
921921 pub array_mut : & ' a mut [ MaybeUninit < T > ; N ] ,
922922 /// The number of items that have been initialized so far.
@@ -930,7 +930,7 @@ impl<T, const N: usize> Guard<'_, T, N> {
930930 ///
931931 /// No more than N elements must be initialized.
932932 #[ inline]
933- pub unsafe fn push_unchecked ( & mut self , item : T ) {
933+ pub const unsafe fn push_unchecked ( & mut self , item : T ) {
934934 // SAFETY: If `initialized` was correct before and the caller does not
935935 // invoke this method more than N times then writes will be in-bounds
936936 // and slots will not be initialized more than once.
@@ -941,15 +941,33 @@ impl<T, const N: usize> Guard<'_, T, N> {
941941 }
942942}
943943
944- impl < T , const N : usize > Drop for Guard < ' _ , T , N > {
944+ impl < T : ~ const Destruct , const N : usize > const Drop for Guard < ' _ , T , N > {
945945 fn drop ( & mut self ) {
946946 debug_assert ! ( self . initialized <= N ) ;
947947
948+ #[ inline]
949+ const fn drop_ct < T : ~const Destruct > ( x : & mut [ T ] ) {
950+ let mut i = 0 ;
951+ while i < x. len ( ) {
952+ // SAFETY: dropping the value, contains initialized objects
953+ unsafe {
954+ crate :: ptr:: read ( & mut x[ i] ) ;
955+ }
956+ i += 1 ;
957+ }
958+ }
959+ #[ inline]
960+ fn drop_rt < T > ( x : & mut [ T ] ) {
961+ // SAFETY: slice contains initialized objects
962+ unsafe { crate :: ptr:: drop_in_place ( x) }
963+ }
964+
948965 // SAFETY: this slice will contain only initialized objects.
949966 unsafe {
950- crate :: ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut (
951- & mut self . array_mut . get_unchecked_mut ( ..self . initialized ) ,
952- ) ) ;
967+ let to_drop = MaybeUninit :: slice_assume_init_mut (
968+ self . array_mut . get_unchecked_mut ( ..self . initialized ) ,
969+ ) ;
970+ crate :: intrinsics:: const_eval_select ( ( to_drop, ) , drop_ct, drop_rt) ;
953971 }
954972 }
955973}
0 commit comments