From 8ef8dd9ceb0a4790d65c1dd8327a0d5618c3a46f Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Mon, 11 Mar 2013 22:37:01 -0700 Subject: [PATCH] Make enum discriminants u64 instead of the host uint. --- src/librustc/metadata/decoder.rs | 6 ++-- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/trans/_match.rs | 4 +-- src/librustc/middle/trans/adt.rs | 47 +++++++++++++------------ src/librustc/middle/trans/base.rs | 4 +-- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/trans/expr.rs | 4 +-- src/librustc/middle/trans/reflect.rs | 2 +- src/librustc/middle/ty.rs | 14 ++++---- src/librustc/middle/typeck/check/mod.rs | 10 +++--- 10 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 9eb09806bc0..3fdd1587c0d 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -26,7 +26,7 @@ use middle::astencode::vtable_decoder_helpers; use std::hash::HashUtil; -use std::uint; +use std::u64; use std::io::WriterUtil; use std::io; use std::option; @@ -207,9 +207,9 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool { reader::tagged_docs(d, tag_items_data_item_reexport, f) } -fn variant_disr_val(d: ebml::Doc) -> Option { +fn variant_disr_val(d: ebml::Doc) -> Option { do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| { - do reader::with_doc_data(val_doc) |data| { uint::parse_bytes(data, 10u) } + do reader::with_doc_data(val_doc) |data| { u64::parse_bytes(data, 10u) } } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index dbed508348d..21eee26620c 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -292,7 +292,7 @@ fn encode_symbol(ecx: &EncodeContext, fn encode_disr_val(_: &EncodeContext, ebml_w: &mut writer::Encoder, - disr_val: uint) { + disr_val: ty::Disr) { ebml_w.start_tag(tag_disr_val); let s = disr_val.to_str(); ebml_w.writer.write(s.as_bytes()); diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 1eeafeacc6f..9a92d91ab50 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -245,7 +245,7 @@ pub enum VecLenOpt { // range) enum Opt { lit(Lit), - var(/* disr val */ uint, @adt::Repr), + var(ty::Disr, @adt::Repr), range(@ast::expr, @ast::expr), vec_len(/* length */ uint, VecLenOpt, /*range of matches*/(uint, uint)) } @@ -992,7 +992,7 @@ struct ExtractedBlock { fn extract_variant_args(bcx: @mut Block, repr: &adt::Repr, - disr_val: uint, + disr_val: ty::Disr, 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 a00cfa29123..010b2f8f9f4 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -55,6 +55,7 @@ use middle::trans::common::*; use middle::trans::machine; use middle::trans::type_of; use middle::ty; +use middle::ty::Disr; use syntax::ast; use util::ppaux::ty_to_str; @@ -64,7 +65,7 @@ use middle::trans::type_::Type; /// Representations. pub enum Repr { /// C-like enums; basically an int. - CEnum(uint, uint), // discriminant range + CEnum(Disr, Disr), // discriminant range /** * Single-case variants, and structs/tuples/records. * @@ -89,7 +90,7 @@ pub enum Repr { * is represented such that `None` is a null pointer and `Some` is the * identity function. */ - NullablePointer{ nonnull: Struct, nndiscr: uint, ptrfield: uint, + NullablePointer{ nonnull: Struct, nndiscr: Disr, ptrfield: uint, nullfields: ~[ty::t] } } @@ -140,7 +141,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: uint, tys: ~[ty::t] }; + struct Case { discr: Disr, tys: ~[ty::t] }; impl Case { fn is_zerolen(&self, cx: &mut CrateContext) -> bool { mk_struct(cx, self.tys, false).size == 0 @@ -177,7 +178,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) { + if !cases.iter().enumerate().all(|(i,c)| c.discr == (i as Disr)) { cx.sess.bug(fmt!("non-C-like enum %s with specified \ discriminants", ty::item_path_str(cx.tcx, def_id))) @@ -306,7 +307,7 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef) match *r { CEnum(min, max) => load_discr(bcx, scrutinee, min, max), Univariant(*) => C_uint(bcx.ccx(), 0), - General(ref cases) => load_discr(bcx, scrutinee, 0, cases.len() - 1), + General(ref cases) => load_discr(bcx, scrutinee, 0, (cases.len() - 1) as Disr), NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee), Type::enum_discrim(bcx.ccx())) @@ -314,7 +315,7 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef) } } -fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: uint, ptrfield: uint, +fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint, scrutinee: ValueRef) -> ValueRef { let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield])); @@ -323,7 +324,7 @@ fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: uint, ptrfield: } /// Helper for cases where the discriminant is simply loaded. -fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: uint, max: uint) +fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: Disr, max: Disr) -> ValueRef { let ptr = GEPi(bcx, scrutinee, [0, 0]); if max + 1 == min { @@ -347,16 +348,16 @@ fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: uint, max: uint) * * This should ideally be less tightly tied to `_match`. */ -pub fn trans_case(bcx: @mut Block, r: &Repr, discr: uint) -> _match::opt_result { +pub fn trans_case(bcx: @mut Block, r: &Repr, discr: Disr) -> _match::opt_result { match *r { CEnum(*) => { - _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr))) + _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr /*bad*/as uint))) } Univariant(*) => { bcx.ccx().sess.bug("no cases for univariants or structs") } General(*) => { - _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr))) + _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr /*bad*/as uint))) } NullablePointer{ _ } => { assert!(discr == 0 || discr == 1); @@ -370,11 +371,11 @@ pub fn trans_case(bcx: @mut Block, r: &Repr, discr: uint) -> _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: uint) { +pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr) { match *r { CEnum(min, max) => { assert!(min <= discr && discr <= max); - Store(bcx, C_uint(bcx.ccx(), discr), GEPi(bcx, val, [0, 0])) + Store(bcx, C_uint(bcx.ccx(), discr/*bad*/ as uint), GEPi(bcx, val, [0, 0])) } Univariant(ref st, true) => { assert_eq!(discr, 0); @@ -385,7 +386,7 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: uint) { assert_eq!(discr, 0); } General(*) => { - Store(bcx, C_uint(bcx.ccx(), discr), GEPi(bcx, val, [0, 0])) + Store(bcx, C_uint(bcx.ccx(), discr/*bad*/ as uint), GEPi(bcx, val, [0, 0])) } NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { if discr != nndiscr { @@ -401,7 +402,7 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: uint) { * 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: uint) -> uint { +pub fn num_args(r: &Repr, discr: Disr) -> uint { match *r { CEnum(*) => 0, Univariant(ref st, dtor) => { @@ -416,7 +417,7 @@ pub fn num_args(r: &Repr, discr: uint) -> 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: uint, +pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: Disr, 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 @@ -494,13 +495,13 @@ 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: uint, +pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: Disr, vals: &[ValueRef]) -> ValueRef { match *r { CEnum(min, max) => { assert_eq!(vals.len(), 0); assert!(min <= discr && discr <= max); - C_uint(ccx, discr) + C_uint(ccx, discr/*bad*/ as uint) } Univariant(ref st, _dro) => { assert_eq!(discr, 0); @@ -509,7 +510,7 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: uint, General(ref cases) => { let case = &cases[discr]; let max_sz = cases.iter().map(|x| x.size).max().unwrap(); - let discr_ty = C_uint(ccx, discr); + let discr_ty = C_uint(ccx, discr/*bad*/ as uint); let contents = build_const_struct(ccx, case, ~[discr_ty] + vals); C_struct(contents + &[padding(max_sz - case.size)]) @@ -581,15 +582,15 @@ 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) - -> uint { + -> Disr { match *r { - CEnum(*) => const_to_uint(val) as uint, + CEnum(*) => const_to_uint(val) as Disr, Univariant(*) => 0, - General(*) => const_to_uint(const_get_elt(ccx, val, [0])) as uint, + General(*) => const_to_uint(const_get_elt(ccx, val, [0])) as Disr, NullablePointer{ nndiscr, ptrfield, _ } => { 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 + (1 - nndiscr) as Disr } else { nndiscr } @@ -605,7 +606,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: uint, ix: uint) -> ValueRef { + _discr: Disr, 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 054c5bcbf8b..634e339e03d 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2014,7 +2014,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, _enum_id: ast::NodeId, variant: &ast::variant, args: &[ast::variant_arg], - disr: uint, + disr: ty::Disr, param_substs: Option<@param_substs>, llfndecl: ValueRef) { let _icx = push_ctxt("trans_enum_variant"); @@ -2063,7 +2063,7 @@ pub fn trans_enum_variant_or_tuple_like_struct( ccx: @mut CrateContext, ctor_id: ast::NodeId, args: &[A], - disr: uint, + disr: ty::Disr, param_substs: Option<@param_substs>, llfndecl: ValueRef) { diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 87d26fa5ba0..dc45632a2d3 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -453,7 +453,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_uint(cx, discr); + let iv = C_uint(cx, discr /*bad*/ as uint); 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 ab4fc8ed6d3..06c45e563c0 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1118,7 +1118,7 @@ pub fn trans_local_var(bcx: @mut Block, def: ast::def) -> Datum { pub fn with_field_tys(tcx: ty::ctxt, ty: ty::t, node_id_opt: Option, - op: &fn(uint, (&[ty::field])) -> R) -> R { + op: &fn(ty::Disr, (&[ty::field])) -> R) -> R { match ty::get(ty).sty { ty::ty_struct(did, ref substs) => { op(0, struct_fields(tcx, did, substs)) @@ -1235,7 +1235,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: uint, +fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: ty::Disr, fields: &[(uint, @ast::expr)], optbase: Option, dest: Dest) -> @mut Block { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index dd1b041ef80..a58cf35c015 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -317,7 +317,7 @@ impl Reflector { for (i, v) in variants.iter().enumerate() { let name = ccx.sess.str_of(v.name); let variant_args = ~[this.c_uint(i), - this.c_uint(v.disr_val), + this.c_uint(v.disr_val /*bad*/ as uint), 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 39ffffa25c7..6593e5632fb 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -48,7 +48,9 @@ use syntax::abi::AbiSet; use syntax; use extra::enum_set::{EnumSet, CLike}; -pub static INITIAL_DISCRIMINANT_VALUE: uint = 0; +pub type Disr = u64; + +pub static INITIAL_DISCRIMINANT_VALUE: Disr = 0; // Data types @@ -3803,7 +3805,7 @@ pub struct VariantInfo { ctor_ty: t, name: ast::ident, id: ast::def_id, - disr_val: uint, + disr_val: Disr, vis: visibility } @@ -3814,7 +3816,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: uint) -> VariantInfo { + discriminant: Disr) -> VariantInfo { let ctor_ty = node_id_to_type(cx, ast_variant.node.id); @@ -4008,7 +4010,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[@VariantInfo] { node: ast::item_enum(ref enum_definition, _), _ }, _) => { - let mut last_discriminant: Option = None; + let mut last_discriminant: Option = None; @enum_definition.variants.iter().map(|variant| { let mut discriminant = match last_discriminant { @@ -4018,8 +4020,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 uint, - Ok(const_eval::const_uint(val)) => discriminant = val as uint, + Ok(const_eval::const_int(val)) => discriminant = val as Disr, + Ok(const_eval::const_uint(val)) => discriminant = val as Disr, 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 5ce82ad6e2c..a839ea976e6 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -83,7 +83,7 @@ use middle::pat_util; use middle::lint::unreachable_code; use middle::ty::{FnSig, VariantInfo}; use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty}; -use middle::ty::{substs, param_ty, ExprTyProvider}; +use middle::ty::{substs, param_ty, Disr, ExprTyProvider}; use middle::ty; use middle::typeck::astconv::AstConv; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; @@ -3000,8 +3000,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: ~[uint] = ~[]; - let mut prev_disr_val: Option = None; + let mut disr_vals: ~[ty::Disr] = ~[]; + let mut prev_disr_val: Option = None; for v in vs.iter() { @@ -3024,8 +3024,8 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, // 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 uint, - Ok(const_eval::const_uint(val)) => current_disr_val = val as uint, + Ok(const_eval::const_int(val)) => current_disr_val = val as Disr, + Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr, Ok(_) => { ccx.tcx.sess.span_err(e.span, "expected signed integer constant"); }