diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-09-13 23:18:40 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-11-19 02:14:29 +0200 |
| commit | 30710609c06beecf4ef33d04d2814f9503f37b6b (patch) | |
| tree | 0613fa5dadb3d692b5c2efd1efd985fd82d8d3ee | |
| parent | 9a0efea4c2ddab7214c7305dd470049e3240ad6a (diff) | |
| download | rust-30710609c06beecf4ef33d04d2814f9503f37b6b.tar.gz rust-30710609c06beecf4ef33d04d2814f9503f37b6b.zip | |
rustc_trans: treat General enums like unions.
| -rw-r--r-- | src/librustc_trans/adt.rs | 29 | ||||
| -rw-r--r-- | src/librustc_trans/mir/lvalue.rs | 5 | ||||
| -rw-r--r-- | src/librustc_trans/type_of.rs | 3 |
3 files changed, 10 insertions, 27 deletions
diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs index ec87429c2b2..7f640195506 100644 --- a/src/librustc_trans/adt.rs +++ b/src/librustc_trans/adt.rs @@ -148,36 +148,15 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } } - layout::General { discr, size, align, primitive_align, .. } => { - // We need a representation that has: - // * The alignment of the most-aligned field - // * The size of the largest variant (rounded up to that alignment) - // * No alignment padding anywhere any variant has actual data - // (currently matters only for enums small enough to be immediate) - // * The discriminant in an obvious place. - // - // So we start with the discriminant, pad it up to the alignment with - // more of its own type, then use alignment-sized ints to get the rest - // of the size. - let discr_ty = Type::from_integer(cx, discr); - let discr_size = discr.size().bytes(); - let padded_discr_size = discr.size().abi_align(align); - let variant_part_size = size - padded_discr_size; - - // Ensure discr_ty can fill pad evenly - assert_eq!(padded_discr_size.bytes() % discr_size, 0); - let fields = [ - discr_ty, - Type::array(&discr_ty, padded_discr_size.bytes() / discr_size - 1), - union_fill(cx, variant_part_size, primitive_align) - ]; + layout::General { size, align, .. } => { + let fill = union_fill(cx, size, align); match name { None => { - Type::struct_(cx, &fields, false) + Type::struct_(cx, &[fill], false) } Some(name) => { let mut llty = Type::named_struct(cx, name); - llty.set_struct_body(&fields, false); + llty.set_struct_body(&[fill], false); llty } } diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index 2bd76308c91..40515743af0 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -216,6 +216,11 @@ impl<'a, 'tcx> LvalueRef<'tcx> { return LvalueRef::new_sized( bcx.pointercast(self.llval, ty.ptr_to()), fty, alignment); } + layout::General { .. } if l.variant_index.is_none() => { + let ty = ccx.llvm_type_of(fty); + return LvalueRef::new_sized( + bcx.pointercast(self.llval, ty.ptr_to()), fty, alignment); + } layout::RawNullablePointer { nndiscr, .. } | layout::StructWrappedNullablePointer { nndiscr, .. } if l.variant_index.unwrap() as u64 != nndiscr => { diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index d504ea1c307..06a82bb2de4 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -262,8 +262,7 @@ impl<'tcx> LayoutLlvmExt for FullLayout<'tcx> { if let Some(v) = self.variant_index { adt::memory_index_to_gep(variants[v].memory_index[index] as u64) } else { - assert_eq!(index, 0); - index as u64 + bug!("FullLayout::llvm_field_index({:?}): not applicable", self) } } |
