about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKevin Murphy <kemurphy.cmu@gmail.com>2013-07-23 11:52:44 -0400
committerKevin Murphy <kemurphy.cmu@gmail.com>2013-07-24 23:54:40 -0400
commit1c3dc294cefcb92b23581273c24c220c74618a02 (patch)
treed6234f2fb9136d7f83897338f62e2336e1df706f
parent4a726f0573dcfcd01ae9b37266014df0e26f2e22 (diff)
Allow uint discriminants and store them as such
Infers type of constants used as discriminants and ensures they are
integral, instead of forcing them to be a signed integer.

Also, stores discriminant values as uint instead of int interally and
deals with related fallout.

Fixes issue #7994
-rw-r--r--src/librustc/metadata/decoder.rs6
-rw-r--r--src/librustc/metadata/encoder.rs5
-rw-r--r--src/librustc/middle/trans/_match.rs4
-rw-r--r--src/librustc/middle/trans/adt.rs62
-rw-r--r--src/librustc/middle/trans/base.rs9
-rw-r--r--src/librustc/middle/trans/consts.rs2
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/librustc/middle/trans/reflect.rs2
-rw-r--r--src/librustc/middle/ty.rs11
-rw-r--r--src/librustc/middle/typeck/check/mod.rs9
10 files changed, 59 insertions, 55 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 6e166cfbfc8..480661b263a 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -23,7 +23,7 @@ use metadata::tydecode::{parse_ty_data, parse_def_id,
 use middle::ty;
 
 use std::hash::HashUtil;
-use std::int;
+use std::uint;
 use std::io::WriterUtil;
 use std::io;
 use std::option;
@@ -200,9 +200,9 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
     return true;
 }
 
-fn variant_disr_val(d: ebml::Doc) -> Option<int> {
+fn variant_disr_val(d: ebml::Doc) -> Option<uint> {
     do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
-        do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) }
+        do reader::with_doc_data(val_doc) |data| { uint::parse_bytes(data, 10u) }
     }
 }
 
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 78e1a579d74..8d1f086b3a7 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -21,7 +21,6 @@ use middle;
 
 use std::hash::HashUtil;
 use std::hashmap::{HashMap, HashSet};
-use std::int;
 use std::io;
 use std::str;
 use std::uint;
@@ -290,9 +289,9 @@ fn encode_discriminant(ecx: &EncodeContext,
 
 fn encode_disr_val(_: &EncodeContext,
                    ebml_w: &mut writer::Encoder,
-                   disr_val: int) {
+                   disr_val: uint) {
     ebml_w.start_tag(tag_disr_val);
-    let s = int::to_str(disr_val);
+    let s = uint::to_str(disr_val);
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 843aa2b749c..648dd033287 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -193,7 +193,7 @@ pub enum Lit {
 // range)
 pub enum Opt {
     lit(Lit),
-    var(/* disr val */int, @adt::Repr),
+    var(/* disr val */ uint, @adt::Repr),
     range(@ast::expr, @ast::expr),
     vec_len_eq(uint),
     vec_len_ge(uint, /* slice */uint)
@@ -874,7 +874,7 @@ pub struct ExtractedBlock {
 
 pub fn extract_variant_args(bcx: @mut Block,
                             repr: &adt::Repr,
-                            disr_val: int,
+                            disr_val: uint,
                             val: ValueRef)
     -> ExtractedBlock {
     let _icx = push_ctxt("match::extract_variant_args");
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index ee53bfdcbda..4a541c17a23 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -64,7 +64,7 @@ use middle::trans::type_::Type;
 /// Representations.
 pub enum Repr {
     /// C-like enums; basically an int.
-    CEnum(int, int), // discriminant range
+    CEnum(uint, uint), // discriminant range
     /**
      * Single-case variants, and structs/tuples/records.
      *
@@ -89,7 +89,7 @@ pub enum Repr {
      * is represented such that `None` is a null pointer and `Some` is the
      * identity function.
      */
-    NullablePointer{ nonnull: Struct, nndiscr: int, ptrfield: uint,
+    NullablePointer{ nonnull: Struct, nndiscr: uint, ptrfield: uint,
                      nullfields: ~[ty::t] }
 }
 
@@ -140,7 +140,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             return Univariant(mk_struct(cx, ftys, packed), dtor)
         }
         ty::ty_enum(def_id, ref substs) => {
-            struct Case { discr: int, tys: ~[ty::t] };
+            struct Case { discr: uint, tys: ~[ty::t] };
             impl Case {
                 fn is_zerolen(&self, cx: &mut CrateContext) -> bool {
                     mk_struct(cx, self.tys, false).size == 0
@@ -177,7 +177,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             // Since there's at least one
             // non-empty body, explicit discriminants should have
             // been rejected by a checker before this point.
-            if !cases.iter().enumerate().all(|(i,c)| c.discr == (i as int)) {
+            if !cases.iter().enumerate().all(|(i,c)| c.discr == i) {
                 cx.sess.bug(fmt!("non-C-like enum %s with specified \
                                   discriminants",
                                  ty::item_path_str(cx.tcx, def_id)))
@@ -206,7 +206,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             }
 
             // The general case.
-            let discr = ~[ty::mk_int()];
+            let discr = ~[ty::mk_uint()];
             return General(cases.map(|c| mk_struct(cx, discr + c.tys, false)))
         }
         _ => cx.sess.bug("adt::represent_type called on non-ADT type")
@@ -305,9 +305,8 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
     -> ValueRef {
     match *r {
         CEnum(min, max) => load_discr(bcx, scrutinee, min, max),
-        Univariant(*) => C_int(bcx.ccx(), 0),
-        General(ref cases) => load_discr(bcx, scrutinee, 0,
-                                         (cases.len() - 1) as int),
+        Univariant(*) => C_uint(bcx.ccx(), 0),
+        General(ref cases) => load_discr(bcx, scrutinee, 0, cases.len() - 1),
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee),
                  Type::enum_discrim(bcx.ccx()))
@@ -315,7 +314,7 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
     }
 }
 
-fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: int, ptrfield: uint,
+fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: uint, ptrfield: uint,
                      scrutinee: ValueRef) -> ValueRef {
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
     let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
@@ -324,7 +323,7 @@ fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: int, ptrfield:
 }
 
 /// Helper for cases where the discriminant is simply loaded.
-fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: int, max: int)
+fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: uint, max: uint)
     -> ValueRef {
     let ptr = GEPi(bcx, scrutinee, [0, 0]);
     if max + 1 == min {
@@ -348,16 +347,16 @@ fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: int, max: int)
  *
  * This should ideally be less tightly tied to `_match`.
  */
-pub fn trans_case(bcx: @mut Block, r: &Repr, discr: int) -> _match::opt_result {
+pub fn trans_case(bcx: @mut Block, r: &Repr, discr: uint) -> _match::opt_result {
     match *r {
         CEnum(*) => {
-            _match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
+            _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr)))
         }
         Univariant(*) => {
             bcx.ccx().sess.bug("no cases for univariants or structs")
         }
         General(*) => {
-            _match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
+            _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr)))
         }
         NullablePointer{ _ } => {
             assert!(discr == 0 || discr == 1);
@@ -371,11 +370,11 @@ pub fn trans_case(bcx: @mut Block, r: &Repr, discr: int) -> _match::opt_result {
  * representation.  The fields, if any, should then be initialized via
  * `trans_field_ptr`.
  */
-pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
+pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: uint) {
     match *r {
         CEnum(min, max) => {
             assert!(min <= discr && discr <= max);
-            Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
+            Store(bcx, C_uint(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
         }
         Univariant(ref st, true) => {
             assert_eq!(discr, 0);
@@ -386,7 +385,7 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
             assert_eq!(discr, 0);
         }
         General(*) => {
-            Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
+            Store(bcx, C_uint(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
         }
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             if discr != nndiscr {
@@ -402,14 +401,14 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
  * The number of fields in a given case; for use when obtaining this
  * information from the type or definition is less convenient.
  */
-pub fn num_args(r: &Repr, discr: int) -> uint {
+pub fn num_args(r: &Repr, discr: uint) -> uint {
     match *r {
         CEnum(*) => 0,
         Univariant(ref st, dtor) => {
             assert_eq!(discr, 0);
             st.fields.len() - (if dtor { 1 } else { 0 })
         }
-        General(ref cases) => cases[discr as uint].fields.len() - 1,
+        General(ref cases) => cases[discr].fields.len() - 1,
         NullablePointer{ nonnull: ref nonnull, nndiscr, nullfields: ref nullfields, _ } => {
             if discr == nndiscr { nonnull.fields.len() } else { nullfields.len() }
         }
@@ -417,7 +416,7 @@ pub fn num_args(r: &Repr, discr: int) -> uint {
 }
 
 /// Access a field, at a point when the value's case is known.
-pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int,
+pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: uint,
                        ix: uint) -> ValueRef {
     // Note: if this ever needs to generate conditionals (e.g., if we
     // decide to do some kind of cdr-coding-like non-unique repr
@@ -431,7 +430,7 @@ pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int,
             struct_field_ptr(bcx, st, val, ix, false)
         }
         General(ref cases) => {
-            struct_field_ptr(bcx, &cases[discr as uint], val, ix + 1, true)
+            struct_field_ptr(bcx, &cases[discr], val, ix + 1, true)
         }
         NullablePointer{ nonnull: ref nonnull, nullfields: ref nullfields, nndiscr, _ } => {
             if (discr == nndiscr) {
@@ -495,22 +494,22 @@ pub fn trans_drop_flag_ptr(bcx: @mut Block, r: &Repr, val: ValueRef) -> ValueRef
  * this could be changed in the future to avoid allocating unnecessary
  * space after values of shorter-than-maximum cases.
  */
-pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int,
+pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: uint,
                    vals: &[ValueRef]) -> ValueRef {
     match *r {
         CEnum(min, max) => {
             assert_eq!(vals.len(), 0);
             assert!(min <= discr && discr <= max);
-            C_int(ccx, discr)
+            C_uint(ccx, discr)
         }
         Univariant(ref st, _dro) => {
             assert_eq!(discr, 0);
             C_struct(build_const_struct(ccx, st, vals))
         }
         General(ref cases) => {
-            let case = &cases[discr as uint];
+            let case = &cases[discr];
             let max_sz = cases.iter().transform(|x| x.size).max().unwrap();
-            let discr_ty = C_int(ccx, discr);
+            let discr_ty = C_uint(ccx, discr);
             let contents = build_const_struct(ccx, case,
                                               ~[discr_ty] + vals);
             C_struct(contents + &[padding(max_sz - case.size)])
@@ -582,13 +581,18 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
 
 /// Get the discriminant of a constant value.  (Not currently used.)
 pub fn const_get_discrim(ccx: &mut CrateContext, r: &Repr, val: ValueRef)
-    -> int {
+    -> uint {
     match *r {
-        CEnum(*) => const_to_int(val) as int,
+        CEnum(*) => const_to_uint(val) as uint,
         Univariant(*) => 0,
-        General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int,
+        General(*) => const_to_uint(const_get_elt(ccx, val, [0])) as uint,
         NullablePointer{ nndiscr, ptrfield, _ } => {
-            if is_null(const_struct_field(ccx, val, ptrfield)) { 1 - nndiscr } else { nndiscr }
+            if is_null(const_struct_field(ccx, val, ptrfield)) {
+                /* subtraction as uint is ok because nndiscr is either 0 or 1 */
+                (1 - nndiscr) as uint
+            } else {
+                nndiscr
+            }
         }
     }
 }
@@ -601,7 +605,7 @@ pub fn const_get_discrim(ccx: &mut CrateContext, r: &Repr, val: ValueRef)
  * raw LLVM-level structs and arrays.)
  */
 pub fn const_get_field(ccx: &mut CrateContext, r: &Repr, val: ValueRef,
-                       _discr: int, ix: uint) -> ValueRef {
+                       _discr: uint, ix: uint) -> ValueRef {
     match *r {
         CEnum(*) => ccx.sess.bug("element access in C-like enum const"),
         Univariant(*) => const_struct_field(ccx, val, ix),
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index d3ae69b23da..437d1a50d18 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -67,7 +67,6 @@ use middle::trans::type_::Type;
 
 use std::hash;
 use std::hashmap::{HashMap, HashSet};
-use std::int;
 use std::io;
 use std::libc::c_uint;
 use std::uint;
@@ -732,7 +731,7 @@ pub fn iter_structural_ty(cx: @mut Block, av: ValueRef, t: ty::t,
                   for (*variants).iter().advance |variant| {
                       let variant_cx =
                           sub_block(cx, ~"enum-iter-variant-" +
-                                    int::to_str(variant.disr_val));
+                                    uint::to_str(variant.disr_val));
                       let variant_cx =
                           iter_variant(variant_cx, repr, av, *variant,
                                        substs.tps, |x,y,z| f(x,y,z));
@@ -1979,7 +1978,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext,
                           _enum_id: ast::node_id,
                           variant: &ast::variant,
                           args: &[ast::variant_arg],
-                          disr: int,
+                          disr: uint,
                           param_substs: Option<@param_substs>,
                           llfndecl: ValueRef) {
     let _icx = push_ctxt("trans_enum_variant");
@@ -2028,7 +2027,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
     ccx: @mut CrateContext,
     ctor_id: ast::node_id,
     args: &[A],
-    disr: int,
+    disr: uint,
     param_substs: Option<@param_substs>,
     llfndecl: ValueRef)
 {
@@ -2628,7 +2627,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
                 }
             };
             unsafe {
-                llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
+                llvm::LLVMSetInitializer(discrim_gvar, C_uint(ccx, disr_val));
                 llvm::LLVMSetGlobalConstant(discrim_gvar, True);
             }
             ccx.discrims.insert(
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 15793ea747f..db9e3db2c0f 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -446,7 +446,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               (expr::cast_enum, expr::cast_float)  => {
                 let repr = adt::represent_type(cx, basety);
                 let discr = adt::const_get_discrim(cx, repr, v);
-                let iv = C_int(cx, discr);
+                let iv = C_uint(cx, discr);
                 let ety_cast = expr::cast_type_kind(ety);
                 match ety_cast {
                     expr::cast_integral => {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index f552eded163..c038ca710aa 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1083,7 +1083,7 @@ pub fn trans_local_var(bcx: @mut Block, def: ast::def) -> Datum {
 pub fn with_field_tys<R>(tcx: ty::ctxt,
                          ty: ty::t,
                          node_id_opt: Option<ast::node_id>,
-                         op: &fn(int, (&[ty::field])) -> R) -> R {
+                         op: &fn(uint, (&[ty::field])) -> R) -> R {
     match ty::get(ty).sty {
         ty::ty_struct(did, ref substs) => {
             op(0, struct_fields(tcx, did, substs))
@@ -1200,7 +1200,7 @@ struct StructBaseInfo {
  * - `optbase` contains information on the base struct (if any) from
  * which remaining fields are copied; see comments on `StructBaseInfo`.
  */
-fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: int,
+fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: uint,
              fields: &[(uint, @ast::expr)],
              optbase: Option<StructBaseInfo>,
              dest: Dest) -> @mut Block {
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 84b001953e0..3d23828979f 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -321,7 +321,7 @@ impl Reflector {
                 for variants.iter().enumerate().advance |(i, v)| {
                     let name = ccx.sess.str_of(v.name);
                     let variant_args = ~[this.c_uint(i),
-                                         this.c_int(v.disr_val),
+                                         this.c_uint(v.disr_val),
                                          this.c_uint(v.args.len()),
                                          this.c_slice(name)];
                     do this.bracketed("enum_variant", variant_args) |this| {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 7eea20175f9..20c39cc84ef 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -49,7 +49,7 @@ use syntax::opt_vec;
 use syntax::abi::AbiSet;
 use syntax;
 
-pub static INITIAL_DISCRIMINANT_VALUE: int = 0;
+pub static INITIAL_DISCRIMINANT_VALUE: uint = 0;
 
 // Data types
 
@@ -3689,7 +3689,7 @@ pub struct VariantInfo {
     ctor_ty: t,
     name: ast::ident,
     id: ast::def_id,
-    disr_val: int,
+    disr_val: uint,
     vis: visibility
 }
 
@@ -3700,7 +3700,7 @@ impl VariantInfo {
     /// Does not do any caching of the value in the type context.
     pub fn from_ast_variant(cx: ctxt,
                             ast_variant: &ast::variant,
-                            discriminant: int) -> VariantInfo {
+                            discriminant: uint) -> VariantInfo {
 
         let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
 
@@ -3894,7 +3894,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[@VariantInfo] {
                     node: ast::item_enum(ref enum_definition, _),
                     _
                 }, _) => {
-            let mut last_discriminant: Option<int> = None;
+            let mut last_discriminant: Option<uint> = None;
             @enum_definition.variants.iter().transform(|variant| {
 
                 let mut discriminant = match last_discriminant {
@@ -3904,7 +3904,8 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[@VariantInfo] {
 
                 match variant.node.disr_expr {
                     Some(e) => match const_eval::eval_const_expr_partial(&cx, e) {
-                        Ok(const_eval::const_int(val)) => discriminant = val as int,
+                        Ok(const_eval::const_int(val)) => discriminant = val as uint,
+                        Ok(const_eval::const_uint(val)) => discriminant = val as uint,
                         Ok(_) => {
                             cx.sess.span_err(e.span, "expected signed integer constant");
                         }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index c04e1c2515c..e5f9cf0d146 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -3139,8 +3139,8 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
 
         let rty = ty::node_id_to_type(ccx.tcx, id);
         let mut variants: ~[@ty::VariantInfo] = ~[];
-        let mut disr_vals: ~[int] = ~[];
-        let mut prev_disr_val: Option<int> = None;
+        let mut disr_vals: ~[uint] = ~[];
+        let mut prev_disr_val: Option<uint> = None;
 
         for vs.iter().advance |v| {
 
@@ -3155,15 +3155,16 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
                 Some(e) => {
                     debug!("disr expr, checking %s", pprust::expr_to_str(e, ccx.tcx.sess.intr()));
 
-                    let declty = ty::mk_int();
                     let fcx = blank_fn_ctxt(ccx, rty, e.id);
+                    let declty = ty::mk_int_var(ccx.tcx, fcx.infcx().next_int_var_id());
                     check_const_with_ty(fcx, e.span, e, declty);
                     // check_expr (from check_const pass) doesn't guarantee
                     // that the expression is in an form that eval_const_expr can
                     // handle, so we may still get an internal compiler error
 
                     match const_eval::eval_const_expr_partial(&ccx.tcx, e) {
-                        Ok(const_eval::const_int(val)) => current_disr_val = val as int,
+                        Ok(const_eval::const_int(val)) => current_disr_val = val as uint,
+                        Ok(const_eval::const_uint(val)) => current_disr_val = val as uint,
                         Ok(_) => {
                             ccx.tcx.sess.span_err(e.span, "expected signed integer constant");
                         }