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.
This commit is contained in:
Jed Davis 2013-01-30 15:34:52 -08:00
parent 52cf61fd3b
commit 877fc8d891
2 changed files with 27 additions and 1 deletions

View File

@ -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 {

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;
}