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