diff --git a/src/test/run-pass/union/union-nonzero.rs b/src/test/run-pass/union/union-nonzero.rs new file mode 100644 index 0000000000000..614aa9ec0ce17 --- /dev/null +++ b/src/test/run-pass/union/union-nonzero.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] + +use std::mem::{size_of, transmute}; + +union U1 { + a: A, +} + +union U2 { + a: A, + b: B, +} + +fn main() { + // Unions do not participate in niche-filling/non-zero optimization... + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + + // ...even when theoretically possible: + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + + // The unused bits of the () variant can have any value. + let zeroed: U2<&u8, ()> = unsafe { transmute(std::ptr::null::()) }; + + if let None = Some(zeroed) { + panic!() + } +} diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index bed1e32a60158..0127261b2b7d0 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -57,6 +57,15 @@ pub enum Enum4 { Four(D) } +pub union Union1 { + a: A, +} + +pub union Union2 { + a: A, + b: B, +} + #[start] fn start(_: isize, _: *const *const u8) -> isize { let _x: MyOption = Default::default(); @@ -69,5 +78,13 @@ fn start(_: isize, _: *const *const u8) -> isize { let _e: Enum4<(), char, (), ()> = Enum4::One(()); let _f: Enum4<(), (), bool, ()> = Enum4::One(()); let _g: Enum4<(), (), (), MyOption> = Enum4::One(()); + + // Unions do not currently participate in niche filling. + let _h: MyOption> = Default::default(); + + // ...even when theoretically possible. + let _i: MyOption> = Default::default(); + let _j: MyOption> = Default::default(); + 0 } diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 9cdb2ae4f57e0..301edc0d086b1 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -14,6 +14,21 @@ print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size variant `None`: 0 bytes print-type-size end padding: 1 bytes +print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes +print-type-size discriminant: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes +print-type-size discriminant: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes +print-type-size type: `MyOption>`: 8 bytes, alignment: 4 bytes +print-type-size discriminant: 4 bytes +print-type-size variant `Some`: 4 bytes +print-type-size field `.0`: 4 bytes +print-type-size variant `None`: 0 bytes print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes @@ -36,6 +51,17 @@ print-type-size type: `MyOption`: 4 bytes, alignment: 4 by print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size variant `None`: 0 bytes +print-type-size type: `Union1`: 4 bytes, alignment: 4 bytes +print-type-size variant `Union1`: 4 bytes +print-type-size field `.a`: 4 bytes +print-type-size type: `Union2`: 4 bytes, alignment: 4 bytes +print-type-size variant `Union2`: 4 bytes +print-type-size field `.a`: 4 bytes +print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes +print-type-size type: `Union2`: 4 bytes, alignment: 4 bytes +print-type-size variant `Union2`: 4 bytes +print-type-size field `.a`: 4 bytes +print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes