]> git.lizzy.rs Git - rust.git/blob - library/core/tests/mem.rs
Rollup merge of #85912 - LingMan:iter_any, r=nagisa
[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 // Remove this test when `std::raw` is removed.
101 // The replacement pointer metadata APIs are tested in library/core/tests/ptr.rs
102 #[allow(deprecated)]
103 #[test]
104 fn test_transmute() {
105     trait Foo {
106         fn dummy(&self) {}
107     }
108     impl Foo for isize {}
109
110     let a = box 100isize as Box<dyn Foo>;
111     unsafe {
112         let x: ::core::raw::TraitObject = transmute(a);
113         assert!(*(x.data as *const isize) == 100);
114         let _x: Box<dyn Foo> = transmute(x);
115     }
116
117     unsafe {
118         assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
119     }
120 }
121
122 #[test]
123 #[allow(dead_code)]
124 fn test_discriminant_send_sync() {
125     enum Regular {
126         A,
127         B(i32),
128     }
129     enum NotSendSync {
130         A(*const i32),
131     }
132
133     fn is_send_sync<T: Send + Sync>() {}
134
135     is_send_sync::<Discriminant<Regular>>();
136     is_send_sync::<Discriminant<NotSendSync>>();
137 }
138
139 #[test]
140 fn assume_init_good() {
141     const TRUE: bool = unsafe { MaybeUninit::<bool>::new(true).assume_init() };
142
143     assert!(TRUE);
144 }
145
146 #[test]
147 fn uninit_array_assume_init() {
148     let mut array: [MaybeUninit<i16>; 5] = MaybeUninit::uninit_array();
149     array[0].write(3);
150     array[1].write(1);
151     array[2].write(4);
152     array[3].write(1);
153     array[4].write(5);
154
155     let array = unsafe { MaybeUninit::array_assume_init(array) };
156
157     assert_eq!(array, [3, 1, 4, 1, 5]);
158
159     let [] = unsafe { MaybeUninit::<!>::array_assume_init([]) };
160 }
161
162 #[test]
163 fn uninit_write_slice() {
164     let mut dst = [MaybeUninit::new(255); 64];
165     let src = [0; 64];
166
167     assert_eq!(MaybeUninit::write_slice(&mut dst, &src), &src);
168 }
169
170 #[test]
171 #[should_panic(expected = "source slice length (32) does not match destination slice length (64)")]
172 fn uninit_write_slice_panic_lt() {
173     let mut dst = [MaybeUninit::uninit(); 64];
174     let src = [0; 32];
175
176     MaybeUninit::write_slice(&mut dst, &src);
177 }
178
179 #[test]
180 #[should_panic(expected = "source slice length (128) does not match destination slice length (64)")]
181 fn uninit_write_slice_panic_gt() {
182     let mut dst = [MaybeUninit::uninit(); 64];
183     let src = [0; 128];
184
185     MaybeUninit::write_slice(&mut dst, &src);
186 }
187
188 #[test]
189 fn uninit_clone_from_slice() {
190     let mut dst = [MaybeUninit::new(255); 64];
191     let src = [0; 64];
192
193     assert_eq!(MaybeUninit::write_slice_cloned(&mut dst, &src), &src);
194 }
195
196 #[test]
197 #[should_panic(expected = "destination and source slices have different lengths")]
198 fn uninit_write_slice_cloned_panic_lt() {
199     let mut dst = [MaybeUninit::uninit(); 64];
200     let src = [0; 32];
201
202     MaybeUninit::write_slice_cloned(&mut dst, &src);
203 }
204
205 #[test]
206 #[should_panic(expected = "destination and source slices have different lengths")]
207 fn uninit_write_slice_cloned_panic_gt() {
208     let mut dst = [MaybeUninit::uninit(); 64];
209     let src = [0; 128];
210
211     MaybeUninit::write_slice_cloned(&mut dst, &src);
212 }
213
214 #[test]
215 #[cfg(panic = "unwind")]
216 fn uninit_write_slice_cloned_mid_panic() {
217     use std::panic;
218
219     enum IncrementOrPanic {
220         Increment(Rc<()>),
221         ExpectedPanic,
222         UnexpectedPanic,
223     }
224
225     impl Clone for IncrementOrPanic {
226         fn clone(&self) -> Self {
227             match self {
228                 Self::Increment(rc) => Self::Increment(rc.clone()),
229                 Self::ExpectedPanic => panic!("expected panic on clone"),
230                 Self::UnexpectedPanic => panic!("unexpected panic on clone"),
231             }
232         }
233     }
234
235     let rc = Rc::new(());
236
237     let mut dst = [
238         MaybeUninit::uninit(),
239         MaybeUninit::uninit(),
240         MaybeUninit::uninit(),
241         MaybeUninit::uninit(),
242     ];
243
244     let src = [
245         IncrementOrPanic::Increment(rc.clone()),
246         IncrementOrPanic::Increment(rc.clone()),
247         IncrementOrPanic::ExpectedPanic,
248         IncrementOrPanic::UnexpectedPanic,
249     ];
250
251     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
252         MaybeUninit::write_slice_cloned(&mut dst, &src);
253     }));
254
255     drop(src);
256
257     match err {
258         Ok(_) => unreachable!(),
259         Err(payload) => {
260             payload
261                 .downcast::<&'static str>()
262                 .and_then(|s| if *s == "expected panic on clone" { Ok(s) } else { Err(s) })
263                 .unwrap_or_else(|p| panic::resume_unwind(p));
264
265             assert_eq!(Rc::strong_count(&rc), 1)
266         }
267     }
268 }
269
270 #[test]
271 fn uninit_write_slice_cloned_no_drop() {
272     #[derive(Clone)]
273     struct Bomb;
274
275     impl Drop for Bomb {
276         fn drop(&mut self) {
277             panic!("dropped a bomb! kaboom")
278         }
279     }
280
281     let mut dst = [MaybeUninit::uninit()];
282     let src = [Bomb];
283
284     MaybeUninit::write_slice_cloned(&mut dst, &src);
285
286     forget(src);
287 }
288
289 #[test]
290 fn uninit_const_assume_init_read() {
291     const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
292     assert_eq!(FOO, 42);
293 }