diff --git a/src/doc/reference.md b/src/doc/reference.md index 21e9be59ebbdf..57c0f2da185fa 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1892,12 +1892,13 @@ interpreted: On `enum`s: -- `repr` - on C-like enums, this sets the underlying type used for - representation. Takes one argument, which is the primitive - type this enum should be represented for, or `C`, which specifies that it - should be the default `enum` size of the C ABI for that platform. Note that - enum representation in C is undefined, and this may be incorrect when the C - code is compiled with certain flags. +- `repr` - this sets the underlying type used for representation of the + discriminant. Takes one argument, which is the primitive type this enum + should be represented as, or `C`, which specifies that it should be the + default `enum` size of the C ABI for that platform. Note that enum + representation in C is implementation defined, and this may be incorrect when + the C code is compiled with certain flags. The representation attribute + inhibits elision of the enum discriminant in layout optimizations. On `struct`s: diff --git a/src/test/run-pass/enum-discrim-manual-sizing-2.rs b/src/test/run-pass/enum-discrim-manual-sizing-2.rs new file mode 100644 index 0000000000000..0470a9e19d580 --- /dev/null +++ b/src/test/run-pass/enum-discrim-manual-sizing-2.rs @@ -0,0 +1,107 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that explicit discriminant sizing inhibits the non-nullable pointer +// optimization in enum layout. + +use std::mem::size_of; + +#[repr(i8)] +enum Ei8 { + _None, + _Some(T), +} + +#[repr(u8)] +enum Eu8 { + _None, + _Some(T), +} + +#[repr(i16)] +enum Ei16 { + _None, + _Some(T), +} + +#[repr(u16)] +enum Eu16 { + _None, + _Some(T), +} + +#[repr(i32)] +enum Ei32 { + _None, + _Some(T), +} + +#[repr(u32)] +enum Eu32 { + _None, + _Some(T), +} + +#[repr(i64)] +enum Ei64 { + _None, + _Some(T), +} + +#[repr(u64)] +enum Eu64 { + _None, + _Some(T), +} + +#[repr(isize)] +enum Eint { + _None, + _Some(T), +} + +#[repr(usize)] +enum Euint { + _None, + _Some(T), +} + +#[repr(C)] +enum EC { + _None, + _Some(T), +} + +pub fn main() { + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), size_of::()); + assert_eq!(size_of::>(), size_of::()); + + let ptrsize = size_of::<&i32>(); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + + assert!(size_of::>() > ptrsize); +}