From a1d11bc4d0400bccac063b091c1bade3e5ef4b8d Mon Sep 17 00:00:00 2001 From: James Miller Date: Mon, 22 Dec 2014 15:58:52 +1300 Subject: [PATCH 1/2] Make single-variant "c-like" enums have no size. This makes an enum like `enum Foo { Foo }` be zero-sized. If a discriminant is set to non-zero, it still treats it as a c-like enum. Fixes #15747 --- src/librustc_trans/trans/adt.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index f7edb281b9eda..7a17a0e635ae5 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -190,6 +190,17 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, dtor); } + if cases.len() == 1 && cases[0].discr == 0 { + // Equivalent to a struct/tuple/newtype. + // (Typechecking will reject discriminant-sizing attrs.) + assert_eq!(hint, attr::ReprAny); + let mut ftys = cases[0].tys.clone(); + if dtor { ftys.push(ty::mk_bool()); } + return Univariant(mk_struct(cx, ftys.as_slice(), false, t), + dtor); + } + + if !dtor && cases.iter().all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs: Vec = cases.iter().map(|c| c.discr).collect(); @@ -212,16 +223,6 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, def_id)).as_slice()); } - if cases.len() == 1 { - // Equivalent to a struct/tuple/newtype. - // (Typechecking will reject discriminant-sizing attrs.) - assert_eq!(hint, attr::ReprAny); - let mut ftys = cases[0].tys.clone(); - if dtor { ftys.push(ty::mk_bool()); } - return Univariant(mk_struct(cx, ftys.as_slice(), false, t), - dtor); - } - if !dtor && cases.len() == 2 && hint == attr::ReprAny { // Nullable pointer optimization let mut discr = 0; From 98ae8ade887a52b5ebddf82ff5acebeb2a4a1732 Mon Sep 17 00:00:00 2001 From: James Miller Date: Mon, 22 Dec 2014 16:59:46 +1300 Subject: [PATCH 2/2] Add test for univariant enum size --- src/test/run-pass/type-sizes.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/run-pass/type-sizes.rs b/src/test/run-pass/type-sizes.rs index 2596bc9c83763..7bb2e78980daa 100644 --- a/src/test/run-pass/type-sizes.rs +++ b/src/test/run-pass/type-sizes.rs @@ -18,6 +18,14 @@ struct w {a: int, b: ()} struct x {a: int, b: (), c: ()} struct y {x: int} +enum c1 { + c1 +} + +enum c2 { + c2 = 1 +} + pub fn main() { assert_eq!(size_of::(), 1 as uint); assert_eq!(size_of::(), 4 as uint); @@ -34,4 +42,8 @@ pub fn main() { assert_eq!(size_of::(), size_of::()); assert_eq!(size_of::(), size_of::()); assert_eq!(size_of::(), size_of::()); + + // Make sure enum sizes are correct + assert_eq!(size_of::(), 0 as uint); + assert_eq!(size_of::(), 1 as uint); }