]>
Commit | Line | Data |
---|---|---|
74b04a01 | 1 | #![feature(const_transmute, never_type)] |
a1dfa0c6 XL |
2 | #![allow(const_err)] // make sure we cannot allow away the errors tested here |
3 | ||
74b04a01 | 4 | use std::mem; |
416331ca XL |
5 | |
6 | #[repr(transparent)] | |
7 | #[derive(Copy, Clone)] | |
8 | struct Wrap<T>(T); | |
9 | ||
74b04a01 XL |
10 | #[derive(Copy, Clone)] |
11 | enum Never {} | |
12 | ||
13 | // # simple enum with discriminant 0 | |
14 | ||
b7449926 XL |
15 | #[repr(usize)] |
16 | #[derive(Copy, Clone)] | |
17 | enum Enum { | |
18 | A = 0, | |
19 | } | |
b7449926 | 20 | |
74b04a01 | 21 | const GOOD_ENUM: Enum = unsafe { mem::transmute(0usize) }; |
416331ca | 22 | |
74b04a01 | 23 | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; |
416331ca XL |
24 | //~^ ERROR is undefined behavior |
25 | ||
74b04a01 | 26 | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; |
416331ca XL |
27 | //~^ ERROR is undefined behavior |
28 | ||
74b04a01 | 29 | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; |
a1dfa0c6 | 30 | //~^ ERROR is undefined behavior |
b7449926 | 31 | |
74b04a01 XL |
32 | // # simple enum with discriminant 2 |
33 | ||
a1dfa0c6 | 34 | // (Potentially) invalid enum discriminant |
b7449926 XL |
35 | #[repr(usize)] |
36 | #[derive(Copy, Clone)] | |
37 | enum Enum2 { | |
38 | A = 2, | |
39 | } | |
416331ca | 40 | |
74b04a01 | 41 | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; |
a1dfa0c6 | 42 | //~^ ERROR is undefined behavior |
74b04a01 | 43 | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; |
a1dfa0c6 | 44 | //~^ ERROR is undefined behavior |
74b04a01 XL |
45 | // something wrapping the enum so that we test layout first, not enum |
46 | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; | |
a1dfa0c6 XL |
47 | //~^ ERROR is undefined behavior |
48 | ||
49 | // Undef enum discriminant. | |
74b04a01 XL |
50 | #[repr(C)] |
51 | union MaybeUninit<T: Copy> { | |
52 | uninit: (), | |
53 | init: T, | |
54 | } | |
55 | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; | |
a1dfa0c6 XL |
56 | //~^ ERROR is undefined behavior |
57 | ||
58 | // Pointer value in an enum with a niche that is not just 0. | |
74b04a01 | 59 | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; |
a1dfa0c6 | 60 | //~^ ERROR is undefined behavior |
b7449926 | 61 | |
74b04a01 XL |
62 | // # valid discriminant for uninhabited variant |
63 | ||
64 | // An enum with 3 variants of which some are uninhabited -- so the uninhabited variants *do* | |
65 | // have a discriminant. | |
66 | enum UninhDiscriminant { | |
67 | A, | |
68 | B(!), | |
69 | C, | |
70 | D(Never), | |
71 | } | |
72 | ||
73 | const GOOD_INHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(0u8) }; // variant A | |
74 | const GOOD_INHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(2u8) }; // variant C | |
75 | ||
76 | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; | |
77 | //~^ ERROR is undefined behavior | |
78 | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; | |
79 | //~^ ERROR is undefined behavior | |
80 | ||
81 | // # other | |
82 | ||
a1dfa0c6 | 83 | // Invalid enum field content (mostly to test printing of paths for enum tuple |
b7449926 | 84 | // variants and tuples). |
b7449926 | 85 | // Need to create something which does not clash with enum layout optimizations. |
74b04a01 XL |
86 | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); |
87 | //~^ ERROR is undefined behavior | |
88 | ||
89 | // All variants are uninhabited but also have data. | |
90 | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(1u64) }; | |
91 | //~^ ERROR is undefined behavior | |
92 | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(1u64) }; | |
a1dfa0c6 | 93 | //~^ ERROR is undefined behavior |
b7449926 XL |
94 | |
95 | fn main() { | |
96 | } |