]> git.lizzy.rs Git - rust.git/blob - library/core/tests/mem.rs
Rollup merge of #100959 - LuisCardosoOliveira:translation-rename-attr-warning, r...
[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 fn test_transmute_copy_shrink() {
102     assert_eq!(0_u8, unsafe { transmute_copy(&0_u64) });
103 }
104
105 #[test]
106 fn test_transmute_copy_unaligned() {
107     #[repr(C)]
108     #[derive(Default)]
109     struct Unaligned {
110         a: u8,
111         b: [u8; 8],
112     }
113
114     let u = Unaligned::default();
115     assert_eq!(0_u64, unsafe { transmute_copy(&u.b) });
116 }
117
118 #[test]
119 #[cfg(panic = "unwind")]
120 fn test_transmute_copy_grow_panics() {
121     use std::panic;
122
123     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe {
124         let _unused: u64 = transmute_copy(&1_u8);
125     }));
126
127     match err {
128         Ok(_) => unreachable!(),
129         Err(payload) => {
130             payload
131                 .downcast::<&'static str>()
132                 .and_then(|s| {
133                     if *s == "cannot transmute_copy if U is larger than T" { Ok(s) } else { Err(s) }
134                 })
135                 .unwrap_or_else(|p| panic::resume_unwind(p));
136         }
137     }
138 }
139
140 #[test]
141 #[allow(dead_code)]
142 fn test_discriminant_send_sync() {
143     enum Regular {
144         A,
145         B(i32),
146     }
147     enum NotSendSync {
148         A(*const i32),
149     }
150
151     fn is_send_sync<T: Send + Sync>() {}
152
153     is_send_sync::<Discriminant<Regular>>();
154     is_send_sync::<Discriminant<NotSendSync>>();
155 }
156
157 #[test]
158 fn assume_init_good() {
159     const TRUE: bool = unsafe { MaybeUninit::<bool>::new(true).assume_init() };
160
161     assert!(TRUE);
162 }
163
164 #[test]
165 fn uninit_array_assume_init() {
166     let mut array: [MaybeUninit<i16>; 5] = MaybeUninit::uninit_array();
167     array[0].write(3);
168     array[1].write(1);
169     array[2].write(4);
170     array[3].write(1);
171     array[4].write(5);
172
173     let array = unsafe { MaybeUninit::array_assume_init(array) };
174
175     assert_eq!(array, [3, 1, 4, 1, 5]);
176
177     let [] = unsafe { MaybeUninit::<!>::array_assume_init([]) };
178 }
179
180 #[test]
181 fn uninit_write_slice() {
182     let mut dst = [MaybeUninit::new(255); 64];
183     let src = [0; 64];
184
185     assert_eq!(MaybeUninit::write_slice(&mut dst, &src), &src);
186 }
187
188 #[test]
189 #[should_panic(expected = "source slice length (32) does not match destination slice length (64)")]
190 fn uninit_write_slice_panic_lt() {
191     let mut dst = [MaybeUninit::uninit(); 64];
192     let src = [0; 32];
193
194     MaybeUninit::write_slice(&mut dst, &src);
195 }
196
197 #[test]
198 #[should_panic(expected = "source slice length (128) does not match destination slice length (64)")]
199 fn uninit_write_slice_panic_gt() {
200     let mut dst = [MaybeUninit::uninit(); 64];
201     let src = [0; 128];
202
203     MaybeUninit::write_slice(&mut dst, &src);
204 }
205
206 #[test]
207 fn uninit_clone_from_slice() {
208     let mut dst = [MaybeUninit::new(255); 64];
209     let src = [0; 64];
210
211     assert_eq!(MaybeUninit::write_slice_cloned(&mut dst, &src), &src);
212 }
213
214 #[test]
215 #[should_panic(expected = "destination and source slices have different lengths")]
216 fn uninit_write_slice_cloned_panic_lt() {
217     let mut dst = [MaybeUninit::uninit(); 64];
218     let src = [0; 32];
219
220     MaybeUninit::write_slice_cloned(&mut dst, &src);
221 }
222
223 #[test]
224 #[should_panic(expected = "destination and source slices have different lengths")]
225 fn uninit_write_slice_cloned_panic_gt() {
226     let mut dst = [MaybeUninit::uninit(); 64];
227     let src = [0; 128];
228
229     MaybeUninit::write_slice_cloned(&mut dst, &src);
230 }
231
232 #[test]
233 #[cfg(panic = "unwind")]
234 fn uninit_write_slice_cloned_mid_panic() {
235     use std::panic;
236
237     enum IncrementOrPanic {
238         Increment(Rc<()>),
239         ExpectedPanic,
240         UnexpectedPanic,
241     }
242
243     impl Clone for IncrementOrPanic {
244         fn clone(&self) -> Self {
245             match self {
246                 Self::Increment(rc) => Self::Increment(rc.clone()),
247                 Self::ExpectedPanic => panic!("expected panic on clone"),
248                 Self::UnexpectedPanic => panic!("unexpected panic on clone"),
249             }
250         }
251     }
252
253     let rc = Rc::new(());
254
255     let mut dst = [
256         MaybeUninit::uninit(),
257         MaybeUninit::uninit(),
258         MaybeUninit::uninit(),
259         MaybeUninit::uninit(),
260     ];
261
262     let src = [
263         IncrementOrPanic::Increment(rc.clone()),
264         IncrementOrPanic::Increment(rc.clone()),
265         IncrementOrPanic::ExpectedPanic,
266         IncrementOrPanic::UnexpectedPanic,
267     ];
268
269     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
270         MaybeUninit::write_slice_cloned(&mut dst, &src);
271     }));
272
273     drop(src);
274
275     match err {
276         Ok(_) => unreachable!(),
277         Err(payload) => {
278             payload
279                 .downcast::<&'static str>()
280                 .and_then(|s| if *s == "expected panic on clone" { Ok(s) } else { Err(s) })
281                 .unwrap_or_else(|p| panic::resume_unwind(p));
282
283             assert_eq!(Rc::strong_count(&rc), 1)
284         }
285     }
286 }
287
288 #[test]
289 fn uninit_write_slice_cloned_no_drop() {
290     #[derive(Clone)]
291     struct Bomb;
292
293     impl Drop for Bomb {
294         fn drop(&mut self) {
295             panic!("dropped a bomb! kaboom")
296         }
297     }
298
299     let mut dst = [MaybeUninit::uninit()];
300     let src = [Bomb];
301
302     MaybeUninit::write_slice_cloned(&mut dst, &src);
303
304     forget(src);
305 }
306
307 #[test]
308 fn uninit_const_assume_init_read() {
309     const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
310     assert_eq!(FOO, 42);
311 }
312
313 #[test]
314 fn const_maybe_uninit() {
315     use std::ptr;
316
317     #[derive(Debug, PartialEq)]
318     struct Foo {
319         x: u8,
320         y: u8,
321     }
322
323     const FIELD_BY_FIELD: Foo = unsafe {
324         let mut val = MaybeUninit::uninit();
325         init_y(&mut val); // order shouldn't matter
326         init_x(&mut val);
327         val.assume_init()
328     };
329
330     const fn init_x(foo: &mut MaybeUninit<Foo>) {
331         unsafe {
332             *ptr::addr_of_mut!((*foo.as_mut_ptr()).x) = 1;
333         }
334     }
335
336     const fn init_y(foo: &mut MaybeUninit<Foo>) {
337         unsafe {
338             *ptr::addr_of_mut!((*foo.as_mut_ptr()).y) = 2;
339         }
340     }
341
342     assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 });
343 }