// compile-flags: -Z print-type-sizes --crate-type=lib // build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. // This file illustrates how niche-filling enums are handled, // modelled after cases like `Option<&u32>`, `Option` and such. // // It uses NonZeroU32 rather than `&_` or `Unique<_>`, because // the test is not set up to deal with target-dependent pointer width. // // It avoids using u64/i64 because on some targets that is only 4-byte // aligned (while on most it is 8-byte aligned) and so the resulting // padding and overall computed sizes can be quite different. #![feature(rustc_attrs)] #![allow(dead_code)] use std::num::NonZeroU32; pub enum MyOption { None, Some(T) } #[rustc_layout_scalar_valid_range_start(0)] #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] pub struct MyNotNegativeOne { _i: i32, } impl Default for MyOption { fn default() -> Self { MyOption::None } } pub enum EmbeddedDiscr { None, Record { pre: u8, val: NonZeroU32, post: u16 }, } impl Default for EmbeddedDiscr { fn default() -> Self { EmbeddedDiscr::None } } #[derive(Default)] pub struct IndirectNonZero { pre: u8, nested: NestedNonZero, post: u16, } pub struct NestedNonZero { pre: u8, val: NonZeroU32, post: u16, } impl Default for NestedNonZero { fn default() -> Self { NestedNonZero { pre: 0, val: unsafe { NonZeroU32::new_unchecked(1) }, post: 0 } } } pub enum Enum4 { One(A), Two(B), Three(C), Four(D) } pub union Union1 { a: A, } pub union Union2 { a: A, b: B, } pub fn test() { let _x: MyOption = Default::default(); let _y: EmbeddedDiscr = Default::default(); let _z: MyOption = Default::default(); let _a: MyOption = Default::default(); let _b: MyOption = Default::default(); let _c: MyOption = Default::default(); let _d: MyOption> = Default::default(); let _e: Enum4<(), char, (), ()> = Enum4::One(()); let _f: Enum4<(), (), bool, ()> = Enum4::One(()); let _g: Enum4<(), (), (), MyOption> = Enum4::One(()); let _h: MyOption = Default::default(); // Unions do not currently participate in niche filling. let _i: MyOption> = Default::default(); // ...even when theoretically possible. let _j: MyOption> = Default::default(); let _k: MyOption> = Default::default(); }