Skip to content

Commit

Permalink
Add drop check test & MaybeUninit::first_ptr_mut
Browse files Browse the repository at this point in the history
Also in drop check test add hacky workaround for platforms that don't support
panic=unwind
  • Loading branch information
JulianKnodt committed Aug 13, 2020
1 parent 412417d commit af32db2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
5 changes: 3 additions & 2 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ impl<T, const N: usize> [T; N] {
}
}
let mut dst = MaybeUninit::uninit_array::<N>();
let mut guard: Guard<U, N> = Guard { dst: &mut dst as *mut _ as *mut U, initialized: 0 };
let mut guard: Guard<U, N> =
Guard { dst: MaybeUninit::first_ptr_mut(&mut dst), initialized: 0 };
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
dst.write(f(src));
guard.initialized += 1;
Expand All @@ -423,6 +424,6 @@ impl<T, const N: usize> [T; N] {
crate::mem::forget(guard);
// SAFETY: At this point we've properly initialized the whole array
// and we just need to cast it to the correct type.
unsafe { (&mut dst as *mut _ as *mut [U; N]).read() }
unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
}
}
29 changes: 29 additions & 0 deletions library/core/tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,32 @@ fn array_map() {
let b = a.map(|v| v as u64);
assert_eq!(b, [1, 2, 3]);
}

// See note on above test for why `should_panic` is used.
#[test]
#[should_panic(expected = "test succeeded")]
fn array_map_drop_safety() {
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering;
static DROPPED: AtomicUsize = AtomicUsize::new(0);
struct DropCounter;
impl Drop for DropCounter {
fn drop(&mut self) {
DROPPED.fetch_add(1, Ordering::SeqCst);
}
}

let num_to_create = 5;
let success = std::panic::catch_unwind(|| {
let items = [0; 10];
let mut nth = 0;
items.map(|_| {
assert!(nth < num_to_create);
nth += 1;
DropCounter
});
});
assert!(success.is_err());
assert_eq!(DROPPED.load(Ordering::SeqCst), num_to_create);
panic!("test succeeded")
}

0 comments on commit af32db2

Please sign in to comment.