From d009c6330b7d034889b0d720c7abbf940945d885 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Sun, 10 Feb 2013 11:44:47 -0800 Subject: [PATCH 1/2] Make univariant enums act like structs, so that they're aligned correctly. Consts of such enums are aligned correctly, so we could either misalign them to match the type_of, or fix the type_of. The latter seems like a better idea. --- src/librustc/middle/trans/type_of.rs | 15 ++++++++++++--- src/test/run-pass/const-enum-newtype-align.rs | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/const-enum-newtype-align.rs diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index d87674f6b6e84..6be82f833a6ae 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -328,11 +328,20 @@ pub fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { pub fn enum_body_types(cx: @crate_ctxt, did: ast::def_id, t: ty::t) -> ~[TypeRef] { let univar = ty::enum_is_univariant(cx.tcx, did); - let size = machine::static_size_of_enum(cx, t); if !univar { + let size = machine::static_size_of_enum(cx, t); ~[T_enum_discrim(cx), T_array(T_i8(), size)] - } else { - ~[T_array(T_i8(), size)] + } + else { + // Use the actual fields, so we get the alignment right. + match ty::get(t).sty { + ty::ty_enum(_, ref substs) => { + do ty::enum_variants(cx.tcx, did)[0].args.map |&field_ty| { + sizing_type_of(cx, ty::subst(cx.tcx, substs, field_ty)) + } + } + _ => cx.sess.bug(~"enum is not an enum") + } } } diff --git a/src/test/run-pass/const-enum-newtype-align.rs b/src/test/run-pass/const-enum-newtype-align.rs new file mode 100644 index 0000000000000..126af6ae73012 --- /dev/null +++ b/src/test/run-pass/const-enum-newtype-align.rs @@ -0,0 +1,17 @@ +// 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. + +enum E = u32; +struct S { a: u8, b: E } +const C: S = S { a: 0xA5, b: E(0xDEADBEEF) }; + +fn main() { + assert C.b == 0xDEADBEEF; +} From 7c34908e69d6cd51e3764f0be63a7a74484d6fe2 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Sun, 17 Feb 2013 00:55:31 -0800 Subject: [PATCH 2/2] pub fn main --- src/test/run-pass/const-enum-newtype-align.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/const-enum-newtype-align.rs b/src/test/run-pass/const-enum-newtype-align.rs index 126af6ae73012..9c9013ef86082 100644 --- a/src/test/run-pass/const-enum-newtype-align.rs +++ b/src/test/run-pass/const-enum-newtype-align.rs @@ -12,6 +12,6 @@ enum E = u32; struct S { a: u8, b: E } const C: S = S { a: 0xA5, b: E(0xDEADBEEF) }; -fn main() { +pub fn main() { assert C.b == 0xDEADBEEF; }