File tree Expand file tree Collapse file tree 2 files changed +32
-2
lines changed Expand file tree Collapse file tree 2 files changed +32
-2
lines changed Original file line number Diff line number Diff line change @@ -413,7 +413,8 @@ impl<T, const N: usize> [T; N] {
413413 }
414414 }
415415 let mut dst = MaybeUninit :: uninit_array :: < N > ( ) ;
416- let mut guard: Guard < U , N > = Guard { dst : & mut dst as * mut _ as * mut U , initialized : 0 } ;
416+ let mut guard: Guard < U , N > =
417+ Guard { dst : MaybeUninit :: first_ptr_mut ( & mut dst) , initialized : 0 } ;
417418 for ( src, dst) in IntoIter :: new ( self ) . zip ( & mut dst) {
418419 dst. write ( f ( src) ) ;
419420 guard. initialized += 1 ;
@@ -423,6 +424,6 @@ impl<T, const N: usize> [T; N] {
423424 crate :: mem:: forget ( guard) ;
424425 // SAFETY: At this point we've properly initialized the whole array
425426 // and we just need to cast it to the correct type.
426- unsafe { ( & mut dst as * mut _ as * mut [ U ; N ] ) . read ( ) }
427+ unsafe { crate :: mem :: transmute_copy :: < _ , [ U ; N ] > ( & dst ) }
427428 }
428429}
Original file line number Diff line number Diff line change @@ -301,3 +301,32 @@ fn array_map() {
301301 let b = a. map ( |v| v as u64 ) ;
302302 assert_eq ! ( b, [ 1 , 2 , 3 ] ) ;
303303}
304+
305+ // See note on above test for why `should_panic` is used.
306+ #[ test]
307+ #[ should_panic( expected = "test succeeded" ) ]
308+ fn array_map_drop_safety ( ) {
309+ use core:: sync:: atomic:: AtomicUsize ;
310+ use core:: sync:: atomic:: Ordering ;
311+ static DROPPED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
312+ struct DropCounter ;
313+ impl Drop for DropCounter {
314+ fn drop ( & mut self ) {
315+ DROPPED . fetch_add ( 1 , Ordering :: SeqCst ) ;
316+ }
317+ }
318+
319+ let num_to_create = 5 ;
320+ let success = std:: panic:: catch_unwind ( || {
321+ let items = [ 0 ; 10 ] ;
322+ let mut nth = 0 ;
323+ items. map ( |_| {
324+ assert ! ( nth < num_to_create) ;
325+ nth += 1 ;
326+ DropCounter
327+ } ) ;
328+ } ) ;
329+ assert ! ( success. is_err( ) ) ;
330+ assert_eq ! ( DROPPED . load( Ordering :: SeqCst ) , num_to_create) ;
331+ panic ! ( "test succeeded" )
332+ }
You can’t perform that action at this time.
0 commit comments