Add drop check test & MaybeUninit::first_ptr_mut
Also in drop check test add hacky workaround for platforms that don't support panic=unwind
This commit is contained in:
parent
412417d807
commit
af32db21c8
2 changed files with 32 additions and 2 deletions
|
@ -413,7 +413,8 @@ impl<T, const N: usize> [T; N] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut dst = MaybeUninit::uninit_array::<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) {
|
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
|
||||||
dst.write(f(src));
|
dst.write(f(src));
|
||||||
guard.initialized += 1;
|
guard.initialized += 1;
|
||||||
|
@ -423,6 +424,6 @@ impl<T, const N: usize> [T; N] {
|
||||||
crate::mem::forget(guard);
|
crate::mem::forget(guard);
|
||||||
// SAFETY: At this point we've properly initialized the whole array
|
// SAFETY: At this point we've properly initialized the whole array
|
||||||
// and we just need to cast it to the correct type.
|
// 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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,3 +301,32 @@ fn array_map() {
|
||||||
let b = a.map(|v| v as u64);
|
let b = a.map(|v| v as u64);
|
||||||
assert_eq!(b, [1, 2, 3]);
|
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")
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue