@@ -916,7 +916,7 @@ where
916
916
///
917
917
/// To minimize indirection fields are still pub but callers should at least use
918
918
/// `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 > {
920
920
/// The array to be initialized.
921
921
pub array_mut : & ' a mut [ MaybeUninit < T > ; N ] ,
922
922
/// The number of items that have been initialized so far.
@@ -930,7 +930,7 @@ impl<T, const N: usize> Guard<'_, T, N> {
930
930
///
931
931
/// No more than N elements must be initialized.
932
932
#[ inline]
933
- pub unsafe fn push_unchecked ( & mut self , item : T ) {
933
+ pub const unsafe fn push_unchecked ( & mut self , item : T ) {
934
934
// SAFETY: If `initialized` was correct before and the caller does not
935
935
// invoke this method more than N times then writes will be in-bounds
936
936
// and slots will not be initialized more than once.
@@ -941,15 +941,33 @@ impl<T, const N: usize> Guard<'_, T, N> {
941
941
}
942
942
}
943
943
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 > {
945
945
fn drop ( & mut self ) {
946
946
debug_assert ! ( self . initialized <= N ) ;
947
947
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
+
948
965
// SAFETY: this slice will contain only initialized objects.
949
966
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) ;
953
971
}
954
972
}
955
973
}
0 commit comments