3 // ignore-wasm32-bare compiled with panic=abort by default
4 // revisions: mir thir strict
5 // [thir]compile-flags: -Zthir-unsafeck
6 // [strict]compile-flags: -Zstrict-init-checks
7 // ignore-tidy-linelength
9 // This test checks panic emitted from `mem::{uninitialized,zeroed}`.
11 #![feature(never_type, arbitrary_enum_discriminant)]
12 #![allow(deprecated, invalid_value)]
15 mem::{self, MaybeUninit, ManuallyDrop},
30 enum OneVariant { Variant(i32) }
32 #[allow(dead_code, non_camel_case_types)]
33 enum OneVariant_NonZero {
34 Variant(i32, i32, num::NonZeroI32),
38 // An `Aggregate` abi enum where 0 is not a valid discriminant.
42 Variant1(i32, i32) = 1,
43 Variant2(i32, i32) = 2,
46 // An enum with ScalarPair layout
52 #[allow(dead_code, non_camel_case_types)]
54 Left(num::NonZeroI64),
55 Right(num::NonZeroI64),
67 fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
68 let err = panic::catch_unwind(op).err();
70 err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
79 || mem::uninitialized::<!>(),
80 "attempted to instantiate uninhabited type `!`"
83 || mem::zeroed::<!>(),
84 "attempted to instantiate uninhabited type `!`"
87 || MaybeUninit::<!>::uninit().assume_init(),
88 "attempted to instantiate uninhabited type `!`"
92 || mem::uninitialized::<Foo>(),
93 "attempted to instantiate uninhabited type `Foo`"
96 || mem::zeroed::<Foo>(),
97 "attempted to instantiate uninhabited type `Foo`"
100 || MaybeUninit::<Foo>::uninit().assume_init(),
101 "attempted to instantiate uninhabited type `Foo`"
105 || mem::uninitialized::<Bar>(),
106 "attempted to instantiate uninhabited type `Bar`"
109 || mem::zeroed::<Bar>(),
110 "attempted to instantiate uninhabited type `Bar`"
113 || MaybeUninit::<Bar>::uninit().assume_init(),
114 "attempted to instantiate uninhabited type `Bar`"
118 || mem::uninitialized::<[Foo; 2]>(),
119 "attempted to instantiate uninhabited type `[Foo; 2]`"
122 || mem::zeroed::<[Foo; 2]>(),
123 "attempted to instantiate uninhabited type `[Foo; 2]`"
126 || MaybeUninit::<[Foo; 2]>::uninit().assume_init(),
127 "attempted to instantiate uninhabited type `[Foo; 2]`"
131 || mem::uninitialized::<[Bar; 2]>(),
132 "attempted to instantiate uninhabited type `[Bar; 2]`"
135 || mem::zeroed::<[Bar; 2]>(),
136 "attempted to instantiate uninhabited type `[Bar; 2]`"
139 || MaybeUninit::<[Bar; 2]>::uninit().assume_init(),
140 "attempted to instantiate uninhabited type `[Bar; 2]`"
143 // Types that do not like zero-initialziation
145 || mem::uninitialized::<fn()>(),
146 "attempted to leave type `fn()` uninitialized, which is invalid"
149 || mem::zeroed::<fn()>(),
150 "attempted to zero-initialize type `fn()`, which is invalid"
154 || mem::uninitialized::<*const dyn Send>(),
155 "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
158 || mem::zeroed::<*const dyn Send>(),
159 "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
163 || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
164 "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
169 || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
170 "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
175 || mem::uninitialized::<OneVariant_NonZero>(),
176 "attempted to leave type `OneVariant_NonZero` uninitialized, \
180 || mem::zeroed::<OneVariant_NonZero>(),
181 "attempted to zero-initialize type `OneVariant_NonZero`, \
186 || mem::uninitialized::<LR_NonZero>(),
187 "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
191 || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
192 "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>` uninitialized, \
197 || mem::uninitialized::<NoNullVariant>(),
198 "attempted to leave type `NoNullVariant` uninitialized, \
203 || mem::zeroed::<NoNullVariant>(),
204 "attempted to zero-initialize type `NoNullVariant`, \
208 // Types that can be zero, but not uninit.
210 || mem::uninitialized::<bool>(),
211 "attempted to leave type `bool` uninitialized, which is invalid"
215 || mem::uninitialized::<LR>(),
216 "attempted to leave type `LR` uninitialized, which is invalid"
220 || mem::uninitialized::<ManuallyDrop<LR>>(),
221 "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
224 // Some things that should work.
225 let _val = mem::zeroed::<bool>();
226 let _val = mem::zeroed::<LR>();
227 let _val = mem::zeroed::<ManuallyDrop<LR>>();
228 let _val = mem::zeroed::<OneVariant>();
229 let _val = mem::zeroed::<Option<&'static i32>>();
230 let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
231 let _val = mem::zeroed::<[!; 0]>();
232 let _val = mem::zeroed::<ZeroIsValid>();
233 let _val = mem::uninitialized::<MaybeUninit<bool>>();
234 let _val = mem::uninitialized::<[!; 0]>();
235 let _val = mem::uninitialized::<()>();
236 let _val = mem::uninitialized::<ZeroSized>();
240 || mem::uninitialized::<i32>(),
241 "attempted to leave type `i32` uninitialized, which is invalid"
245 || mem::uninitialized::<*const ()>(),
246 "attempted to leave type `*const ()` uninitialized, which is invalid"
250 || mem::uninitialized::<[i32; 1]>(),
251 "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
255 || mem::zeroed::<NonNull<()>>(),
256 "attempted to zero-initialize type `core::ptr::non_null::NonNull<()>`, which is invalid"
260 || mem::zeroed::<[NonNull<()>; 1]>(),
261 "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
264 // FIXME(#66151) we conservatively do not error here yet (by default).
266 || mem::zeroed::<LR_NonZero>(),
267 "attempted to zero-initialize type `LR_NonZero`, which is invalid"
271 || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
272 "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
276 // These are UB because they have not been officially blessed, but we await the resolution
277 // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
278 // anything about that.
279 let _val = mem::uninitialized::<i32>();
280 let _val = mem::uninitialized::<*const ()>();
282 // These are UB, but best to test them to ensure we don't become unintentionally
285 // It's currently unchecked to create invalid enums and values inside arrays.
286 let _val = mem::zeroed::<LR_NonZero>();
287 let _val = mem::zeroed::<[LR_NonZero; 1]>();
288 let _val = mem::zeroed::<[NonNull<()>; 1]>();
289 let _val = mem::uninitialized::<[NonNull<()>; 1]>();