3 // ignore-wasm32-bare compiled with panic=abort by default
5 // [thir]compile-flags: -Zthir-unsafeck
6 // ignore-tidy-linelength
8 // This test checks panic emitted from `mem::{uninitialized,zeroed}`.
10 #![feature(never_type, arbitrary_enum_discriminant)]
11 #![allow(deprecated, invalid_value)]
14 mem::{self, MaybeUninit, ManuallyDrop},
29 enum OneVariant { Variant(i32) }
31 #[allow(dead_code, non_camel_case_types)]
32 enum OneVariant_NonZero {
33 Variant(i32, i32, num::NonZeroI32),
37 // An `Aggregate` abi enum where 0 is not a valid discriminant.
41 Variant1(i32, i32) = 1,
42 Variant2(i32, i32) = 2,
45 // An enum with ScalarPair layout
51 #[allow(dead_code, non_camel_case_types)]
53 Left(num::NonZeroI64),
54 Right(num::NonZeroI64),
57 fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
58 let err = panic::catch_unwind(op).err();
60 err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
69 || mem::uninitialized::<!>(),
70 "attempted to instantiate uninhabited type `!`"
73 || mem::zeroed::<!>(),
74 "attempted to instantiate uninhabited type `!`"
77 || MaybeUninit::<!>::uninit().assume_init(),
78 "attempted to instantiate uninhabited type `!`"
82 || mem::uninitialized::<Foo>(),
83 "attempted to instantiate uninhabited type `Foo`"
86 || mem::zeroed::<Foo>(),
87 "attempted to instantiate uninhabited type `Foo`"
90 || MaybeUninit::<Foo>::uninit().assume_init(),
91 "attempted to instantiate uninhabited type `Foo`"
95 || mem::uninitialized::<Bar>(),
96 "attempted to instantiate uninhabited type `Bar`"
99 || mem::zeroed::<Bar>(),
100 "attempted to instantiate uninhabited type `Bar`"
103 || MaybeUninit::<Bar>::uninit().assume_init(),
104 "attempted to instantiate uninhabited type `Bar`"
107 // Types that do not like zero-initialziation
109 || mem::uninitialized::<fn()>(),
110 "attempted to leave type `fn()` uninitialized, which is invalid"
113 || mem::zeroed::<fn()>(),
114 "attempted to zero-initialize type `fn()`, which is invalid"
118 || mem::uninitialized::<*const dyn Send>(),
119 "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
122 || mem::zeroed::<*const dyn Send>(),
123 "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
126 /* FIXME(#66151) we conservatively do not error here yet.
128 || mem::uninitialized::<LR_NonZero>(),
129 "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
132 || mem::zeroed::<LR_NonZero>(),
133 "attempted to zero-initialize type `LR_NonZero`, which is invalid"
137 || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
138 "attempted to leave type `std::mem::ManuallyDrop<LR_NonZero>` uninitialized, \
142 || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
143 "attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
149 || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
150 "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
154 || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
155 "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
160 || mem::uninitialized::<OneVariant_NonZero>(),
161 "attempted to leave type `OneVariant_NonZero` uninitialized, \
165 || mem::zeroed::<OneVariant_NonZero>(),
166 "attempted to zero-initialize type `OneVariant_NonZero`, \
171 || mem::uninitialized::<NoNullVariant>(),
172 "attempted to leave type `NoNullVariant` uninitialized, \
176 || mem::zeroed::<NoNullVariant>(),
177 "attempted to zero-initialize type `NoNullVariant`, \
181 // Types that can be zero, but not uninit.
183 || mem::uninitialized::<bool>(),
184 "attempted to leave type `bool` uninitialized, which is invalid"
187 || mem::uninitialized::<LR>(),
188 "attempted to leave type `LR` uninitialized, which is invalid"
191 || mem::uninitialized::<ManuallyDrop<LR>>(),
192 "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
195 // Some things that should work.
196 let _val = mem::zeroed::<bool>();
197 let _val = mem::zeroed::<LR>();
198 let _val = mem::zeroed::<ManuallyDrop<LR>>();
199 let _val = mem::zeroed::<OneVariant>();
200 let _val = mem::zeroed::<Option<&'static i32>>();
201 let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
202 let _val = mem::uninitialized::<MaybeUninit<bool>>();
204 // These are UB because they have not been officially blessed, but we await the resolution
205 // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
206 // anything about that.
207 let _val = mem::uninitialized::<i32>();
208 let _val = mem::uninitialized::<*const ()>();