]> git.lizzy.rs Git - rust.git/blob - library/core/tests/mem.rs
Merge commit '370c397ec9169809e5ad270079712e0043514240' into sync_cg_clif-2022-03-20
[rust.git] / library / core / tests / mem.rs
1 use core::mem::*;
2
3 #[cfg(panic = "unwind")]
4 use std::rc::Rc;
5
6 #[test]
7 fn size_of_basic() {
8     assert_eq!(size_of::<u8>(), 1);
9     assert_eq!(size_of::<u16>(), 2);
10     assert_eq!(size_of::<u32>(), 4);
11     assert_eq!(size_of::<u64>(), 8);
12 }
13
14 #[test]
15 #[cfg(target_pointer_width = "16")]
16 fn size_of_16() {
17     assert_eq!(size_of::<usize>(), 2);
18     assert_eq!(size_of::<*const usize>(), 2);
19 }
20
21 #[test]
22 #[cfg(target_pointer_width = "32")]
23 fn size_of_32() {
24     assert_eq!(size_of::<usize>(), 4);
25     assert_eq!(size_of::<*const usize>(), 4);
26 }
27
28 #[test]
29 #[cfg(target_pointer_width = "64")]
30 fn size_of_64() {
31     assert_eq!(size_of::<usize>(), 8);
32     assert_eq!(size_of::<*const usize>(), 8);
33 }
34
35 #[test]
36 fn size_of_val_basic() {
37     assert_eq!(size_of_val(&1u8), 1);
38     assert_eq!(size_of_val(&1u16), 2);
39     assert_eq!(size_of_val(&1u32), 4);
40     assert_eq!(size_of_val(&1u64), 8);
41 }
42
43 #[test]
44 fn align_of_basic() {
45     assert_eq!(align_of::<u8>(), 1);
46     assert_eq!(align_of::<u16>(), 2);
47     assert_eq!(align_of::<u32>(), 4);
48 }
49
50 #[test]
51 #[cfg(target_pointer_width = "16")]
52 fn align_of_16() {
53     assert_eq!(align_of::<usize>(), 2);
54     assert_eq!(align_of::<*const usize>(), 2);
55 }
56
57 #[test]
58 #[cfg(target_pointer_width = "32")]
59 fn align_of_32() {
60     assert_eq!(align_of::<usize>(), 4);
61     assert_eq!(align_of::<*const usize>(), 4);
62 }
63
64 #[test]
65 #[cfg(target_pointer_width = "64")]
66 fn align_of_64() {
67     assert_eq!(align_of::<usize>(), 8);
68     assert_eq!(align_of::<*const usize>(), 8);
69 }
70
71 #[test]
72 fn align_of_val_basic() {
73     assert_eq!(align_of_val(&1u8), 1);
74     assert_eq!(align_of_val(&1u16), 2);
75     assert_eq!(align_of_val(&1u32), 4);
76 }
77
78 #[test]
79 fn test_swap() {
80     let mut x = 31337;
81     let mut y = 42;
82     swap(&mut x, &mut y);
83     assert_eq!(x, 42);
84     assert_eq!(y, 31337);
85 }
86
87 #[test]
88 fn test_replace() {
89     let mut x = Some("test".to_string());
90     let y = replace(&mut x, None);
91     assert!(x.is_none());
92     assert!(y.is_some());
93 }
94
95 #[test]
96 fn test_transmute_copy() {
97     assert_eq!(1, unsafe { transmute_copy(&1) });
98 }
99
100 #[test]
101 #[allow(dead_code)]
102 fn test_discriminant_send_sync() {
103     enum Regular {
104         A,
105         B(i32),
106     }
107     enum NotSendSync {
108         A(*const i32),
109     }
110
111     fn is_send_sync<T: Send + Sync>() {}
112
113     is_send_sync::<Discriminant<Regular>>();
114     is_send_sync::<Discriminant<NotSendSync>>();
115 }
116
117 #[test]
118 fn assume_init_good() {
119     const TRUE: bool = unsafe { MaybeUninit::<bool>::new(true).assume_init() };
120
121     assert!(TRUE);
122 }
123
124 #[test]
125 fn uninit_array_assume_init() {
126     let mut array: [MaybeUninit<i16>; 5] = MaybeUninit::uninit_array();
127     array[0].write(3);
128     array[1].write(1);
129     array[2].write(4);
130     array[3].write(1);
131     array[4].write(5);
132
133     let array = unsafe { MaybeUninit::array_assume_init(array) };
134
135     assert_eq!(array, [3, 1, 4, 1, 5]);
136
137     let [] = unsafe { MaybeUninit::<!>::array_assume_init([]) };
138 }
139
140 #[test]
141 fn uninit_write_slice() {
142     let mut dst = [MaybeUninit::new(255); 64];
143     let src = [0; 64];
144
145     assert_eq!(MaybeUninit::write_slice(&mut dst, &src), &src);
146 }
147
148 #[test]
149 #[should_panic(expected = "source slice length (32) does not match destination slice length (64)")]
150 fn uninit_write_slice_panic_lt() {
151     let mut dst = [MaybeUninit::uninit(); 64];
152     let src = [0; 32];
153
154     MaybeUninit::write_slice(&mut dst, &src);
155 }
156
157 #[test]
158 #[should_panic(expected = "source slice length (128) does not match destination slice length (64)")]
159 fn uninit_write_slice_panic_gt() {
160     let mut dst = [MaybeUninit::uninit(); 64];
161     let src = [0; 128];
162
163     MaybeUninit::write_slice(&mut dst, &src);
164 }
165
166 #[test]
167 fn uninit_clone_from_slice() {
168     let mut dst = [MaybeUninit::new(255); 64];
169     let src = [0; 64];
170
171     assert_eq!(MaybeUninit::write_slice_cloned(&mut dst, &src), &src);
172 }
173
174 #[test]
175 #[should_panic(expected = "destination and source slices have different lengths")]
176 fn uninit_write_slice_cloned_panic_lt() {
177     let mut dst = [MaybeUninit::uninit(); 64];
178     let src = [0; 32];
179
180     MaybeUninit::write_slice_cloned(&mut dst, &src);
181 }
182
183 #[test]
184 #[should_panic(expected = "destination and source slices have different lengths")]
185 fn uninit_write_slice_cloned_panic_gt() {
186     let mut dst = [MaybeUninit::uninit(); 64];
187     let src = [0; 128];
188
189     MaybeUninit::write_slice_cloned(&mut dst, &src);
190 }
191
192 #[test]
193 #[cfg(panic = "unwind")]
194 fn uninit_write_slice_cloned_mid_panic() {
195     use std::panic;
196
197     enum IncrementOrPanic {
198         Increment(Rc<()>),
199         ExpectedPanic,
200         UnexpectedPanic,
201     }
202
203     impl Clone for IncrementOrPanic {
204         fn clone(&self) -> Self {
205             match self {
206                 Self::Increment(rc) => Self::Increment(rc.clone()),
207                 Self::ExpectedPanic => panic!("expected panic on clone"),
208                 Self::UnexpectedPanic => panic!("unexpected panic on clone"),
209             }
210         }
211     }
212
213     let rc = Rc::new(());
214
215     let mut dst = [
216         MaybeUninit::uninit(),
217         MaybeUninit::uninit(),
218         MaybeUninit::uninit(),
219         MaybeUninit::uninit(),
220     ];
221
222     let src = [
223         IncrementOrPanic::Increment(rc.clone()),
224         IncrementOrPanic::Increment(rc.clone()),
225         IncrementOrPanic::ExpectedPanic,
226         IncrementOrPanic::UnexpectedPanic,
227     ];
228
229     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
230         MaybeUninit::write_slice_cloned(&mut dst, &src);
231     }));
232
233     drop(src);
234
235     match err {
236         Ok(_) => unreachable!(),
237         Err(payload) => {
238             payload
239                 .downcast::<&'static str>()
240                 .and_then(|s| if *s == "expected panic on clone" { Ok(s) } else { Err(s) })
241                 .unwrap_or_else(|p| panic::resume_unwind(p));
242
243             assert_eq!(Rc::strong_count(&rc), 1)
244         }
245     }
246 }
247
248 #[test]
249 fn uninit_write_slice_cloned_no_drop() {
250     #[derive(Clone)]
251     struct Bomb;
252
253     impl Drop for Bomb {
254         fn drop(&mut self) {
255             panic!("dropped a bomb! kaboom")
256         }
257     }
258
259     let mut dst = [MaybeUninit::uninit()];
260     let src = [Bomb];
261
262     MaybeUninit::write_slice_cloned(&mut dst, &src);
263
264     forget(src);
265 }
266
267 #[test]
268 fn uninit_const_assume_init_read() {
269     const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
270     assert_eq!(FOO, 42);
271 }
272
273 #[test]
274 fn const_maybe_uninit() {
275     use std::ptr;
276
277     #[derive(Debug, PartialEq)]
278     struct Foo {
279         x: u8,
280         y: u8,
281     }
282
283     const FIELD_BY_FIELD: Foo = unsafe {
284         let mut val = MaybeUninit::uninit();
285         init_y(&mut val); // order shouldn't matter
286         init_x(&mut val);
287         val.assume_init()
288     };
289
290     const fn init_x(foo: &mut MaybeUninit<Foo>) {
291         unsafe {
292             *ptr::addr_of_mut!((*foo.as_mut_ptr()).x) = 1;
293         }
294     }
295
296     const fn init_y(foo: &mut MaybeUninit<Foo>) {
297         unsafe {
298             *ptr::addr_of_mut!((*foo.as_mut_ptr()).y) = 2;
299         }
300     }
301
302     assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 });
303 }