about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/layout.rs31
-rw-r--r--src/librustc_lint/types.rs4
-rw-r--r--src/librustc_trans/abi.rs2
-rw-r--r--src/librustc_trans/adt.rs10
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs11
-rw-r--r--src/librustc_trans/debuginfo/mod.rs2
-rw-r--r--src/librustc_trans/mir/constant.rs12
-rw-r--r--src/librustc_trans/mir/lvalue.rs48
8 files changed, 57 insertions, 63 deletions
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index d798982f3c8..65efc3b5186 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -843,7 +843,7 @@ impl<'a, 'tcx> Struct {
             }
             (&CEnum { discr, .. }, &ty::TyAdt(def, _)) => {
                 if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) {
-                    Ok(Some((Size::from_bytes(0), Int(discr))))
+                    Ok(Some((Size::from_bytes(0), discr)))
                 } else {
                     Ok(None)
                 }
@@ -1097,7 +1097,7 @@ pub enum Layout {
 
     /// C-like enums; basically an integer.
     CEnum {
-        discr: Integer,
+        discr: Primitive,
         signed: bool,
         /// Inclusive discriminant range.
         /// If min > max, it represents min...u64::MAX followed by 0...max.
@@ -1118,7 +1118,7 @@ pub enum Layout {
     /// all space reserved for the discriminant, and their first field starts
     /// at a non-0 offset, after where the discriminant would go.
     General {
-        discr: Integer,
+        discr: Primitive,
         variants: Vec<Struct>,
         size: Size,
         align: Align,
@@ -1251,8 +1251,8 @@ impl<'a, 'tcx> Layout {
                 }
             };
             let abi = match *layout {
-                Scalar(value) => Abi::Scalar(value),
-                CEnum { discr, .. } => Abi::Scalar(Int(discr)),
+                Scalar(value) |
+                CEnum { discr: value, .. } => Abi::Scalar(value),
 
                 Vector { .. } => Abi::Vector,
 
@@ -1453,7 +1453,7 @@ impl<'a, 'tcx> Layout {
                     // grok.
                     let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
                     return success(CEnum {
-                        discr,
+                        discr: Int(discr),
                         signed,
                         // FIXME: should be u128?
                         min: min as u64,
@@ -1646,7 +1646,7 @@ impl<'a, 'tcx> Layout {
                 }
 
                 General {
-                    discr: ity,
+                    discr: Int(ity),
                     variants,
                     size,
                     align,
@@ -1722,7 +1722,7 @@ impl<'a, 'tcx> Layout {
                  metadata.size(dl)).abi_align(self.align(dl))
             }
 
-            CEnum { discr, .. } => Int(discr).size(dl),
+            CEnum { discr, .. } => discr.size(dl),
             General { size, .. } => size,
             UntaggedUnion(ref un) => un.stride(),
 
@@ -1756,7 +1756,7 @@ impl<'a, 'tcx> Layout {
                 Pointer.align(dl).max(metadata.align(dl))
             }
 
-            CEnum { discr, .. } => Int(discr).align(dl),
+            CEnum { discr, .. } => discr.align(dl),
             Array { align, .. } | General { align, .. } => align,
             UntaggedUnion(ref un) => un.align,
 
@@ -1858,7 +1858,7 @@ impl<'a, 'tcx> Layout {
             }
         };
 
-        let build_primitive_info = |name: ast::Name, value: &Primitive| {
+        let build_primitive_info = |name: ast::Name, value: Primitive| {
             session::VariantInfo {
                 name: Some(name.to_string()),
                 kind: session::SizeKind::Exact,
@@ -1951,7 +1951,7 @@ impl<'a, 'tcx> Layout {
                                                            variant_layout)
                                     })
                                     .collect();
-                record(adt_kind.into(), Some(discr.size()), variant_infos);
+                record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
             }
 
             Layout::UntaggedUnion(ref un) => {
@@ -1966,11 +1966,10 @@ impl<'a, 'tcx> Layout {
                 let variant_infos: Vec<_> =
                     adt_def.variants.iter()
                                     .map(|variant_def| {
-                                        build_primitive_info(variant_def.name,
-                                                             &Primitive::Int(discr))
+                                        build_primitive_info(variant_def.name, discr)
                                     })
                                     .collect();
-                record(adt_kind.into(), Some(discr.size()), variant_infos);
+                record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
             }
 
             // other cases provide little interesting (i.e. adjustable
@@ -2359,9 +2358,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
                     match self.variant_index {
                         None => match *self.layout {
                             // Discriminant field for enums (where applicable).
-                            General { discr, .. } => {
-                                return [discr.to_ty(tcx, false)][i];
-                            }
+                            General { discr, .. } |
                             NullablePointer { discr, .. } => {
                                 return [discr.to_ty(tcx)][i];
                             }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 86bd227b1af..879d2e326d8 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -13,7 +13,7 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, AdtKind, Ty, TyCtxt};
-use rustc::ty::layout::{Layout, LayoutOf, Primitive};
+use rustc::ty::layout::{Layout, LayoutOf};
 use middle::const_val::ConstVal;
 use rustc_const_eval::ConstContext;
 use util::nodemap::FxHashSet;
@@ -754,7 +754,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
                 });
 
                 if let Layout::General { ref variants, ref size, discr, .. } = *layout {
-                    let discr_size = Primitive::Int(discr).size(cx.tcx).bytes();
+                    let discr_size = discr.size(cx.tcx).bytes();
 
                     debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
                       t, size.bytes(), layout);
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index c3b6c1cce67..45367508c94 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -474,7 +474,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
 
             // Rust enum types that map onto C enums also need to follow
             // the target ABI zero-/sign-extension rules.
-            Layout::CEnum { discr, signed, .. } => (discr, signed),
+            Layout::CEnum { discr: layout::Int(i), signed, .. } => (i, signed),
 
             _ => return
         };
diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs
index 871d25c0468..e718c7f6f48 100644
--- a/src/librustc_trans/adt.rs
+++ b/src/librustc_trans/adt.rs
@@ -103,7 +103,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let l = cx.layout_of(t);
     debug!("adt::generic_type_of t: {:?} name: {:?}", t, name);
     match *l {
-        layout::CEnum { discr, .. } => Type::from_integer(cx, discr),
+        layout::CEnum { discr, .. } => cx.llvm_type_of(discr.to_ty(cx.tcx())),
         layout::NullablePointer { nndiscr, ref nonnull, .. } => {
             if let layout::Abi::Scalar(_) = l.abi {
                 return cx.llvm_type_of(l.field(cx, 0).ty);
@@ -236,11 +236,3 @@ pub fn is_discr_signed<'tcx>(l: &layout::Layout) -> bool {
         _ => false,
     }
 }
-
-pub fn assert_discr_in_range<D: PartialOrd>(min: D, max: D, discr: D) {
-    if min <= max {
-        assert!(min <= discr && discr <= max)
-    } else {
-        assert!(min <= discr || discr <= max)
-    }
-}
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index e8af81a3d3b..9ae1ded7805 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -1451,8 +1451,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         })
         .collect();
 
-    let discriminant_type_metadata = |inttype: layout::Integer, signed: bool| {
-        let disr_type_key = (enum_def_id, inttype);
+    let discriminant_type_metadata = |discr: layout::Primitive, signed: bool| {
+        let disr_type_key = (enum_def_id, discr);
         let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
                                                                  .borrow()
                                                                  .get(&disr_type_key).cloned();
@@ -1460,10 +1460,13 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             Some(discriminant_type_metadata) => discriminant_type_metadata,
             None => {
                 let (discriminant_size, discriminant_align) =
-                    (inttype.size(), inttype.align(cx));
+                    (discr.size(cx), discr.align(cx));
                 let discriminant_base_type_metadata =
                     type_metadata(cx,
-                                  inttype.to_ty(cx.tcx(), signed),
+                                  match discr {
+                                    layout::Int(i) => i.to_ty(cx.tcx(), signed),
+                                    _ => discr.to_ty(cx.tcx())
+                                  },
                                   syntax_pos::DUMMY_SP);
                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
 
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index 53c5c82b8e3..8d3a0fd5725 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -71,7 +71,7 @@ pub struct CrateDebugContext<'tcx> {
     llmod: ModuleRef,
     builder: DIBuilderRef,
     created_files: RefCell<FxHashMap<(Symbol, Symbol), DIFile>>,
-    created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Integer), DIType>>,
+    created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>,
 
     type_map: RefCell<TypeMap<'tcx>>,
     namespace_map: RefCell<DefIdMap<DIScope>>,
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index befb5409e46..dd06f369470 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -1093,7 +1093,7 @@ fn trans_const_adt<'a, 'tcx>(
         _ => 0,
     };
     match *l {
-        layout::CEnum { discr: d, min, max, .. } => {
+        layout::CEnum { .. } => {
             let discr = match *kind {
                 mir::AggregateKind::Adt(adt_def, _, _, _) => {
                     adt_def.discriminant_for_variant(ccx.tcx(), variant_index)
@@ -1102,14 +1102,14 @@ fn trans_const_adt<'a, 'tcx>(
                 _ => 0,
             };
             assert_eq!(vals.len(), 0);
-            adt::assert_discr_in_range(min, max, discr);
-            Const::new(C_int(Type::from_integer(ccx, d), discr as i64), t)
+            Const::new(C_int(ccx.llvm_type_of(t), discr as i64), t)
         }
-        layout::General { discr: d, ref variants, .. } => {
+        layout::General { ref variants, .. } => {
+            let discr_ty = l.field(ccx, 0).ty;
             let variant = &variants[variant_index];
-            let lldiscr = C_int(Type::from_integer(ccx, d), variant_index as i64);
+            let lldiscr = C_int(ccx.llvm_type_of(discr_ty), variant_index as i64);
             build_const_struct(ccx, l, &variant, vals,
-                Some(Const::new(lldiscr, d.to_ty(ccx.tcx(), false))))
+                Some(Const::new(lldiscr, discr_ty)))
         }
         layout::UntaggedUnion(ref un) => {
             assert_eq!(variant_index, 0);
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index 1b0486dbf96..dd134138f78 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -351,25 +351,28 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
     }
 
     /// Helper for cases where the discriminant is simply loaded.
-    fn load_discr(self, bcx: &Builder, ity: layout::Integer, min: u64, max: u64) -> ValueRef {
-        let bits = ity.size().bits();
-        assert!(bits <= 64);
-        let bits = bits as usize;
-        let mask = !0u64 >> (64 - bits);
-        // For a (max) discr of -1, max will be `-1 as usize`, which overflows.
-        // However, that is fine here (it would still represent the full range),
-        if max.wrapping_add(1) & mask == min & mask {
-            // i.e., if the range is everything.  The lo==hi case would be
-            // rejected by the LLVM verifier (it would mean either an
-            // empty set, which is impossible, or the entire range of the
-            // type, which is pointless).
-            bcx.load(self.llval, self.alignment.non_abi())
-        } else {
-            // llvm::ConstantRange can deal with ranges that wrap around,
-            // so an overflow on (max + 1) is fine.
-            bcx.load_range_assert(self.llval, min, max.wrapping_add(1), /* signed: */ llvm::True,
-                                  self.alignment.non_abi())
+    fn load_discr(self, bcx: &Builder, discr: layout::Primitive, min: u64, max: u64) -> ValueRef {
+        if let layout::Int(ity) = discr {
+            let bits = ity.size().bits();
+            assert!(bits <= 64);
+            let bits = bits as usize;
+            let mask = !0u64 >> (64 - bits);
+            // For a (max) discr of -1, max will be `-1 as usize`, which overflows.
+            // However, that is fine here (it would still represent the full range),
+            if max.wrapping_add(1) & mask == min & mask {
+                // i.e., if the range is everything.  The lo==hi case would be
+                // rejected by the LLVM verifier (it would mean either an
+                // empty set, which is impossible, or the entire range of the
+                // type, which is pointless).
+            } else {
+                // llvm::ConstantRange can deal with ranges that wrap around,
+                // so an overflow on (max + 1) is fine.
+                return bcx.load_range_assert(self.llval, min, max.wrapping_add(1),
+                                             /* signed: */ llvm::True,
+                                             self.alignment.non_abi());
+            }
         }
+        bcx.load(self.llval, self.alignment.non_abi())
     }
 
     /// Obtain the actual discriminant of a value.
@@ -406,14 +409,13 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
             .discriminant_for_variant(bcx.tcx(), variant_index)
             .to_u128_unchecked() as u64;
         match *l {
-            layout::CEnum { discr, min, max, .. } => {
-                adt::assert_discr_in_range(min, max, to);
-                bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64),
+            layout::CEnum { .. } => {
+                bcx.store(C_int(bcx.ccx.llvm_type_of(self.ty.to_ty(bcx.tcx())), to as i64),
                     self.llval, self.alignment.non_abi());
             }
-            layout::General { discr, .. } => {
+            layout::General { .. } => {
                 let ptr = self.project_field(bcx, 0);
-                bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64),
+                bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())), to as i64),
                     ptr.llval, ptr.alignment.non_abi());
             }
             layout::Univariant { .. }