File tree 2 files changed +32
-2
lines changed
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] {
413
413
}
414
414
}
415
415
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 } ;
417
418
for ( src, dst) in IntoIter :: new ( self ) . zip ( & mut dst) {
418
419
dst. write ( f ( src) ) ;
419
420
guard. initialized += 1 ;
@@ -423,6 +424,6 @@ impl<T, const N: usize> [T; N] {
423
424
crate :: mem:: forget ( guard) ;
424
425
// SAFETY: At this point we've properly initialized the whole array
425
426
// 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 ) }
427
428
}
428
429
}
Original file line number Diff line number Diff line change @@ -301,3 +301,32 @@ fn array_map() {
301
301
let b = a. map ( |v| v as u64 ) ;
302
302
assert_eq ! ( b, [ 1 , 2 , 3 ] ) ;
303
303
}
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