]> git.lizzy.rs Git - rust.git/blob - src/test/ui/print_type_sizes/niche-filling.rs
drive-by: Fix path spans
[rust.git] / src / test / ui / print_type_sizes / niche-filling.rs
1 // compile-flags: -Z print-type-sizes
2 // build-pass
3 // ignore-pass
4 // ^-- needed because `--pass check` does not emit the output needed.
5 //     FIXME: consider using an attribute instead of side-effects.
6
7 // This file illustrates how niche-filling enums are handled,
8 // modelled after cases like `Option<&u32>`, `Option<bool>` and such.
9 //
10 // It uses NonZeroU32 rather than `&_` or `Unique<_>`, because
11 // the test is not set up to deal with target-dependent pointer width.
12 //
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.
16
17 #![feature(start)]
18 #![feature(rustc_attrs)]
19 #![allow(dead_code)]
20
21 use std::num::NonZeroU32;
22
23 pub enum MyOption<T> { None, Some(T) }
24
25 #[rustc_layout_scalar_valid_range_start(0)]
26 #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
27 pub struct MyNotNegativeOne {
28   _i: i32,
29 }
30
31 impl<T> Default for MyOption<T> {
32     fn default() -> Self { MyOption::None }
33 }
34
35 pub enum EmbeddedDiscr {
36     None,
37     Record { pre: u8, val: NonZeroU32, post: u16 },
38 }
39
40 impl Default for EmbeddedDiscr {
41     fn default() -> Self { EmbeddedDiscr::None }
42 }
43
44 #[derive(Default)]
45 pub struct IndirectNonZero {
46     pre: u8,
47     nested: NestedNonZero,
48     post: u16,
49 }
50
51 pub struct NestedNonZero {
52     pre: u8,
53     val: NonZeroU32,
54     post: u16,
55 }
56
57 impl Default for NestedNonZero {
58     fn default() -> Self {
59         NestedNonZero { pre: 0, val: NonZeroU32::new(1).unwrap(), post: 0 }
60     }
61 }
62
63 pub enum Enum4<A, B, C, D> {
64     One(A),
65     Two(B),
66     Three(C),
67     Four(D)
68 }
69
70 pub union Union1<A: Copy> {
71     a: A,
72 }
73
74 pub union Union2<A: Copy, B: Copy> {
75     a: A,
76     b: B,
77 }
78
79 #[start]
80 fn start(_: isize, _: *const *const u8) -> isize {
81     let _x: MyOption<NonZeroU32> = Default::default();
82     let _y: EmbeddedDiscr = Default::default();
83     let _z: MyOption<IndirectNonZero> = Default::default();
84     let _a: MyOption<bool> = Default::default();
85     let _b: MyOption<char> = Default::default();
86     let _c: MyOption<std::cmp::Ordering> = Default::default();
87     let _d: MyOption<MyOption<u8>> = Default::default();
88     let _e: Enum4<(), char, (), ()> = Enum4::One(());
89     let _f: Enum4<(), (), bool, ()> = Enum4::One(());
90     let _g: Enum4<(), (), (), MyOption<u8>> = Enum4::One(());
91     let _h: MyOption<MyNotNegativeOne> = Default::default();
92
93     // Unions do not currently participate in niche filling.
94     let _i: MyOption<Union2<NonZeroU32, u32>> = Default::default();
95
96     // ...even when theoretically possible.
97     let _j: MyOption<Union1<NonZeroU32>> = Default::default();
98     let _k: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
99
100     0
101 }