Skip to content

Commit af32db2

Browse files
committed
Add drop check test & MaybeUninit::first_ptr_mut
Also in drop check test add hacky workaround for platforms that don't support panic=unwind
1 parent 412417d commit af32db2

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

library/core/src/array/mod.rs

+3-2
Original file line numberDiff line numberDiff 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
}

library/core/tests/array.rs

+29
Original file line numberDiff line numberDiff 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+
}

0 commit comments

Comments
 (0)