Skip to content

Commit 877fc8d

Browse files
committed
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.
1 parent 52cf61f commit 877fc8d

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/librustc/middle/trans/consts.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,12 +470,20 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
470470

471471
// FIXME (#1645): enum body alignment is generaly wrong.
472472
if !degen {
473+
// Pad out the data to the size of its type_of;
474+
// this is necessary if the enum is contained
475+
// within an aggregate (tuple, struct, vector) so
476+
// that the next element is at the right offset.
477+
let actual_size =
478+
machine::llsize_of_real(cx, llvm::LLVMTypeOf(c_args));
479+
let padding =
480+
C_null(T_array(T_i8(), size - actual_size));
473481
// A packed_struct has an alignment of 1; thus,
474482
// wrapping one around c_args will misalign it the
475483
// same way we normally misalign enum bodies
476484
// without affecting its internal alignment or
477485
// changing the alignment of the enum.
478-
C_struct(~[discrim, C_packed_struct(~[c_args])])
486+
C_struct(~[discrim, C_packed_struct(~[c_args]), padding])
479487
} else if size == 0 {
480488
C_struct(~[discrim])
481489
} else {

src/test/run-pass/const-enum-tuple.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
enum E { V16(u16), V32(u32) }
12+
const C: (E, u16, u16) = (V16(0xDEAD), 0x600D, 0xBAD);
13+
14+
fn main() {
15+
let (_, n, _) = C;
16+
assert n != 0xBAD;
17+
assert n == 0x600D;
18+
}

0 commit comments

Comments
 (0)