Auto merge of #30931 - oli-obk:trans_disr_newtype, r=arielb1

This is groundwork for #30587 (typestrong constant integrals), but imo it's a change that in itself is good, too, since we don't just juggle `u64`s around anymore.

`ty::Disr` will be changed to a `ConstInt` in #30587
This commit is contained in:
bors 2016-01-17 10:31:47 +00:00
commit 0b524edb04
19 changed files with 173 additions and 101 deletions

View File

@ -215,6 +215,7 @@ use trans::expr::{self, Dest};
use trans::monomorphize;
use trans::tvec;
use trans::type_of;
use trans::Disr;
use middle::ty::{self, Ty};
use session::config::NoDebugInfo;
use util::common::indenter;
@ -249,7 +250,7 @@ impl<'a> ConstantExpr<'a> {
enum Opt<'a, 'tcx> {
ConstantValue(ConstantExpr<'a>, DebugLoc),
ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>, DebugLoc),
Variant(ty::Disr, Rc<adt::Repr<'tcx>>, DefId, DebugLoc),
Variant(Disr, Rc<adt::Repr<'tcx>>, DefId, DebugLoc),
SliceLengthEqual(usize, DebugLoc),
SliceLengthGreaterOrEqual(/* prefix length */ usize,
/* suffix length */ usize,
@ -670,7 +671,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match opt_def {
Some(def::DefVariant(enum_id, var_id, _)) => {
let variant = tcx.lookup_adt_def(enum_id).variant_with_id(var_id);
Variant(variant.disr_val,
Variant(Disr::from(variant.disr_val),
adt::represent_node(bcx, cur.id),
var_id,
debug_loc)
@ -704,7 +705,7 @@ struct ExtractedBlock<'blk, 'tcx: 'blk> {
fn extract_variant_args<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
repr: &adt::Repr<'tcx>,
disr_val: ty::Disr,
disr_val: Disr,
val: MatchInput)
-> ExtractedBlock<'blk, 'tcx> {
let _icx = push_ctxt("match::extract_variant_args");
@ -1189,7 +1190,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
};
let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) {
let repr = adt::represent_type(bcx.ccx(), left_ty);
let arg_count = adt::num_args(&*repr, 0);
let arg_count = adt::num_args(&*repr, Disr(0));
let (arg_count, struct_val) = if type_is_sized(bcx.tcx(), left_ty) {
(arg_count, val.val)
} else {
@ -1201,7 +1202,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
};
let mut field_vals: Vec<ValueRef> = (0..arg_count).map(|ix|
// By definition, these are all sized
adt::trans_field_ptr(bcx, &*repr, adt::MaybeSizedValue::sized(struct_val), 0, ix)
adt::trans_field_ptr(bcx, &*repr, adt::MaybeSizedValue::sized(struct_val), Disr(0), ix)
).collect();
match left_ty.sty {
@ -1217,7 +1218,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let meta = Load(bcx, expr::get_meta(bcx, val.val));
let struct_val = adt::MaybeSizedValue::unsized_(struct_val, meta);
let data = adt::trans_field_ptr(bcx, &*repr, struct_val, 0, arg_count);
let data = adt::trans_field_ptr(bcx, &*repr, struct_val, Disr(0), arg_count);
Store(bcx, data, expr::get_dataptr(bcx, scratch));
Store(bcx, meta, expr::get_meta(bcx, scratch));
field_vals.push(scratch);
@ -1855,7 +1856,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let vinfo = ccx.tcx().lookup_adt_def(enum_id).variant_with_id(var_id);
let args = extract_variant_args(bcx,
&*repr,
vinfo.disr_val,
Disr::from(vinfo.disr_val),
val);
if let Some(ref sub_pat) = *sub_pats {
for (i, &argval) in args.vals.iter().enumerate() {
@ -1878,7 +1879,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let val = adt::MaybeSizedValue::sized(val.val);
for (i, elem) in elems.iter().enumerate() {
let fldptr = adt::trans_field_ptr(bcx, &*repr,
val, 0, i);
val, Disr(0), i);
bcx = bind_irrefutable_pat(
bcx,
&**elem,
@ -1937,7 +1938,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let repr = adt::represent_node(bcx, pat.id);
let val = adt::MaybeSizedValue::sized(val.val);
for (i, elem) in elems.iter().enumerate() {
let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i);
let fldptr = adt::trans_field_ptr(bcx, &*repr, val, Disr(0), i);
bcx = bind_irrefutable_pat(
bcx,
&**elem,

View File

@ -42,6 +42,7 @@
//! taken to it, implementing them for Rust seems difficult.
pub use self::Repr::*;
use super::Disr;
use std;
use std::rc::Rc;
@ -50,7 +51,6 @@ use llvm::{ValueRef, True, IntEQ, IntNE};
use back::abi::FAT_PTR_ADDR;
use middle::subst;
use middle::ty::{self, Ty};
use middle::ty::Disr;
use syntax::ast;
use syntax::attr;
use syntax::attr::IntType;
@ -308,12 +308,12 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
if !dtor && cases.iter().all(|c| c.tys.is_empty()) {
// All bodies empty -> intlike
let discrs: Vec<u64> = cases.iter().map(|c| c.discr).collect();
let discrs: Vec<_> = cases.iter().map(|c| Disr::from(c.discr)).collect();
let bounds = IntBounds {
ulo: *discrs.iter().min().unwrap(),
uhi: *discrs.iter().max().unwrap(),
slo: discrs.iter().map(|n| *n as i64).min().unwrap(),
shi: discrs.iter().map(|n| *n as i64).max().unwrap()
ulo: discrs.iter().min().unwrap().0,
uhi: discrs.iter().max().unwrap().0,
slo: discrs.iter().map(|n| n.0 as i64).min().unwrap(),
shi: discrs.iter().map(|n| n.0 as i64).max().unwrap()
};
return mk_cenum(cx, hint, &bounds);
}
@ -321,7 +321,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// 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 Disr)) {
if !cases.iter().enumerate().all(|(i,c)| c.discr == Disr::from(i)) {
cx.sess().bug(&format!("non-C-like enum {} with specified \
discriminants",
cx.tcx().item_path_str(def.did)));
@ -347,7 +347,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
match cases[discr].find_ptr(cx) {
Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
return RawNullablePointer {
nndiscr: discr as Disr,
nndiscr: Disr::from(discr),
nnty: st.fields[0],
nullfields: cases[1 - discr].tys.clone()
};
@ -356,7 +356,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
discrfield.push(0);
discrfield.reverse();
return StructWrappedNullablePointer {
nndiscr: discr as Disr,
nndiscr: Disr::from(discr),
nonnull: st,
discrfield: discrfield,
nullfields: cases[1 - discr].tys.clone()
@ -564,7 +564,7 @@ fn get_cases<'tcx>(tcx: &ty::ctxt<'tcx>,
let field_tys = vi.fields.iter().map(|field| {
monomorphize::field_ty(tcx, substs, field)
}).collect();
Case { discr: vi.disr_val, tys: field_tys }
Case { discr: Disr::from(vi.disr_val), tys: field_tys }
}).collect()
}
@ -605,8 +605,8 @@ fn mk_cenum<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
-> Repr<'tcx> {
let it = range_to_inttype(cx, hint, bounds);
match it {
attr::SignedInt(_) => CEnum(it, bounds.slo as Disr, bounds.shi as Disr),
attr::UnsignedInt(_) => CEnum(it, bounds.ulo, bounds.uhi)
attr::SignedInt(_) => CEnum(it, Disr(bounds.slo as u64), Disr(bounds.shi as u64)),
attr::UnsignedInt(_) => CEnum(it, Disr(bounds.ulo), Disr(bounds.uhi))
}
}
@ -923,11 +923,11 @@ pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
CEnum(ity, min, max) => load_discr(bcx, ity, scrutinee, min, max),
General(ity, ref cases, _) => {
let ptr = StructGEP(bcx, scrutinee, 0);
load_discr(bcx, ity, ptr, 0, (cases.len() - 1) as Disr)
load_discr(bcx, ity, ptr, Disr(0), Disr(cases.len() as u64 - 1))
}
Univariant(..) => C_u8(bcx.ccx(), 0),
RawNullablePointer { nndiscr, nnty, .. } => {
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
let cmp = if nndiscr == Disr(0) { IntEQ } else { IntNE };
let llptrty = type_of::sizing_type_of(bcx.ccx(), nnty);
ICmp(bcx, cmp, Load(bcx, scrutinee), C_null(llptrty), DebugLoc::None)
}
@ -945,7 +945,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, discrfield: &Disc
scrutinee: ValueRef) -> ValueRef {
let llptrptr = GEPi(bcx, scrutinee, &discrfield[..]);
let llptr = Load(bcx, llptrptr);
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
let cmp = if nndiscr == Disr(0) { IntEQ } else { IntNE };
ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)), DebugLoc::None)
}
@ -957,10 +957,10 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
let bits = machine::llbitsize_of_real(bcx.ccx(), llty);
assert!(bits <= 64);
let bits = bits as usize;
let mask = (!0u64 >> (64 - bits)) as Disr;
let mask = Disr(!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 {
if max.wrapping_add(Disr(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
@ -969,7 +969,7 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
} else {
// llvm::ConstantRange can deal with ranges that wrap around,
// so an overflow on (max + 1) is fine.
LoadRangeAssert(bcx, ptr, min, (max.wrapping_add(1)), /* signed: */ True)
LoadRangeAssert(bcx, ptr, min, max.wrapping_add(Disr(1)), /* signed: */ True)
}
}
@ -981,18 +981,18 @@ pub fn trans_case<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr, discr: Disr)
-> ValueRef {
match *r {
CEnum(ity, _, _) => {
C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true)
C_integral(ll_inttype(bcx.ccx(), ity), discr.0, true)
}
General(ity, _, _) => {
C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true)
C_integral(ll_inttype(bcx.ccx(), ity), discr.0, true)
}
Univariant(..) => {
bcx.ccx().sess().bug("no cases for univariants or structs")
}
RawNullablePointer { .. } |
StructWrappedNullablePointer { .. } => {
assert!(discr == 0 || discr == 1);
C_bool(bcx.ccx(), discr != 0)
assert!(discr == Disr(0) || discr == Disr(1));
C_bool(bcx.ccx(), discr != Disr(0))
}
}
}
@ -1004,20 +1004,20 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
match *r {
CEnum(ity, min, max) => {
assert_discr_in_range(ity, min, max, discr);
Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),
Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr.0, true),
val);
}
General(ity, ref cases, dtor) => {
if dtor_active(dtor) {
let ptr = trans_field_ptr(bcx, r, MaybeSizedValue::sized(val), discr,
cases[discr as usize].fields.len() - 2);
cases[discr.0 as usize].fields.len() - 2);
Store(bcx, C_u8(bcx.ccx(), DTOR_NEEDED), ptr);
}
Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),
Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr.0, true),
StructGEP(bcx, val, 0));
}
Univariant(ref st, dtor) => {
assert_eq!(discr, 0);
assert_eq!(discr, Disr(0));
if dtor_active(dtor) {
Store(bcx, C_u8(bcx.ccx(), DTOR_NEEDED),
StructGEP(bcx, val, st.fields.len() - 1));
@ -1041,8 +1041,14 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) {
match ity {
attr::UnsignedInt(_) => assert!(min <= discr && discr <= max),
attr::SignedInt(_) => assert!(min as i64 <= discr as i64 && discr as i64 <= max as i64)
attr::UnsignedInt(_) => {
assert!(min <= discr);
assert!(discr <= max)
},
attr::SignedInt(_) => {
assert!(min.0 as i64 <= discr.0 as i64);
assert!(discr.0 as i64 <= max.0 as i64);
},
}
}
@ -1052,11 +1058,11 @@ pub fn num_args(r: &Repr, discr: Disr) -> usize {
match *r {
CEnum(..) => 0,
Univariant(ref st, dtor) => {
assert_eq!(discr, 0);
assert_eq!(discr, Disr(0));
st.fields.len() - (if dtor_active(dtor) { 1 } else { 0 })
}
General(_, ref cases, dtor) => {
cases[discr as usize].fields.len() - 1 - (if dtor_active(dtor) { 1 } else { 0 })
cases[discr.0 as usize].fields.len() - 1 - (if dtor_active(dtor) { 1 } else { 0 })
}
RawNullablePointer { nndiscr, ref nullfields, .. } => {
if discr == nndiscr { 1 } else { nullfields.len() }
@ -1079,11 +1085,11 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
bcx.ccx().sess().bug("element access in C-like enum")
}
Univariant(ref st, _dtor) => {
assert_eq!(discr, 0);
assert_eq!(discr, Disr(0));
struct_field_ptr(bcx, st, val, ix, false)
}
General(_, ref cases, _) => {
struct_field_ptr(bcx, &cases[discr as usize], val, ix + 1, true)
struct_field_ptr(bcx, &cases[discr.0 as usize], val, ix + 1, true)
}
RawNullablePointer { nndiscr, ref nullfields, .. } |
StructWrappedNullablePointer { nndiscr, ref nullfields, .. } if discr != nndiscr => {
@ -1326,12 +1332,12 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
CEnum(ity, min, max) => {
assert_eq!(vals.len(), 0);
assert_discr_in_range(ity, min, max, discr);
C_integral(ll_inttype(ccx, ity), discr as u64, true)
C_integral(ll_inttype(ccx, ity), discr.0, true)
}
General(ity, ref cases, _) => {
let case = &cases[discr as usize];
let case = &cases[discr.0 as usize];
let (max_sz, _) = union_size_and_align(&cases[..]);
let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
let lldiscr = C_integral(ll_inttype(ccx, ity), discr.0 as u64, true);
let mut f = vec![lldiscr];
f.extend_from_slice(vals);
let mut contents = build_const_struct(ccx, case, &f[..]);
@ -1339,7 +1345,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
C_struct(ccx, &contents[..], false)
}
Univariant(ref st, _dro) => {
assert!(discr == 0);
assert_eq!(discr, Disr(0));
let contents = build_const_struct(ccx, st, vals);
C_struct(ccx, &contents[..], st.packed)
}
@ -1444,17 +1450,17 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef) -> Disr {
match *r {
CEnum(ity, _, _) => {
match ity {
attr::SignedInt(..) => const_to_int(val) as Disr,
attr::UnsignedInt(..) => const_to_uint(val) as Disr
attr::SignedInt(..) => Disr(const_to_int(val) as u64),
attr::UnsignedInt(..) => Disr(const_to_uint(val)),
}
}
General(ity, _, _) => {
match ity {
attr::SignedInt(..) => const_to_int(const_get_elt(ccx, val, &[0])) as Disr,
attr::UnsignedInt(..) => const_to_uint(const_get_elt(ccx, val, &[0])) as Disr
attr::SignedInt(..) => Disr(const_to_int(const_get_elt(ccx, val, &[0])) as u64),
attr::UnsignedInt(..) => Disr(const_to_uint(const_get_elt(ccx, val, &[0])))
}
}
Univariant(..) => 0,
Univariant(..) => Disr(0),
RawNullablePointer { .. } | StructWrappedNullablePointer { .. } => {
ccx.sess().bug("const discrim access of non c-like enum")
}

View File

@ -85,6 +85,7 @@ use trans::type_::Type;
use trans::type_of;
use trans::type_of::*;
use trans::value::Value;
use trans::Disr;
use util::common::indenter;
use util::sha2::Sha256;
use util::nodemap::{NodeMap, NodeSet};
@ -489,7 +490,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
for (i, field) in variant.fields.iter().enumerate() {
let arg = monomorphize::field_ty(tcx, substs, field);
cx = f(cx,
adt::trans_field_ptr(cx, repr, av, variant.disr_val, i),
adt::trans_field_ptr(cx, repr, av, Disr::from(variant.disr_val), i),
arg);
}
return cx;
@ -509,7 +510,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
let repr = adt::represent_type(cx.ccx(), t);
let VariantInfo { fields, discr } = VariantInfo::from_ty(cx.tcx(), t, None);
for (i, &Field(_, field_ty)) in fields.iter().enumerate() {
let llfld_a = adt::trans_field_ptr(cx, &*repr, value, discr, i);
let llfld_a = adt::trans_field_ptr(cx, &*repr, value, Disr::from(discr), i);
let val = if common::type_is_sized(cx.tcx(), field_ty) {
llfld_a
@ -525,7 +526,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
ty::TyClosure(_, ref substs) => {
let repr = adt::represent_type(cx.ccx(), t);
for (i, upvar_ty) in substs.upvar_tys.iter().enumerate() {
let llupvar = adt::trans_field_ptr(cx, &*repr, value, 0, i);
let llupvar = adt::trans_field_ptr(cx, &*repr, value, Disr(0), i);
cx = f(cx, llupvar, upvar_ty);
}
}
@ -541,7 +542,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
ty::TyTuple(ref args) => {
let repr = adt::represent_type(cx.ccx(), t);
for (i, arg) in args.iter().enumerate() {
let llfld_a = adt::trans_field_ptr(cx, &*repr, value, 0, i);
let llfld_a = adt::trans_field_ptr(cx, &*repr, value, Disr(0), i);
cx = f(cx, llfld_a, *arg);
}
}
@ -588,7 +589,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
let variant_cx = fcx.new_temp_block(&format!("enum-iter-variant-{}",
&variant.disr_val
.to_string()));
let case_val = adt::trans_case(cx, &*repr, variant.disr_val);
let case_val = adt::trans_case(cx, &*repr, Disr::from(variant.disr_val));
AddCase(llswitch, case_val, variant_cx.llbb);
let variant_cx = iter_variant(variant_cx,
&*repr,
@ -720,8 +721,8 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
continue;
}
let src_f = adt::trans_field_ptr(bcx, &src_repr, src, 0, i);
let dst_f = adt::trans_field_ptr(bcx, &dst_repr, dst, 0, i);
let src_f = adt::trans_field_ptr(bcx, &src_repr, src, Disr(0), i);
let dst_f = adt::trans_field_ptr(bcx, &dst_repr, dst, Disr(0), i);
if src_fty == dst_fty {
memcpy_ty(bcx, dst_f, src_f, src_fty);
} else {
@ -1022,11 +1023,11 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) ->
}
let val = if t.is_bool() {
LoadRangeAssert(cx, ptr, 0, 2, llvm::False)
LoadRangeAssert(cx, ptr, Disr(0), Disr(2), llvm::False)
} else if t.is_char() {
// a char is a Unicode codepoint, and so takes values from 0
// to 0x10FFFF inclusive only.
LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
LoadRangeAssert(cx, ptr, Disr(0), Disr(0x10FFFF + 1), llvm::False)
} else if (t.is_region_ptr() || t.is_unique()) && !common::type_is_fat_ptr(cx.tcx(), t) {
LoadNonNull(cx, ptr)
} else {
@ -2111,7 +2112,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
pub fn trans_enum_variant<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ctor_id: ast::NodeId,
disr: ty::Disr,
disr: Disr,
param_substs: &'tcx Substs<'tcx>,
llfndecl: ValueRef) {
let _icx = push_ctxt("trans_enum_variant");
@ -2121,7 +2122,7 @@ pub fn trans_enum_variant<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
ctor_ty: Ty<'tcx>,
disr: ty::Disr,
disr: Disr,
args: callee::CallArgs,
dest: expr::Dest,
debug_loc: DebugLoc)
@ -2197,12 +2198,12 @@ pub fn trans_tuple_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
llfndecl: ValueRef) {
let _icx = push_ctxt("trans_tuple_struct");
trans_enum_variant_or_tuple_like_struct(ccx, ctor_id, 0, param_substs, llfndecl);
trans_enum_variant_or_tuple_like_struct(ccx, ctor_id, Disr(0), param_substs, llfndecl);
}
fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ctor_id: ast::NodeId,
disr: ty::Disr,
disr: Disr,
param_substs: &'tcx Substs<'tcx>,
llfndecl: ValueRef) {
let ctor_ty = ccx.tcx().node_id_to_type(ctor_id);
@ -2233,7 +2234,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
let repr = adt::represent_type(ccx, result_ty.unwrap());
let mut llarg_idx = fcx.arg_offset() as c_uint;
for (i, arg_ty) in arg_tys.into_iter().enumerate() {
let lldestptr = adt::trans_field_ptr(bcx, &*repr, dest_val, disr, i);
let lldestptr = adt::trans_field_ptr(bcx, &*repr, dest_val, Disr::from(disr), i);
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
Store(bcx,
get_param(fcx.llfn, llarg_idx),

View File

@ -21,6 +21,7 @@ use syntax::codemap::Span;
use trans::builder::Builder;
use trans::type_::Type;
use trans::debuginfo::DebugLoc;
use trans::Disr;
use libc::{c_uint, c_char};
@ -577,8 +578,8 @@ pub fn AtomicLoad(cx: Block, pointer_val: ValueRef, order: AtomicOrdering) -> Va
}
pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: u64,
hi: u64, signed: llvm::Bool) -> ValueRef {
pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: Disr,
hi: Disr, signed: llvm::Bool) -> ValueRef {
if cx.unreachable.get() {
let ccx = cx.fcx.ccx;
let ty = val_ty(pointer_val);
@ -591,7 +592,7 @@ pub fn LoadRangeAssert(cx: Block, pointer_val: ValueRef, lo: u64,
llvm::LLVMGetUndef(eltty.to_ref())
}
} else {
B(cx).load_range_assert(pointer_val, lo, hi, signed)
B(cx).load_range_assert(pointer_val, lo.0, hi.0, signed)
}
}

View File

@ -50,6 +50,7 @@ use trans::meth;
use trans::monomorphize;
use trans::type_::Type;
use trans::type_of;
use trans::Disr;
use middle::ty::{self, Ty, TypeFoldable};
use middle::ty::MethodCall;
use rustc_front::hir;
@ -68,7 +69,7 @@ pub struct MethodData {
pub enum CalleeData<'tcx> {
// Constructor for enum variant/tuple-like-struct
// i.e. Some, Ok
NamedTupleConstructor(ty::Disr),
NamedTupleConstructor(Disr),
// Represents a (possibly monomorphized) top-level fn item or method
// item. Note that this is just the fn-ptr and is not a Rust closure
@ -151,7 +152,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
} => {
Callee {
bcx: bcx,
data: NamedTupleConstructor(0),
data: NamedTupleConstructor(Disr(0)),
ty: expr_ty
}
}
@ -195,14 +196,14 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
Callee {
bcx: bcx,
data: NamedTupleConstructor(vinfo.disr_val),
data: NamedTupleConstructor(Disr::from(vinfo.disr_val)),
ty: expr_ty
}
}
def::DefStruct(_) => {
Callee {
bcx: bcx,
data: NamedTupleConstructor(0),
data: NamedTupleConstructor(Disr(0)),
ty: expr_ty
}
}
@ -863,7 +864,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
bcx,
field_type,
|srcval| {
adt::trans_field_ptr(bcx, repr_ptr, srcval, 0, i)
adt::trans_field_ptr(bcx, repr_ptr, srcval, Disr(0), i)
}).to_expr_datum();
bcx = trans_arg_datum(bcx,
field_type,

View File

@ -26,6 +26,7 @@ use trans::declare;
use trans::expr;
use trans::monomorphize::{MonoId};
use trans::type_of::*;
use trans::Disr;
use middle::ty;
use session::config::FullDebugInfo;
@ -242,7 +243,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
for (i, freevar) in freevars.iter().enumerate() {
let datum = expr::trans_local_var(bcx, freevar.def);
let upvar_slot_dest = adt::trans_field_ptr(
bcx, &*repr, adt::MaybeSizedValue::sized(dest_addr), 0, i);
bcx, &*repr, adt::MaybeSizedValue::sized(dest_addr), Disr(0), i);
let upvar_id = ty::UpvarId { var_id: freevar.def.var_id(),
closure_expr_id: id };
match tcx.upvar_capture(upvar_id).unwrap() {
@ -254,7 +255,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
}
}
}
adt::trans_set_discr(bcx, &*repr, dest_addr, 0);
adt::trans_set_discr(bcx, &*repr, dest_addr, Disr(0));
Some(bcx)
}

View File

@ -161,6 +161,8 @@ pub fn gensym_name(name: &str) -> ast::Name {
*
*/
use trans::Disr;
#[derive(Copy, Clone)]
pub struct NodeIdAndSpan {
pub id: ast::NodeId,
@ -177,7 +179,7 @@ pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>);
/// The concrete version of ty::VariantDef
pub struct VariantInfo<'tcx> {
pub discr: ty::Disr,
pub discr: Disr,
pub fields: Vec<Field<'tcx>>
}
@ -195,7 +197,7 @@ impl<'tcx> VariantInfo<'tcx> {
};
VariantInfo {
discr: variant.disr_val,
discr: Disr::from(variant.disr_val),
fields: variant.fields.iter().map(|f| {
Field(f.name, monomorphize::field_ty(tcx, substs, f))
}).collect()
@ -204,7 +206,7 @@ impl<'tcx> VariantInfo<'tcx> {
ty::TyTuple(ref v) => {
VariantInfo {
discr: 0,
discr: Disr(0),
fields: v.iter().enumerate().map(|(i, &t)| {
Field(token::intern(&i.to_string()), t)
}).collect()

View File

@ -37,6 +37,7 @@ use trans::declare;
use trans::monomorphize;
use trans::type_::Type;
use trans::type_of;
use trans::Disr;
use middle::subst::Substs;
use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
use middle::ty::adjustment::AdjustUnsafeFnPointer;
@ -740,7 +741,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
(CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
let repr = adt::represent_type(cx, t_expr);
let discr = adt::const_get_discrim(cx, &*repr, v);
let iv = C_integral(cx.int_type(), discr, false);
let iv = C_integral(cx.int_type(), discr.0, false);
let s = adt::is_discr_signed(&*repr) as Bool;
llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
},
@ -807,7 +808,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
hir::ExprTup(ref es) => {
let repr = adt::represent_type(cx, ety);
let vals = try!(map_list(&es[..]));
adt::trans_const(cx, &*repr, 0, &vals[..])
adt::trans_const(cx, &*repr, Disr(0), &vals[..])
},
hir::ExprStruct(_, ref fs, ref base_opt) => {
let repr = adt::represent_type(cx, ety);
@ -898,7 +899,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
match vinfo.kind() {
ty::VariantKind::Unit => {
let repr = adt::represent_type(cx, ety);
adt::trans_const(cx, &*repr, vinfo.disr_val, &[])
adt::trans_const(cx, &*repr, Disr::from(vinfo.disr_val), &[])
}
ty::VariantKind::Tuple => {
expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
@ -952,7 +953,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
C_vector(&arg_vals[..])
} else {
let repr = adt::represent_type(cx, ety);
adt::trans_const(cx, &*repr, 0, &arg_vals[..])
adt::trans_const(cx, &*repr, Disr(0), &arg_vals[..])
}
}
def::DefVariant(enum_did, variant_did, _) => {
@ -960,7 +961,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let vinfo = cx.tcx().lookup_adt_def(enum_did).variant_with_id(variant_did);
adt::trans_const(cx,
&*repr,
vinfo.disr_val,
Disr::from(vinfo.disr_val),
&arg_vals[..])
}
_ => cx.sess().span_bug(e.span, "expected a struct, variant, or const fn def"),

View File

@ -1341,7 +1341,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
// DWARF representation of enums uniform.
// First create a description of the artificial wrapper struct:
let non_null_variant = &adt.variants[non_null_variant_index as usize];
let non_null_variant = &adt.variants[non_null_variant_index.0 as usize];
let non_null_variant_name = non_null_variant.name.as_str();
// The llvm type and metadata of the pointer
@ -1389,7 +1389,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
// Encode the information about the null variant in the union
// member's name.
let null_variant_index = (1 - non_null_variant_index) as usize;
let null_variant_index = (1 - non_null_variant_index.0) as usize;
let null_variant_name = adt.variants[null_variant_index].name;
let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
0,
@ -1415,7 +1415,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
describe_enum_variant(cx,
self.enum_type,
struct_def,
&adt.variants[nndiscr as usize],
&adt.variants[nndiscr.0 as usize],
OptimizedDiscriminant,
self.containing_scope,
self.span);
@ -1430,7 +1430,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
// Encode the information about the null variant in the union
// member's name.
let null_variant_index = (1 - nndiscr) as usize;
let null_variant_index = (1 - nndiscr.0) as usize;
let null_variant_name = adt.variants[null_variant_index].name;
let discrfield = discrfield.iter()
.skip(1)

View File

@ -0,0 +1,49 @@
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub struct Disr(pub u64);
impl Disr {
pub fn wrapping_add(self, other: Self) -> Self {
Disr(self.0.wrapping_add(other.0))
}
}
impl ::std::ops::BitAnd for Disr {
type Output = Disr;
fn bitand(self, other: Self) -> Self {
Disr(self.0 & other.0)
}
}
impl From<::middle::ty::Disr> for Disr {
fn from(i: ::middle::ty::Disr) -> Disr {
Disr(i)
}
}
impl From<usize> for Disr {
fn from(i: usize) -> Disr {
Disr(i as u64)
}
}
impl PartialOrd for Disr {
fn partial_cmp(&self, other: &Disr) -> Option<::std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl Ord for Disr {
fn cmp(&self, other: &Disr) -> ::std::cmp::Ordering {
self.0.cmp(&other.0)
}
}

View File

@ -71,6 +71,7 @@ use trans::machine;
use trans::meth;
use trans::tvec;
use trans::type_of;
use trans::Disr;
use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer};
use middle::ty::adjustment::{AdjustUnsafeFnPointer, CustomCoerceUnsized};
use middle::ty::{self, Ty};
@ -549,8 +550,8 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let iter = src_fields.iter().zip(target_fields).enumerate();
for (i, (src_ty, target_ty)) in iter {
let ll_source = adt::trans_field_ptr(bcx, &repr_source, source_val, 0, i);
let ll_target = adt::trans_field_ptr(bcx, &repr_target, target_val, 0, i);
let ll_source = adt::trans_field_ptr(bcx, &repr_source, source_val, Disr(0), i);
let ll_target = adt::trans_field_ptr(bcx, &repr_target, target_val, Disr(0), i);
// If this is the field we need to coerce, recurse on it.
if i == coerce_index {
@ -1154,7 +1155,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
args.iter().enumerate().map(|(i, arg)| (i, &**arg)).collect();
trans_adt(bcx,
expr_ty(bcx, expr),
0,
Disr(0),
&numbered_fields[..],
None,
dest,
@ -1295,7 +1296,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Nullary variant.
let ty = expr_ty(bcx, ref_expr);
let repr = adt::represent_type(bcx.ccx(), ty);
adt::trans_set_discr(bcx, &*repr, lldest, variant.disr_val);
adt::trans_set_discr(bcx, &*repr, lldest, Disr::from(variant.disr_val));
return bcx;
}
}
@ -1304,7 +1305,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match ty.sty {
ty::TyStruct(def, _) if def.has_dtor() => {
let repr = adt::represent_type(bcx.ccx(), ty);
adt::trans_set_discr(bcx, &*repr, lldest, 0);
adt::trans_set_discr(bcx, &*repr, lldest, Disr(0));
}
_ => {}
}
@ -1466,7 +1467,7 @@ pub struct StructBaseInfo<'a, 'tcx> {
/// which remaining fields are copied; see comments on `StructBaseInfo`.
pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
ty: Ty<'tcx>,
discr: ty::Disr,
discr: Disr,
fields: &[(usize, &hir::Expr)],
optbase: Option<StructBaseInfo<'a, 'tcx>>,
dest: Dest,
@ -1534,7 +1535,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
debug_location.apply(bcx.fcx);
// Second, trans the base to the dest.
assert_eq!(discr, 0);
assert_eq!(discr, Disr(0));
let addr = adt::MaybeSizedValue::sized(addr);
match expr_kind(bcx.tcx(), &*base.expr) {

View File

@ -27,6 +27,7 @@ use trans::monomorphize;
use trans::type_::Type;
use trans::type_of::*;
use trans::type_of;
use trans::Disr;
use middle::infer;
use middle::ty::{self, Ty};
use middle::subst::Substs;
@ -334,7 +335,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
llarg_rust
} else {
if passed_arg_tys[i].is_bool() {
let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
let val = LoadRangeAssert(bcx, llarg_rust, Disr(0), Disr(2), llvm::False);
Trunc(bcx, val, Type::i1(bcx.ccx()))
} else {
Load(bcx, llarg_rust)

View File

@ -36,6 +36,7 @@ use trans::type_of;
use trans::machine;
use trans::type_::Type;
use middle::ty::{self, Ty, TypeFoldable};
use trans::Disr;
use middle::subst::Substs;
use rustc::dep_graph::DepNode;
use rustc_front::hir;
@ -848,7 +849,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let arg = adt::MaybeSizedValue::sized(llarg);
(0..contents.len())
.map(|i| {
Load(bcx, adt::trans_field_ptr(bcx, repr_ptr, arg, 0, i))
Load(bcx, adt::trans_field_ptr(bcx, repr_ptr, arg, Disr(0), i))
})
.collect()
}

View File

@ -18,6 +18,7 @@ use trans::common::{self, Block};
use trans::debuginfo::DebugLoc;
use trans::type_of;
use trans::type_::Type;
use trans::Disr;
use super::MirContext;
use super::operand::OperandValue::{FatPtr, Immediate, Ref};
@ -60,7 +61,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
let switch = build::Switch(bcx, discr, unreachable_blk.llbb, targets.len());
assert_eq!(adt_def.variants.len(), targets.len());
for (adt_variant, target) in adt_def.variants.iter().zip(targets) {
let llval = adt::trans_case(bcx, &*repr, adt_variant.disr_val);
let llval = adt::trans_case(bcx, &*repr, Disr::from(adt_variant.disr_val));
let llbb = self.llblock(*target);
build::AddCase(switch, llval, llbb)

View File

@ -20,6 +20,7 @@ use trans::debuginfo::DebugLoc;
use trans::machine;
use trans::type_of;
use llvm;
use trans::Disr;
use std::ptr;
@ -137,7 +138,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
} else {
adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
};
(adt::trans_field_ptr(bcx, &base_repr, base, discr, field.index()),
(adt::trans_field_ptr(bcx, &base_repr, base, Disr(discr), field.index()),
if is_sized {
ptr::null_mut()
} else {

View File

@ -25,6 +25,7 @@ use trans::machine;
use trans::type_::Type;
use trans::type_of;
use trans::tvec;
use trans::Disr;
use super::MirContext;
use super::operand::{OperandRef, OperandValue};
@ -100,8 +101,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
match *kind {
mir::AggregateKind::Adt(adt_def, index, _) => {
let repr = adt::represent_type(bcx.ccx(), dest.ty.to_ty(bcx.tcx()));
let disr = adt_def.variants[index].disr_val;
adt::trans_set_discr(bcx, &*repr, dest.llval, disr);
let disr = Disr::from(adt_def.variants[index].disr_val);
adt::trans_set_discr(bcx, &*repr, dest.llval, Disr::from(disr));
for (i, operand) in operands.iter().enumerate() {
let op = self.trans_operand(bcx, operand);
// Do not generate stores and GEPis for zero-sized fields.

View File

@ -14,6 +14,7 @@ use middle::cstore::LinkMeta;
pub use self::base::trans_crate;
pub use self::context::CrateContext;
pub use self::common::gensym_name;
pub use self::disr::Disr;
#[macro_use]
mod macros;
@ -45,6 +46,7 @@ mod controlflow;
mod datum;
mod debuginfo;
mod declare;
mod disr;
mod expr;
mod foreign;
mod glue;

View File

@ -24,6 +24,7 @@ use trans::common::*;
use trans::declare;
use trans::foreign;
use middle::ty::{self, Ty};
use trans::Disr;
use rustc::front::map as hir_map;
use rustc_front::hir;
@ -207,7 +208,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
assert_eq!(v.node.name, variant.name);
let d = mk_lldecl(abi::Rust);
attributes::inline(d, attributes::InlineAttr::Hint);
trans_enum_variant(ccx, fn_node_id, variant.disr_val, psubsts, d);
trans_enum_variant(ccx, fn_node_id, Disr::from(variant.disr_val), psubsts, d);
d
}
hir_map::NodeImplItem(impl_item) => {

View File

@ -4153,7 +4153,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
sp: Span,
vs: &'tcx [hir::Variant],
id: ast::NodeId) {
// disr_in_range should be removed once we have forced type hints for consts
fn disr_in_range(ccx: &CrateCtxt,
ty: attr::IntType,
disr: ty::Disr) -> bool {