about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/context.rs4
-rw-r--r--src/librustc/ty/layout.rs13
-rw-r--r--src/librustc/ty/mod.rs8
-rw-r--r--src/librustc/ty/util.rs61
-rw-r--r--src/librustc_metadata/decoder.rs16
-rw-r--r--src/librustc_metadata/encoder.rs10
-rw-r--r--src/librustc_metadata/schema.rs2
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/disr.rs2
-rw-r--r--src/librustc_typeck/collect.rs109
10 files changed, 105 insertions, 122 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 6203679a510..19bb8a63aa2 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -673,10 +673,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn alloc_adt_def(self,
                          did: DefId,
                          kind: AdtKind,
+                         discr_ty: Option<attr::IntType>,
                          variants: Vec<ty::VariantDef>,
                          repr: ReprOptions)
                          -> &'gcx ty::AdtDef {
-        let def = ty::AdtDef::new(self, did, kind, variants, repr);
+        let discr_ty = discr_ty.unwrap_or(attr::UnsignedInt(ast::UintTy::U8));
+        let def = ty::AdtDef::new(self, did, kind, discr_ty, variants, repr);
         self.global_arenas.adt_def.alloc(def)
     }
 
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 3a463e981a6..4d3a17e51c1 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -20,7 +20,6 @@ use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
 use syntax::ast::{FloatTy, IntTy, UintTy};
 use syntax::attr;
 use syntax_pos::DUMMY_SP;
-use rustc_const_math::ConstInt;
 
 use std::cmp;
 use std::fmt;
@@ -1183,10 +1182,12 @@ impl<'a, 'gcx, 'tcx> Layout {
                                                             i64::min_value(),
                                                             true);
                     for v in &def.variants {
-                        let x = match v.disr_val.erase_type() {
-                            ConstInt::InferSigned(i) => i as i64,
-                            ConstInt::Infer(i) => i as u64 as i64,
-                            _ => bug!()
+                        let x = match def.discr_ty {
+                            attr::IntType::SignedInt(IntTy::I128) |
+                            attr::IntType::UnsignedInt(UintTy::U128) =>
+                                bug!("128-bit discriminants not yet supported"),
+                            attr::IntType::SignedInt(_) => v.disr_val as i64,
+                            attr::IntType::UnsignedInt(_) => v.disr_val as u64 as i64,
                         };
                         if x == 0 { non_zero = false; }
                         if x < min { min = x; }
@@ -1247,7 +1248,7 @@ impl<'a, 'gcx, 'tcx> Layout {
                 // non-empty body, explicit discriminants should have
                 // been rejected by a checker before this point.
                 for (i, v) in def.variants.iter().enumerate() {
-                    if i as u128 != v.disr_val.to_u128_unchecked() {
+                    if i as u128 != v.disr_val {
                         bug!("non-C-like enum {} with specified discriminants",
                             tcx.item_path_str(def.did));
                     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index beb286108a0..5ec27b57c37 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -45,7 +45,6 @@ use syntax::attr;
 use syntax::symbol::{Symbol, InternedString};
 use syntax_pos::{DUMMY_SP, Span};
 
-use rustc_const_math::ConstInt;
 use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
 
 use hir;
@@ -72,6 +71,8 @@ pub use self::context::{Lift, TypeckTables};
 
 pub use self::trait_def::{TraitDef, TraitFlags};
 
+use rustc_i128::u128;
+
 pub mod adjustment;
 pub mod cast;
 pub mod error;
@@ -96,7 +97,7 @@ mod flags;
 mod structural_impls;
 mod sty;
 
-pub type Disr = ConstInt;
+pub type Disr = u128;
 
 // Data types
 
@@ -1325,6 +1326,7 @@ pub struct FieldDef {
 /// table.
 pub struct AdtDef {
     pub did: DefId,
+    pub discr_ty: attr::IntType, // Type of the discriminant
     pub variants: Vec<VariantDef>,
     destructor: Cell<Option<DefId>>,
     flags: Cell<AdtFlags>,
@@ -1387,6 +1389,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
     fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
            did: DefId,
            kind: AdtKind,
+           discr_ty: attr::IntType,
            variants: Vec<VariantDef>,
            repr: ReprOptions) -> Self {
         let mut flags = AdtFlags::NO_ADT_FLAGS;
@@ -1410,6 +1413,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
         }
         AdtDef {
             did: did,
+            discr_ty: discr_ty,
             variants: variants,
             flags: Cell::new(flags),
             destructor: Cell::new(None),
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index b01b77bbcf8..1df87da4227 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -23,7 +23,7 @@ use ty::TypeVariants::*;
 use util::nodemap::FxHashMap;
 use middle::lang_items;
 
-use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
+use rustc_const_math::ConstInt;
 use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult};
 
 use std::cell::RefCell;
@@ -34,14 +34,15 @@ use syntax::ast::{self, Name};
 use syntax::attr::{self, SignedInt, UnsignedInt};
 use syntax_pos::Span;
 
+use rustc_i128::i128;
+
 use hir;
 
 pub trait IntTypeExt {
     fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx>;
     fn disr_incr<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, val: Option<Disr>)
                            -> Option<Disr>;
-    fn assert_ty_matches(&self, val: Disr);
-    fn initial_discriminant<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Disr;
+    fn initial_discriminant<'a, 'tcx>(&self, _: TyCtxt<'a, 'tcx, 'tcx>) -> Disr;
 }
 
 impl IntTypeExt for attr::IntType {
@@ -62,56 +63,18 @@ impl IntTypeExt for attr::IntType {
         }
     }
 
-    fn initial_discriminant<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Disr {
-        match *self {
-            SignedInt(ast::IntTy::I8)    => ConstInt::I8(0),
-            SignedInt(ast::IntTy::I16)   => ConstInt::I16(0),
-            SignedInt(ast::IntTy::I32)   => ConstInt::I32(0),
-            SignedInt(ast::IntTy::I64)   => ConstInt::I64(0),
-            SignedInt(ast::IntTy::I128)   => ConstInt::I128(0),
-            SignedInt(ast::IntTy::Is) => match tcx.sess.target.int_type {
-                ast::IntTy::I16 => ConstInt::Isize(ConstIsize::Is16(0)),
-                ast::IntTy::I32 => ConstInt::Isize(ConstIsize::Is32(0)),
-                ast::IntTy::I64 => ConstInt::Isize(ConstIsize::Is64(0)),
-                _ => bug!(),
-            },
-            UnsignedInt(ast::UintTy::U8)  => ConstInt::U8(0),
-            UnsignedInt(ast::UintTy::U16) => ConstInt::U16(0),
-            UnsignedInt(ast::UintTy::U32) => ConstInt::U32(0),
-            UnsignedInt(ast::UintTy::U64) => ConstInt::U64(0),
-            UnsignedInt(ast::UintTy::U128) => ConstInt::U128(0),
-            UnsignedInt(ast::UintTy::Us) => match tcx.sess.target.uint_type {
-                ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(0)),
-                ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(0)),
-                ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64(0)),
-                _ => bug!(),
-            },
-        }
-    }
-
-    fn assert_ty_matches(&self, val: Disr) {
-        match (*self, val) {
-            (SignedInt(ast::IntTy::I8), ConstInt::I8(_)) => {},
-            (SignedInt(ast::IntTy::I16), ConstInt::I16(_)) => {},
-            (SignedInt(ast::IntTy::I32), ConstInt::I32(_)) => {},
-            (SignedInt(ast::IntTy::I64), ConstInt::I64(_)) => {},
-            (SignedInt(ast::IntTy::I128), ConstInt::I128(_)) => {},
-            (SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) => {},
-            (UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) => {},
-            (UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) => {},
-            (UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) => {},
-            (UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) => {},
-            (UnsignedInt(ast::UintTy::U128), ConstInt::U128(_)) => {},
-            (UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) => {},
-            _ => bug!("disr type mismatch: {:?} vs {:?}", self, val),
-        }
+    fn initial_discriminant<'a, 'tcx>(&self, _: TyCtxt<'a, 'tcx, 'tcx>) -> Disr {
+        0
     }
 
+    /// None = overflow
     fn disr_incr<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, val: Option<Disr>)
-                           -> Option<Disr> {
+    -> Option<Disr> {
         if let Some(val) = val {
-            self.assert_ty_matches(val);
-            (val + ConstInt::Infer(1)).ok()
+            match *self {
+                SignedInt(it) => ConstInt::new_signed(val as i128, it, tcx.sess.target.int_type),
+                UnsignedInt(it) => ConstInt::new_unsigned(val, it, tcx.sess.target.uint_type),
+            }.and_then(|l| (l + ConstInt::Infer(1)).ok()).map(|v| v.to_u128_unchecked())
         } else {
             Some(self.initial_discriminant(tcx))
         }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index bb99be20f64..88c04d88a6f 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -25,8 +25,6 @@ use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::Substs;
 
-use rustc_const_math::ConstInt;
-
 use rustc::mir::Mir;
 
 use std::borrow::Cow;
@@ -435,7 +433,7 @@ impl<'tcx> EntryKind<'tcx> {
             EntryKind::Mod(_) => Def::Mod(did),
             EntryKind::Variant(_) => Def::Variant(did),
             EntryKind::Trait(_) => Def::Trait(did),
-            EntryKind::Enum(_) => Def::Enum(did),
+            EntryKind::Enum(..) => Def::Enum(did),
             EntryKind::MacroDef(_) => Def::Macro(did),
 
             EntryKind::ForeignMod |
@@ -535,7 +533,7 @@ impl<'a, 'tcx> CrateMetadata {
                     vis: f.visibility.decode(self)
                 }
             }).collect(),
-            disr_val: ConstInt::Infer(data.disr),
+            disr_val: data.disr,
             ctor_kind: data.ctor_kind,
         }, data.struct_ctor)
     }
@@ -546,6 +544,12 @@ impl<'a, 'tcx> CrateMetadata {
                        -> &'tcx ty::AdtDef {
         let item = self.entry(item_id);
         let did = self.local_def_id(item_id);
+        let (kind, ty) = match item.kind {
+            EntryKind::Enum(dt, _) => (ty::AdtKind::Enum, Some(dt.decode(self))),
+            EntryKind::Struct(_) => (ty::AdtKind::Struct, None),
+            EntryKind::Union(_) => (ty::AdtKind::Union, None),
+            _ => bug!("get_adt_def called on a non-ADT {:?}", did),
+        };
         let mut ctor_index = None;
         let variants = if let EntryKind::Enum(_) = item.kind {
             item.children
@@ -562,13 +566,13 @@ impl<'a, 'tcx> CrateMetadata {
             vec![variant]
         };
         let (kind, repr) = match item.kind {
-            EntryKind::Enum(repr) => (ty::AdtKind::Enum, repr),
+            EntryKind::Enum(_, repr) => (ty::AdtKind::Enum, repr),
             EntryKind::Struct(_, repr) => (ty::AdtKind::Struct, repr),
             EntryKind::Union(_, repr) => (ty::AdtKind::Union, repr),
             _ => bug!("get_adt_def called on a non-ADT {:?}", did),
         };
 
-        let adt = tcx.alloc_adt_def(did, kind, variants, repr);
+        let adt = tcx.alloc_adt_def(did, kind, ty, variants, repr);
         if let Some(ctor_index) = ctor_index {
             // Make adt definition available through constructor id as well.
             tcx.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt);
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index f4ff5f4626f..b913f68e584 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -261,7 +261,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
-            disr: variant.disr_val.to_u128_unchecked(),
+            disr: variant.disr_val,
             struct_ctor: None,
         };
 
@@ -388,7 +388,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
-            disr: variant.disr_val.to_u128_unchecked(),
+            disr: variant.disr_val,
             struct_ctor: Some(def_id.index),
         };
 
@@ -661,7 +661,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             hir::ItemForeignMod(_) => EntryKind::ForeignMod,
             hir::ItemTy(..) => EntryKind::Type,
-            hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
+            hir::ItemEnum(..) => EntryKind::Enum(self.lazy(&tcx.lookup_adt_def(def_id).discr_ty), get_repr_options(&tcx, def_id)),
             hir::ItemStruct(ref struct_def, _) => {
                 let variant = tcx.lookup_adt_def(def_id).struct_variant();
 
@@ -678,7 +678,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
                 EntryKind::Struct(self.lazy(&VariantData {
                     ctor_kind: variant.ctor_kind,
-                    disr: variant.disr_val.to_u128_unchecked(),
+                    disr: variant.disr_val,
                     struct_ctor: struct_ctor,
                 }), repr_options)
             }
@@ -688,7 +688,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
                 EntryKind::Union(self.lazy(&VariantData {
                     ctor_kind: variant.ctor_kind,
-                    disr: variant.disr_val.to_u128_unchecked(),
+                    disr: variant.disr_val,
                     struct_ctor: None,
                 }), repr_options)
             }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 10aa4784aa2..777af02772e 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -228,7 +228,7 @@ pub enum EntryKind<'tcx> {
     ForeignMutStatic,
     ForeignMod,
     Type,
-    Enum(ReprOptions),
+    Enum(Lazy<attr::IntType>, ReprOptions),
     Field,
     Variant(Lazy<VariantData>),
     Struct(Lazy<VariantData>, ReprOptions),
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index 7578cc74dbf..9ae83991962 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -1473,7 +1473,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     DIB(cx),
                     name.as_ptr(),
                     // FIXME: what if enumeration has i128 discriminant?
-                    v.disr_val.to_u128_unchecked() as u64)
+                    v.disr_val as u64)
             }
         })
         .collect();
diff --git a/src/librustc_trans/disr.rs b/src/librustc_trans/disr.rs
index c5737c6e5f1..f3a62bc85b8 100644
--- a/src/librustc_trans/disr.rs
+++ b/src/librustc_trans/disr.rs
@@ -27,7 +27,7 @@ impl ::std::ops::BitAnd for Disr {
 impl From<::rustc::ty::Disr> for Disr {
     fn from(i: ::rustc::ty::Disr) -> Disr {
         // FIXME: what if discr has 128 bit discr?
-        Disr(i.to_u128_unchecked() as u64)
+        Disr(i as u64)
     }
 }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 7936db65c44..c1b4531f85e 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1004,9 +1004,8 @@ fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let did = ccx.tcx.hir.local_def_id(it.id);
     // Use separate constructor id for unit/tuple structs and reuse did for braced structs.
     let ctor_id = if !def.is_struct() { Some(ccx.tcx.hir.local_def_id(def.id())) } else { None };
-    let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
-                                               ConstInt::Infer(0), def)];
-    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, variants,
+    let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name, 0, def)];
+    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, None, variants,
         ReprOptions::new(&ccx.tcx, did));
     if let Some(ctor_id) = ctor_id {
         // Make adt definition available through constructor id as well.
@@ -1023,63 +1022,69 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 -> &'tcx ty::AdtDef
 {
     let did = ccx.tcx.hir.local_def_id(it.id);
+<<<<<<< HEAD
     let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)];
 
     let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants, ReprOptions::new(&ccx.tcx, did));
+=======
+    let variants = vec![convert_struct_variant(ccx, did, it.name, 0, def)];
+    let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, None, variants);
+>>>>>>> b1934037e6... Move type of discriminant to AdtDef
     ccx.tcx.adt_defs.borrow_mut().insert(did, adt);
     adt
 }
 
-    fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, body: hir::BodyId)
-                          -> Option<ty::Disr> {
-        let e = &ccx.tcx.hir.body(body).value;
-        debug!("disr expr, checking {}", ccx.tcx.hir.node_to_pretty_string(e.id));
-
-        let ty_hint = repr_ty.to_ty(ccx.tcx);
-        let print_err = |cv: ConstVal| {
-            struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types")
-                .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description()))
-                .span_label(e.span, &format!("expected '{}' type", ty_hint))
-                .emit();
-        };
+fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, body: hir::BodyId)
+                      -> Option<ty::Disr> {
+    let e = &ccx.tcx.hir.body(body).value;
+    debug!("disr expr, checking {}", ccx.tcx.hir.node_to_pretty_string(e.id));
+
+    let ty_hint = repr_ty.to_ty(ccx.tcx);
+    let print_err = |cv: ConstVal| {
+        struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types")
+            .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description()))
+            .span_label(e.span, &format!("expected '{}' type", ty_hint))
+            .emit();
+    };
 
-        let hint = UncheckedExprHint(ty_hint);
-        match ConstContext::new(ccx.tcx, body).eval(e, hint) {
-            Ok(ConstVal::Integral(i)) => {
-                // FIXME: eval should return an error if the hint is wrong
-                match (repr_ty, i) {
-                    (attr::SignedInt(ast::IntTy::I8), ConstInt::I8(_)) |
-                    (attr::SignedInt(ast::IntTy::I16), ConstInt::I16(_)) |
-                    (attr::SignedInt(ast::IntTy::I32), ConstInt::I32(_)) |
-                    (attr::SignedInt(ast::IntTy::I64), ConstInt::I64(_)) |
-                    (attr::SignedInt(ast::IntTy::I128), ConstInt::I128(_)) |
-                    (attr::SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) |
-                    (attr::UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) |
-                    (attr::UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) |
-                    (attr::UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) |
-                    (attr::UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) |
-                    (attr::UnsignedInt(ast::UintTy::U128), ConstInt::U128(_)) |
-                    (attr::UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) => Some(i),
-                    (_, i) => {
-                        print_err(ConstVal::Integral(i));
-                        None
-                    },
-                }
-            },
-            Ok(cv) => {
-                print_err(cv);
-                None
-            },
-            // enum variant evaluation happens before the global constant check
-            // so we need to report the real error
-            Err(err) => {
-                let mut diag = report_const_eval_err(
-                    ccx.tcx, &err, e.span, "enum discriminant");
-                diag.emit();
-                None
+    let hint = UncheckedExprHint(ty_hint);
+    match ConstContext::new(ccx.tcx, body).eval(e, hint) {
+        Ok(ConstVal::Integral(i)) => {
+            // FIXME: eval should return an error if the hint is wrong
+            match (repr_ty, i) {
+                (attr::SignedInt(ast::IntTy::I8), ConstInt::I8(_)) |
+                (attr::SignedInt(ast::IntTy::I16), ConstInt::I16(_)) |
+                (attr::SignedInt(ast::IntTy::I32), ConstInt::I32(_)) |
+                (attr::SignedInt(ast::IntTy::I64), ConstInt::I64(_)) |
+                (attr::SignedInt(ast::IntTy::I128), ConstInt::I128(_)) |
+                (attr::SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) |
+                (attr::UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) |
+                (attr::UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) |
+                (attr::UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) |
+                (attr::UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) |
+                (attr::UnsignedInt(ast::UintTy::U128), ConstInt::U128(_)) |
+                (attr::UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) =>
+                    Some(i.to_u128_unchecked()),
+                (_, i) => {
+                    print_err(ConstVal::Integral(i));
+                    None
+                },
             }
+        },
+        Ok(cv) => {
+            print_err(cv);
+            None
+        },
+        // enum variant evaluation happens before the global constant check
+        // so we need to report the real error
+        Err(err) => {
+            let mut diag = report_const_eval_err(
+                ccx.tcx, &err, e.span, "enum discriminant");
+            diag.emit();
+            None
         }
     }
+}
 
 fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                               it: &hir::Item,
@@ -1093,7 +1098,7 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let initial = repr_type.initial_discriminant(tcx);
     let mut prev_disr = None::<ty::Disr>;
     let variants = def.variants.iter().map(|v| {
-        let wrapped_disr = prev_disr.map_or(initial, |d| d.wrap_incr());
+        let wrapped_disr = prev_disr.map_or(initial, |d| d.wrapping_add(1));
         let disr = if let Some(e) = v.node.disr_expr {
             evaluate_disr_expr(ccx, repr_type, e)
         } else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) {
@@ -1113,7 +1118,11 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
     }).collect();
 
+<<<<<<< HEAD
     let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants, ReprOptions::new(&ccx.tcx, did));
+=======
+    let adt = tcx.alloc_adt_def(did, AdtKind::Enum, Some(repr_type), variants);
+>>>>>>> b1934037e6... Move type of discriminant to AdtDef
     tcx.adt_defs.borrow_mut().insert(did, adt);
     adt
 }