about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-09-13 23:18:40 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-11-19 02:14:29 +0200
commit30710609c06beecf4ef33d04d2814f9503f37b6b (patch)
tree0613fa5dadb3d692b5c2efd1efd985fd82d8d3ee
parent9a0efea4c2ddab7214c7305dd470049e3240ad6a (diff)
downloadrust-30710609c06beecf4ef33d04d2814f9503f37b6b.tar.gz
rust-30710609c06beecf4ef33d04d2814f9503f37b6b.zip
rustc_trans: treat General enums like unions.
-rw-r--r--src/librustc_trans/adt.rs29
-rw-r--r--src/librustc_trans/mir/lvalue.rs5
-rw-r--r--src/librustc_trans/type_of.rs3
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)
                 }
             }