1 // compile-flags: -Z print-type-sizes --crate-type=lib
4 // ^-- needed because `--pass check` does not emit the output needed.
5 // FIXME: consider using an attribute instead of side-effects.
7 // This file illustrates how niche-filling enums are handled,
8 // modelled after cases like `Option<&u32>`, `Option<bool>` and such.
10 // It uses NonZeroU32 rather than `&_` or `Unique<_>`, because
11 // the test is not set up to deal with target-dependent pointer width.
13 // It avoids using u64/i64 because on some targets that is only 4-byte
14 // aligned (while on most it is 8-byte aligned) and so the resulting
15 // padding and overall computed sizes can be quite different.
17 #![feature(rustc_attrs)]
20 use std::num::NonZeroU32;
22 pub enum MyOption<T> { None, Some(T) }
24 #[rustc_layout_scalar_valid_range_start(0)]
25 #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
26 pub struct MyNotNegativeOne {
30 impl<T> Default for MyOption<T> {
31 fn default() -> Self { MyOption::None }
34 pub enum EmbeddedDiscr {
36 Record { pre: u8, val: NonZeroU32, post: u16 },
39 impl Default for EmbeddedDiscr {
40 fn default() -> Self { EmbeddedDiscr::None }
44 pub struct IndirectNonZero {
46 nested: NestedNonZero,
50 pub struct NestedNonZero {
56 impl Default for NestedNonZero {
57 fn default() -> Self {
58 NestedNonZero { pre: 0, val: unsafe { NonZeroU32::new_unchecked(1) }, post: 0 }
62 pub enum Enum4<A, B, C, D> {
69 pub union Union1<A: Copy> {
73 pub union Union2<A: Copy, B: Copy> {
79 let _x: MyOption<NonZeroU32> = Default::default();
80 let _y: EmbeddedDiscr = Default::default();
81 let _z: MyOption<IndirectNonZero> = Default::default();
82 let _a: MyOption<bool> = Default::default();
83 let _b: MyOption<char> = Default::default();
84 let _c: MyOption<std::cmp::Ordering> = Default::default();
85 let _d: MyOption<MyOption<u8>> = Default::default();
86 let _e: Enum4<(), char, (), ()> = Enum4::One(());
87 let _f: Enum4<(), (), bool, ()> = Enum4::One(());
88 let _g: Enum4<(), (), (), MyOption<u8>> = Enum4::One(());
89 let _h: MyOption<MyNotNegativeOne> = Default::default();
91 // Unions do not currently participate in niche filling.
92 let _i: MyOption<Union2<NonZeroU32, u32>> = Default::default();
94 // ...even when theoretically possible.
95 let _j: MyOption<Union1<NonZeroU32>> = Default::default();
96 let _k: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();