@@ -365,8 +365,8 @@ macro_rules! array_impl_default {
365
365
366
366
array_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 }
367
367
368
- #[ lang = "array" ]
369
368
#[ cfg( not( bootstrap) ) ]
369
+ #[ lang = "array" ]
370
370
impl < T , const N : usize > [ T ; N ] {
371
371
/// Returns an array of the same size as self, with `f` applied to each element.
372
372
///
@@ -382,9 +382,35 @@ impl<T, const N: usize> [T; N] {
382
382
F : FnMut ( T ) -> S ,
383
383
{
384
384
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
+ }
385
409
let dst = MaybeUninit :: uninit_array :: < N > ( ) ;
410
+ let mut guard = Guard :: new ( & mut dst) ;
386
411
for ( i, e) in self . into_iter ( ) . enumerate ( ) {
387
412
dst[ i] = MaybeUninit :: new ( f ( e) ) ;
413
+ guard. curr_init += 1 ;
388
414
}
389
415
// FIXME convert to crate::mem::transmute when works with generics
390
416
// unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) }
0 commit comments