2014-06-28 15:57:36 -05:00
|
|
|
use core::mem::*;
|
|
|
|
|
2020-12-18 16:53:55 -06:00
|
|
|
#[cfg(panic = "unwind")]
|
2020-12-01 00:24:04 -06:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2014-06-28 15:57:36 -05:00
|
|
|
#[test]
|
|
|
|
fn size_of_basic() {
|
2015-02-03 07:50:52 -06:00
|
|
|
assert_eq!(size_of::<u8>(), 1);
|
|
|
|
assert_eq!(size_of::<u16>(), 2);
|
|
|
|
assert_eq!(size_of::<u32>(), 4);
|
|
|
|
assert_eq!(size_of::<u64>(), 8);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
2016-05-06 08:31:11 -05:00
|
|
|
#[test]
|
|
|
|
#[cfg(target_pointer_width = "16")]
|
|
|
|
fn size_of_16() {
|
|
|
|
assert_eq!(size_of::<usize>(), 2);
|
|
|
|
assert_eq!(size_of::<*const usize>(), 2);
|
|
|
|
}
|
|
|
|
|
2014-06-28 15:57:36 -05:00
|
|
|
#[test]
|
2015-01-13 20:59:45 -06:00
|
|
|
#[cfg(target_pointer_width = "32")]
|
2014-06-28 15:57:36 -05:00
|
|
|
fn size_of_32() {
|
2015-03-25 19:06:52 -05:00
|
|
|
assert_eq!(size_of::<usize>(), 4);
|
|
|
|
assert_eq!(size_of::<*const usize>(), 4);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2015-01-13 20:59:45 -06:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
2014-06-28 15:57:36 -05:00
|
|
|
fn size_of_64() {
|
2015-03-25 19:06:52 -05:00
|
|
|
assert_eq!(size_of::<usize>(), 8);
|
|
|
|
assert_eq!(size_of::<*const usize>(), 8);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn size_of_val_basic() {
|
|
|
|
assert_eq!(size_of_val(&1u8), 1);
|
|
|
|
assert_eq!(size_of_val(&1u16), 2);
|
|
|
|
assert_eq!(size_of_val(&1u32), 4);
|
|
|
|
assert_eq!(size_of_val(&1u64), 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn align_of_basic() {
|
2015-02-03 07:50:52 -06:00
|
|
|
assert_eq!(align_of::<u8>(), 1);
|
|
|
|
assert_eq!(align_of::<u16>(), 2);
|
|
|
|
assert_eq!(align_of::<u32>(), 4);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
2016-05-06 08:31:11 -05:00
|
|
|
#[test]
|
|
|
|
#[cfg(target_pointer_width = "16")]
|
|
|
|
fn align_of_16() {
|
|
|
|
assert_eq!(align_of::<usize>(), 2);
|
|
|
|
assert_eq!(align_of::<*const usize>(), 2);
|
|
|
|
}
|
|
|
|
|
2014-06-28 15:57:36 -05:00
|
|
|
#[test]
|
2015-01-13 20:59:45 -06:00
|
|
|
#[cfg(target_pointer_width = "32")]
|
2014-06-28 15:57:36 -05:00
|
|
|
fn align_of_32() {
|
2015-03-25 19:06:52 -05:00
|
|
|
assert_eq!(align_of::<usize>(), 4);
|
|
|
|
assert_eq!(align_of::<*const usize>(), 4);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2015-01-13 20:59:45 -06:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
2014-06-28 15:57:36 -05:00
|
|
|
fn align_of_64() {
|
2015-03-25 19:06:52 -05:00
|
|
|
assert_eq!(align_of::<usize>(), 8);
|
|
|
|
assert_eq!(align_of::<*const usize>(), 8);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn align_of_val_basic() {
|
2015-02-03 07:50:52 -06:00
|
|
|
assert_eq!(align_of_val(&1u8), 1);
|
|
|
|
assert_eq!(align_of_val(&1u16), 2);
|
|
|
|
assert_eq!(align_of_val(&1u32), 4);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_swap() {
|
2015-01-25 15:05:03 -06:00
|
|
|
let mut x = 31337;
|
|
|
|
let mut y = 42;
|
2014-06-28 15:57:36 -05:00
|
|
|
swap(&mut x, &mut y);
|
|
|
|
assert_eq!(x, 42);
|
|
|
|
assert_eq!(y, 31337);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_replace() {
|
|
|
|
let mut x = Some("test".to_string());
|
|
|
|
let y = replace(&mut x, None);
|
|
|
|
assert!(x.is_none());
|
|
|
|
assert!(y.is_some());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_transmute_copy() {
|
2015-02-03 07:50:52 -06:00
|
|
|
assert_eq!(1, unsafe { transmute_copy(&1) });
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_transmute() {
|
2019-12-06 22:18:12 -06:00
|
|
|
trait Foo {
|
|
|
|
fn dummy(&self) {}
|
|
|
|
}
|
2015-03-25 19:06:52 -05:00
|
|
|
impl Foo for isize {}
|
2014-06-28 15:57:36 -05:00
|
|
|
|
2018-07-13 00:25:22 -05:00
|
|
|
let a = box 100isize as Box<dyn Foo>;
|
2014-06-28 15:57:36 -05:00
|
|
|
unsafe {
|
|
|
|
let x: ::core::raw::TraitObject = transmute(a);
|
2015-03-25 19:06:52 -05:00
|
|
|
assert!(*(x.data as *const isize) == 100);
|
2018-07-13 00:25:22 -05:00
|
|
|
let _x: Box<dyn Foo> = transmute(x);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
2015-03-10 19:59:23 -05:00
|
|
|
assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
|
2014-06-28 15:57:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-07 14:33:36 -05:00
|
|
|
#[test]
|
|
|
|
#[allow(dead_code)]
|
|
|
|
fn test_discriminant_send_sync() {
|
|
|
|
enum Regular {
|
|
|
|
A,
|
2019-12-06 22:18:12 -06:00
|
|
|
B(i32),
|
2017-10-07 14:33:36 -05:00
|
|
|
}
|
|
|
|
enum NotSendSync {
|
2019-12-06 22:18:12 -06:00
|
|
|
A(*const i32),
|
2017-10-07 14:33:36 -05:00
|
|
|
}
|
|
|
|
|
2019-12-06 22:18:12 -06:00
|
|
|
fn is_send_sync<T: Send + Sync>() {}
|
2017-10-07 14:33:36 -05:00
|
|
|
|
|
|
|
is_send_sync::<Discriminant<Regular>>();
|
|
|
|
is_send_sync::<Discriminant<NotSendSync>>();
|
|
|
|
}
|
2020-12-02 12:14:10 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn assume_init_good() {
|
2020-12-05 12:37:03 -06:00
|
|
|
const TRUE: bool = unsafe { MaybeUninit::<bool>::new(true).assume_init() };
|
|
|
|
|
2020-12-02 12:14:10 -06:00
|
|
|
assert!(TRUE);
|
|
|
|
}
|
2020-12-01 00:24:04 -06:00
|
|
|
|
2021-01-01 15:12:49 -06:00
|
|
|
#[test]
|
|
|
|
fn uninit_array_assume_init() {
|
|
|
|
let mut array: [MaybeUninit<i16>; 5] = MaybeUninit::uninit_array();
|
|
|
|
array[0].write(3);
|
|
|
|
array[1].write(1);
|
|
|
|
array[2].write(4);
|
|
|
|
array[3].write(1);
|
|
|
|
array[4].write(5);
|
|
|
|
|
2021-01-01 15:56:54 -06:00
|
|
|
let array = unsafe { MaybeUninit::array_assume_init(array) };
|
|
|
|
|
2021-01-01 15:12:49 -06:00
|
|
|
assert_eq!(array, [3, 1, 4, 1, 5]);
|
2021-01-26 09:21:00 -06:00
|
|
|
|
|
|
|
let [] = unsafe { MaybeUninit::<!>::array_assume_init([]) };
|
2021-01-01 15:12:49 -06:00
|
|
|
}
|
|
|
|
|
2020-12-01 00:24:04 -06:00
|
|
|
#[test]
|
|
|
|
fn uninit_write_slice() {
|
|
|
|
let mut dst = [MaybeUninit::new(255); 64];
|
|
|
|
let src = [0; 64];
|
|
|
|
|
|
|
|
assert_eq!(MaybeUninit::write_slice(&mut dst, &src), &src);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "source slice length (32) does not match destination slice length (64)")]
|
|
|
|
fn uninit_write_slice_panic_lt() {
|
|
|
|
let mut dst = [MaybeUninit::uninit(); 64];
|
|
|
|
let src = [0; 32];
|
|
|
|
|
|
|
|
MaybeUninit::write_slice(&mut dst, &src);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "source slice length (128) does not match destination slice length (64)")]
|
|
|
|
fn uninit_write_slice_panic_gt() {
|
|
|
|
let mut dst = [MaybeUninit::uninit(); 64];
|
|
|
|
let src = [0; 128];
|
|
|
|
|
|
|
|
MaybeUninit::write_slice(&mut dst, &src);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn uninit_clone_from_slice() {
|
|
|
|
let mut dst = [MaybeUninit::new(255); 64];
|
|
|
|
let src = [0; 64];
|
|
|
|
|
|
|
|
assert_eq!(MaybeUninit::write_slice_cloned(&mut dst, &src), &src);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "destination and source slices have different lengths")]
|
|
|
|
fn uninit_write_slice_cloned_panic_lt() {
|
|
|
|
let mut dst = [MaybeUninit::uninit(); 64];
|
|
|
|
let src = [0; 32];
|
|
|
|
|
|
|
|
MaybeUninit::write_slice_cloned(&mut dst, &src);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "destination and source slices have different lengths")]
|
|
|
|
fn uninit_write_slice_cloned_panic_gt() {
|
|
|
|
let mut dst = [MaybeUninit::uninit(); 64];
|
|
|
|
let src = [0; 128];
|
|
|
|
|
|
|
|
MaybeUninit::write_slice_cloned(&mut dst, &src);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg(panic = "unwind")]
|
|
|
|
fn uninit_write_slice_cloned_mid_panic() {
|
|
|
|
use std::panic;
|
|
|
|
|
|
|
|
enum IncrementOrPanic {
|
|
|
|
Increment(Rc<()>),
|
|
|
|
ExpectedPanic,
|
|
|
|
UnexpectedPanic,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for IncrementOrPanic {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
match self {
|
|
|
|
Self::Increment(rc) => Self::Increment(rc.clone()),
|
|
|
|
Self::ExpectedPanic => panic!("expected panic on clone"),
|
|
|
|
Self::UnexpectedPanic => panic!("unexpected panic on clone"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let rc = Rc::new(());
|
|
|
|
|
|
|
|
let mut dst = [
|
|
|
|
MaybeUninit::uninit(),
|
|
|
|
MaybeUninit::uninit(),
|
|
|
|
MaybeUninit::uninit(),
|
|
|
|
MaybeUninit::uninit(),
|
|
|
|
];
|
|
|
|
|
|
|
|
let src = [
|
|
|
|
IncrementOrPanic::Increment(rc.clone()),
|
|
|
|
IncrementOrPanic::Increment(rc.clone()),
|
|
|
|
IncrementOrPanic::ExpectedPanic,
|
|
|
|
IncrementOrPanic::UnexpectedPanic,
|
|
|
|
];
|
|
|
|
|
|
|
|
let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
|
|
|
MaybeUninit::write_slice_cloned(&mut dst, &src);
|
|
|
|
}));
|
|
|
|
|
|
|
|
drop(src);
|
|
|
|
|
|
|
|
match err {
|
|
|
|
Ok(_) => unreachable!(),
|
|
|
|
Err(payload) => {
|
|
|
|
payload
|
|
|
|
.downcast::<&'static str>()
|
|
|
|
.and_then(|s| if *s == "expected panic on clone" { Ok(s) } else { Err(s) })
|
|
|
|
.unwrap_or_else(|p| panic::resume_unwind(p));
|
|
|
|
|
|
|
|
assert_eq!(Rc::strong_count(&rc), 1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn uninit_write_slice_cloned_no_drop() {
|
2020-12-17 11:18:06 -06:00
|
|
|
#[derive(Clone)]
|
|
|
|
struct Bomb;
|
|
|
|
|
|
|
|
impl Drop for Bomb {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
panic!("dropped a bomb! kaboom")
|
|
|
|
}
|
|
|
|
}
|
2020-12-01 00:24:04 -06:00
|
|
|
|
|
|
|
let mut dst = [MaybeUninit::uninit()];
|
2020-12-17 11:18:06 -06:00
|
|
|
let src = [Bomb];
|
2020-12-01 00:24:04 -06:00
|
|
|
|
|
|
|
MaybeUninit::write_slice_cloned(&mut dst, &src);
|
|
|
|
|
2020-12-17 11:18:06 -06:00
|
|
|
forget(src);
|
2020-12-01 00:24:04 -06:00
|
|
|
}
|
2020-12-25 18:59:08 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[cfg(not(bootstrap))]
|
|
|
|
fn uninit_const_assume_init_read() {
|
|
|
|
const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
|
|
|
|
assert_eq!(FOO, 42);
|
|
|
|
}
|