@@ -64,6 +64,31 @@ enum ZeroIsValid {
6464 One ( NonNull < ( ) > ) = 1 ,
6565}
6666
67+ #[ rustfmt:: skip]
68+ #[ allow( dead_code) ]
69+ enum SoManyVariants {
70+ A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9 , A10 , A11 , A12 , A13 , A14 , A15 , A16 , A17 ,
71+ A18 , A19 , A20 , A21 , A22 , A23 , A24 , A25 , A26 , A27 , A28 , A29 , A30 , A31 , A32 ,
72+ A33 , A34 , A35 , A36 , A37 , A38 , A39 , A40 , A41 , A42 , A43 , A44 , A45 , A46 , A47 ,
73+ A48 , A49 , A50 , A51 , A52 , A53 , A54 , A55 , A56 , A57 , A58 , A59 , A60 , A61 , A62 ,
74+ A63 , A64 , A65 , A66 , A67 , A68 , A69 , A70 , A71 , A72 , A73 , A74 , A75 , A76 , A77 ,
75+ A78 , A79 , A80 , A81 , A82 , A83 , A84 , A85 , A86 , A87 , A88 , A89 , A90 , A91 , A92 ,
76+ A93 , A94 , A95 , A96 , A97 , A98 , A99 , A100 , A101 , A102 , A103 , A104 , A105 , A106 ,
77+ A107 , A108 , A109 , A110 , A111 , A112 , A113 , A114 , A115 , A116 , A117 , A118 , A119 ,
78+ A120 , A121 , A122 , A123 , A124 , A125 , A126 , A127 , A128 , A129 , A130 , A131 , A132 ,
79+ A133 , A134 , A135 , A136 , A137 , A138 , A139 , A140 , A141 , A142 , A143 , A144 , A145 ,
80+ A146 , A147 , A148 , A149 , A150 , A151 , A152 , A153 , A154 , A155 , A156 , A157 , A158 ,
81+ A159 , A160 , A161 , A162 , A163 , A164 , A165 , A166 , A167 , A168 , A169 , A170 , A171 ,
82+ A172 , A173 , A174 , A175 , A176 , A177 , A178 , A179 , A180 , A181 , A182 , A183 , A184 ,
83+ A185 , A186 , A187 , A188 , A189 , A190 , A191 , A192 , A193 , A194 , A195 , A196 , A197 ,
84+ A198 , A199 , A200 , A201 , A202 , A203 , A204 , A205 , A206 , A207 , A208 , A209 , A210 ,
85+ A211 , A212 , A213 , A214 , A215 , A216 , A217 , A218 , A219 , A220 , A221 , A222 , A223 ,
86+ A224 , A225 , A226 , A227 , A228 , A229 , A230 , A231 , A232 , A233 , A234 , A235 , A236 ,
87+ A237 , A238 , A239 , A240 , A241 , A242 , A243 , A244 , A245 , A246 , A247 , A248 , A249 ,
88+ A250 , A251 , A252 , A253 , A254 , A255 , A256 ,
89+ }
90+
91+ #[ track_caller]
6792fn test_panic_msg < T > ( op : impl ( FnOnce ( ) -> T ) + panic:: UnwindSafe , msg : & str ) {
6893 let err = panic:: catch_unwind ( op) . err ( ) ;
6994 assert_eq ! (
@@ -72,6 +97,19 @@ fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
7297 ) ;
7398}
7499
100+ #[ track_caller]
101+ // If strict mode is enabled, expect the msg. Otherwise, expect there to be no error.
102+ fn test_strict_panic_msg < T > ( op : impl ( FnOnce ( ) -> T ) + panic:: UnwindSafe , msg : & str ) {
103+ let err = panic:: catch_unwind ( op) . err ( ) ;
104+
105+ let expectation = if cfg ! ( strict) { Some ( & msg) } else { None } ;
106+
107+ assert_eq ! (
108+ err. as_ref( ) . and_then( |a| a. downcast_ref:: <& str >( ) ) ,
109+ expectation
110+ ) ;
111+ }
112+
75113fn main ( ) {
76114 unsafe {
77115 // Uninhabited types
@@ -221,6 +259,67 @@ fn main() {
221259 "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
222260 ) ;
223261
262+ test_panic_msg (
263+ || mem:: uninitialized :: < & ' static [ u8 ] > ( ) ,
264+ "attempted to leave type `&[u8]` uninitialized, which is invalid"
265+ ) ;
266+
267+ test_panic_msg (
268+ || mem:: uninitialized :: < & ' static [ u16 ] > ( ) ,
269+ "attempted to leave type `&[u16]` uninitialized, which is invalid"
270+ ) ;
271+
272+ test_panic_msg (
273+ || mem:: uninitialized :: < SoManyVariants > ( ) ,
274+ "attempted to leave type `SoManyVariants` uninitialized, which is invalid"
275+ ) ;
276+
277+ test_panic_msg (
278+ || mem:: zeroed :: < [ ( & ' static [ u8 ] , & ' static str ) ; 1 ] > ( ) ,
279+ "attempted to zero-initialize type `[(&[u8], &str); 1]`, which is invalid"
280+ ) ;
281+
282+ test_panic_msg (
283+ || mem:: uninitialized :: < [ & ' static [ u16 ] ; 1 ] > ( ) ,
284+ "attempted to leave type `[&[u16]; 1]` uninitialized, which is invalid"
285+ ) ;
286+
287+ test_panic_msg (
288+ || mem:: zeroed :: < [ NonNull < ( ) > ; 1 ] > ( ) ,
289+ "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
290+ ) ;
291+
292+ test_panic_msg (
293+ || mem:: uninitialized :: < [ NonNull < ( ) > ; 1 ] > ( ) ,
294+ "attempted to leave type `[core::ptr::non_null::NonNull<()>; 1]` uninitialized, which is invalid"
295+ ) ;
296+
297+ test_panic_msg (
298+ || mem:: zeroed :: < LR_NonZero > ( ) ,
299+ "attempted to zero-initialize type `LR_NonZero`, which is invalid"
300+ ) ;
301+
302+ test_panic_msg (
303+ || mem:: zeroed :: < [ LR_NonZero ; 1 ] > ( ) ,
304+ "attempted to zero-initialize type `[LR_NonZero; 1]`, which is invalid"
305+ ) ;
306+
307+ test_panic_msg (
308+ || mem:: zeroed :: < [ LR_NonZero ; 1 ] > ( ) ,
309+ "attempted to zero-initialize type `[LR_NonZero; 1]`, which is invalid"
310+ ) ;
311+
312+ test_panic_msg (
313+ || mem:: zeroed :: < ManuallyDrop < LR_NonZero > > ( ) ,
314+ "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
315+ which is invalid"
316+ ) ;
317+
318+ test_panic_msg (
319+ || mem:: uninitialized :: < ( & ' static [ u8 ] , & ' static str ) > ( ) ,
320+ "attempted to leave type `(&[u8], &str)` uninitialized, which is invalid"
321+ ) ;
322+
224323 // Some things that should work.
225324 let _val = mem:: zeroed :: < bool > ( ) ;
226325 let _val = mem:: zeroed :: < LR > ( ) ;
@@ -230,63 +329,34 @@ fn main() {
230329 let _val = mem:: zeroed :: < MaybeUninit < NonNull < u32 > > > ( ) ;
231330 let _val = mem:: zeroed :: < [ !; 0 ] > ( ) ;
232331 let _val = mem:: zeroed :: < ZeroIsValid > ( ) ;
332+ let _val = mem:: zeroed :: < SoManyVariants > ( ) ;
333+ let _val = mem:: uninitialized :: < [ SoManyVariants ; 0 ] > ( ) ;
233334 let _val = mem:: uninitialized :: < MaybeUninit < bool > > ( ) ;
234335 let _val = mem:: uninitialized :: < [ !; 0 ] > ( ) ;
235336 let _val = mem:: uninitialized :: < ( ) > ( ) ;
236337 let _val = mem:: uninitialized :: < ZeroSized > ( ) ;
237338
238- if cfg ! ( strict) {
239- test_panic_msg (
240- || mem:: uninitialized :: < i32 > ( ) ,
241- "attempted to leave type `i32` uninitialized, which is invalid"
242- ) ;
243-
244- test_panic_msg (
245- || mem:: uninitialized :: < * const ( ) > ( ) ,
246- "attempted to leave type `*const ()` uninitialized, which is invalid"
247- ) ;
248-
249- test_panic_msg (
250- || mem:: uninitialized :: < [ i32 ; 1 ] > ( ) ,
251- "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
252- ) ;
253-
254- test_panic_msg (
255- || mem:: zeroed :: < NonNull < ( ) > > ( ) ,
256- "attempted to zero-initialize type `core::ptr::non_null::NonNull<()>`, which is invalid"
257- ) ;
258-
259- test_panic_msg (
260- || mem:: zeroed :: < [ NonNull < ( ) > ; 1 ] > ( ) ,
261- "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
262- ) ;
263-
264- // FIXME(#66151) we conservatively do not error here yet (by default).
265- test_panic_msg (
266- || mem:: zeroed :: < LR_NonZero > ( ) ,
267- "attempted to zero-initialize type `LR_NonZero`, which is invalid"
268- ) ;
269-
270- test_panic_msg (
271- || mem:: zeroed :: < ManuallyDrop < LR_NonZero > > ( ) ,
272- "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
273- which is invalid"
274- ) ;
275- } else {
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 ( ) > ( ) ;
281-
282- // These are UB, but best to test them to ensure we don't become unintentionally
283- // stricter.
284-
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 ] > ( ) ;
290- }
339+ // These are UB because they have not been officially blessed, but we await the resolution
340+ // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
341+ // anything about that.
342+ test_strict_panic_msg (
343+ || mem:: uninitialized :: < i32 > ( ) ,
344+ "attempted to leave type `i32` uninitialized, which is invalid"
345+ ) ;
346+
347+ test_strict_panic_msg (
348+ || mem:: uninitialized :: < * const ( ) > ( ) ,
349+ "attempted to leave type `*const ()` uninitialized, which is invalid"
350+ ) ;
351+
352+ test_strict_panic_msg (
353+ || mem:: uninitialized :: < [ i32 ; 1 ] > ( ) ,
354+ "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
355+ ) ;
356+
357+ test_strict_panic_msg (
358+ || mem:: uninitialized :: < [ ( & ' static [ u8 ] , & ' static str ) ; 1 ] > ( ) ,
359+ "attempted to leave type `[(&[u8], &str); 1]` uninitialized, which is invalid"
360+ ) ;
291361 }
292362}
0 commit comments