Skip to content

Commit 3071060

Browse files
committed
rustc_trans: treat General enums like unions.
1 parent 9a0efea commit 3071060

File tree

3 files changed

+10
-27
lines changed

3 files changed

+10
-27
lines changed

src/librustc_trans/adt.rs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -148,36 +148,15 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
148148
}
149149
}
150150
}
151-
layout::General { discr, size, align, primitive_align, .. } => {
152-
// We need a representation that has:
153-
// * The alignment of the most-aligned field
154-
// * The size of the largest variant (rounded up to that alignment)
155-
// * No alignment padding anywhere any variant has actual data
156-
// (currently matters only for enums small enough to be immediate)
157-
// * The discriminant in an obvious place.
158-
//
159-
// So we start with the discriminant, pad it up to the alignment with
160-
// more of its own type, then use alignment-sized ints to get the rest
161-
// of the size.
162-
let discr_ty = Type::from_integer(cx, discr);
163-
let discr_size = discr.size().bytes();
164-
let padded_discr_size = discr.size().abi_align(align);
165-
let variant_part_size = size - padded_discr_size;
166-
167-
// Ensure discr_ty can fill pad evenly
168-
assert_eq!(padded_discr_size.bytes() % discr_size, 0);
169-
let fields = [
170-
discr_ty,
171-
Type::array(&discr_ty, padded_discr_size.bytes() / discr_size - 1),
172-
union_fill(cx, variant_part_size, primitive_align)
173-
];
151+
layout::General { size, align, .. } => {
152+
let fill = union_fill(cx, size, align);
174153
match name {
175154
None => {
176-
Type::struct_(cx, &fields, false)
155+
Type::struct_(cx, &[fill], false)
177156
}
178157
Some(name) => {
179158
let mut llty = Type::named_struct(cx, name);
180-
llty.set_struct_body(&fields, false);
159+
llty.set_struct_body(&[fill], false);
181160
llty
182161
}
183162
}

src/librustc_trans/mir/lvalue.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
216216
return LvalueRef::new_sized(
217217
bcx.pointercast(self.llval, ty.ptr_to()), fty, alignment);
218218
}
219+
layout::General { .. } if l.variant_index.is_none() => {
220+
let ty = ccx.llvm_type_of(fty);
221+
return LvalueRef::new_sized(
222+
bcx.pointercast(self.llval, ty.ptr_to()), fty, alignment);
223+
}
219224
layout::RawNullablePointer { nndiscr, .. } |
220225
layout::StructWrappedNullablePointer { nndiscr, .. }
221226
if l.variant_index.unwrap() as u64 != nndiscr => {

src/librustc_trans/type_of.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,7 @@ impl<'tcx> LayoutLlvmExt for FullLayout<'tcx> {
262262
if let Some(v) = self.variant_index {
263263
adt::memory_index_to_gep(variants[v].memory_index[index] as u64)
264264
} else {
265-
assert_eq!(index, 0);
266-
index as u64
265+
bug!("FullLayout::llvm_field_index({:?}): not applicable", self)
267266
}
268267
}
269268

0 commit comments

Comments
 (0)