From 877fc8d891e1c710b626281d5312d9a45cbb2226 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Wed, 30 Jan 2013 15:34:52 -0800 Subject: [PATCH] Pad out enum consts to the expected size; makes enums in tuples work. This is wasted space if the const is just an enum, but optimizing that case without breaking everything else is an issue that can be addressed separately. --- src/librustc/middle/trans/consts.rs | 10 +++++++++- src/test/run-pass/const-enum-tuple.rs | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/const-enum-tuple.rs diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index f24ea04569c6..a9dea596f7df 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -470,12 +470,20 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { // FIXME (#1645): enum body alignment is generaly wrong. if !degen { + // Pad out the data to the size of its type_of; + // this is necessary if the enum is contained + // within an aggregate (tuple, struct, vector) so + // that the next element is at the right offset. + let actual_size = + machine::llsize_of_real(cx, llvm::LLVMTypeOf(c_args)); + let padding = + C_null(T_array(T_i8(), size - actual_size)); // A packed_struct has an alignment of 1; thus, // wrapping one around c_args will misalign it the // same way we normally misalign enum bodies // without affecting its internal alignment or // changing the alignment of the enum. - C_struct(~[discrim, C_packed_struct(~[c_args])]) + C_struct(~[discrim, C_packed_struct(~[c_args]), padding]) } else if size == 0 { C_struct(~[discrim]) } else { diff --git a/src/test/run-pass/const-enum-tuple.rs b/src/test/run-pass/const-enum-tuple.rs new file mode 100644 index 000000000000..a55554921c49 --- /dev/null +++ b/src/test/run-pass/const-enum-tuple.rs @@ -0,0 +1,18 @@ +// 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 { V16(u16), V32(u32) } +const C: (E, u16, u16) = (V16(0xDEAD), 0x600D, 0xBAD); + +fn main() { + let (_, n, _) = C; + assert n != 0xBAD; + assert n == 0x600D; +}