@@ -365,8 +365,8 @@ macro_rules! array_impl_default {
365365
366366array_impl_default ! { 32 , T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T }
367367
368- #[ lang = "array" ]
369368#[ cfg( not( bootstrap) ) ]
369+ #[ lang = "array" ]
370370impl < T , const N : usize > [ T ; N ] {
371371 /// Returns an array of the same size as self, with `f` applied to each element.
372372 ///
@@ -382,9 +382,35 @@ impl<T, const N: usize> [T; N] {
382382 F : FnMut ( T ) -> S ,
383383 {
384384 use crate :: mem:: MaybeUninit ;
385+ struct Guard < T , const N : usize > {
386+ dst : * mut T ,
387+ curr_init : usize ,
388+ }
389+
390+ impl < T , const N : usize > Guard < T , N > {
391+ fn new ( dst : & mut [ MaybeUninit < T > ; N ] ) -> Self {
392+ Guard { dst : dst as * mut _ as * mut T , curr_init : 0 }
393+ }
394+ }
395+
396+ impl < T , const N : usize > Drop for Guard < T , N > {
397+ fn drop ( & mut self ) {
398+ debug_assert ! ( self . curr_init <= N ) ;
399+
400+ let initialized_part =
401+ crate :: ptr:: slice_from_raw_parts_mut ( self . dst , self . curr_init ) ;
402+ // SAFETY: this raw slice will contain only initialized objects
403+ // that's why, it is allowed to drop it.
404+ unsafe {
405+ crate :: ptr:: drop_in_place ( initialized_part) ;
406+ }
407+ }
408+ }
385409 let dst = MaybeUninit :: uninit_array :: < N > ( ) ;
410+ let mut guard = Guard :: new ( & mut dst) ;
386411 for ( i, e) in self . into_iter ( ) . enumerate ( ) {
387412 dst[ i] = MaybeUninit :: new ( f ( e) ) ;
413+ guard. curr_init += 1 ;
388414 }
389415 // FIXME convert to crate::mem::transmute when works with generics
390416 // unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) }
0 commit comments