diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2018-11-01 16:01:24 +0100 |
|---|---|---|
| committer | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2018-11-12 12:33:16 +0100 |
| commit | 740fb0cbaa0a5fd1770b256edf71d2c4587bff8f (patch) | |
| tree | da3eaf1f657cd0d88b5c7bbd408fa67ccdb59626 | |
| parent | 19ae2b940c03750adb3594ff4699c72af452c149 (diff) | |
| download | rust-740fb0cbaa0a5fd1770b256edf71d2c4587bff8f.tar.gz rust-740fb0cbaa0a5fd1770b256edf71d2c4587bff8f.zip | |
Use IndexVec instead of `usize` in librustc
| -rw-r--r-- | src/Cargo.lock | 1 | ||||
| -rw-r--r-- | src/librustc/middle/intrinsicck.rs | 14 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 4 | ||||
| -rw-r--r-- | src/librustc/mir/mod.rs | 11 | ||||
| -rw-r--r-- | src/librustc/mir/tcx.rs | 9 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 4 | ||||
| -rw-r--r-- | src/librustc/ty/layout.rs | 71 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 30 | ||||
| -rw-r--r-- | src/librustc/ty/structural_impls.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/const_eval.rs | 2 | ||||
| -rw-r--r-- | src/librustc_target/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/librustc_target/abi/mod.rs | 22 | ||||
| -rw-r--r-- | src/librustc_target/lib.rs | 5 |
13 files changed, 108 insertions, 68 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock index 32304c81182..d80aa902c8b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2400,6 +2400,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", + "rustc_data_structures 0.0.0", "serialize 0.0.0", ] diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 0a5b1e184de..d2be0e4dcb9 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -11,9 +11,10 @@ use hir::def::Def; use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; -use ty::layout::{LayoutError, Pointer, SizeSkeleton}; +use ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; use rustc_target::spec::abi::Abi::RustIntrinsic; +use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir; @@ -48,10 +49,13 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() { let data_idx; - if def.variants[0].fields.is_empty() { - data_idx = 1; - } else if def.variants[1].fields.is_empty() { - data_idx = 0; + let one = VariantIdx::new(1); + let zero = VariantIdx::new(0); + + if def.variants[zero].fields.is_empty() { + data_idx = one; + } else if def.variants[one].fields.is_empty() { + data_idx = zero; } else { return ty; } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 9d3f37bc36a..59ef8fa1448 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -76,6 +76,7 @@ use hir::def::{Def, CtorKind}; use ty::adjustment; use ty::{self, Ty, TyCtxt}; use ty::fold::TypeFoldable; +use ty::layout::VariantIdx; use hir::{MutImmutable, MutMutable, PatKind}; use hir::pat_util::EnumerateAndAdjustIterator; @@ -87,6 +88,7 @@ use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::indexed_vec::Idx; use std::rc::Rc; use util::nodemap::ItemLocalSet; @@ -227,7 +229,7 @@ impl<'tcx> cmt_<'tcx> { } _ => { assert_eq!(adt_def.variants.len(), 1); - &adt_def.variants[0] + &adt_def.variants[VariantIdx::new(0)] } }; Some((adt_def, &variant_def.fields[field_index])) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index b8ccec4fec7..8a0306ab346 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -40,6 +40,7 @@ use syntax_pos::{Span, DUMMY_SP}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::subst::{CanonicalUserSubsts, Subst, Substs}; use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt}; +use ty::layout::VariantIdx; use util::ppaux; pub use mir::interpret::AssertMessage; @@ -1939,7 +1940,7 @@ pub enum ProjectionElem<'tcx, V, T> { /// "Downcast" to a variant of an ADT. Currently, we only introduce /// this for ADTs with more than one variant. It may be better to /// just introduce it always, or always for enums. - Downcast(&'tcx AdtDef, u32), + Downcast(&'tcx AdtDef, VariantIdx), } /// Alias for projections as they appear in places, where the base is a place @@ -1974,8 +1975,8 @@ impl<'tcx> Place<'tcx> { self.elem(ProjectionElem::Deref) } - pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> { - self.elem(ProjectionElem::Downcast(adt_def, variant_index as u32)) + pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Place<'tcx> { + self.elem(ProjectionElem::Downcast(adt_def, variant_index)) } pub fn index(self, index: Local) -> Place<'tcx> { @@ -2026,7 +2027,7 @@ impl<'tcx> Debug for Place<'tcx> { Promoted(ref promoted) => write!(fmt, "({:?}: {:?})", promoted.0, promoted.1), Projection(ref data) => match data.elem { ProjectionElem::Downcast(ref adt_def, index) => { - write!(fmt, "({:?} as {})", data.base, adt_def.variants[index as usize].name) + write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name) } ProjectionElem::Deref => write!(fmt, "(*{:?})", data.base), ProjectionElem::Field(field, ty) => { @@ -2216,7 +2217,7 @@ pub enum AggregateKind<'tcx> { /// active field index would identity the field `c` Adt( &'tcx AdtDef, - usize, + VariantIdx, &'tcx Substs<'tcx>, Option<UserTypeAnnotation<'tcx>>, Option<usize>, diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index c9a396ff8c5..baa88dba459 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -16,6 +16,7 @@ use mir::*; use ty::subst::{Subst, Substs}; use ty::{self, AdtDef, Ty, TyCtxt}; +use ty::layout::VariantIdx; use hir; use ty::util::IntTypeExt; @@ -27,7 +28,7 @@ pub enum PlaceTy<'tcx> { /// Downcast to a particular variant of an enum. Downcast { adt_def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>, - variant_index: u32 }, + variant_index: VariantIdx }, } static_assert!(PLACE_TY_IS_3_PTRS_LARGE: @@ -58,11 +59,11 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { pub fn field_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, f: &Field) -> Ty<'tcx> { // Pass `0` here so it can be used as a "default" variant_index in first arm below - let answer = match (self, 0) { + let answer = match (self, VariantIdx::new(0)) { (PlaceTy::Ty { ty: &ty::TyS { sty: ty::TyKind::Adt(adt_def, substs), .. } }, variant_index) | (PlaceTy::Downcast { adt_def, substs, variant_index }, _) => { - let variant_def = &adt_def.variants[variant_index as usize]; + let variant_def = &adt_def.variants[variant_index]; let field_def = &variant_def.fields[f.index()]; field_def.ty(tcx, substs) } @@ -138,7 +139,7 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { match self.to_ty(tcx).sty { ty::Adt(adt_def, substs) => { assert!(adt_def.is_enum()); - assert!(index < adt_def.variants.len() as u32); + assert!(index.as_usize() < adt_def.variants.len()); assert_eq!(adt_def, adt_def1); PlaceTy::Downcast { adt_def, substs, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 82095a2f5b0..a86a56a45cd 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -45,7 +45,7 @@ use ty::RegionKind; use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; use ty::TyKind::*; use ty::GenericParamDefKind; -use ty::layout::{LayoutDetails, TargetDataLayout}; +use ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx}; use ty::query; use ty::steal::Steal; use ty::BindingMode; @@ -1009,7 +1009,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn alloc_adt_def(self, did: DefId, kind: AdtKind, - variants: Vec<ty::VariantDef>, + variants: IndexVec<VariantIdx, ty::VariantDef>, repr: ReprOptions) -> &'gcx ty::AdtDef { let def = ty::AdtDef::new(self, did, kind, variants, repr); diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 5aeba652f32..877bd5a82e6 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -23,6 +23,7 @@ use std::mem; use std::ops::Bound; use ich::StableHashingContext; +use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; @@ -229,7 +230,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let b_offset = a.value.size(dl).abi_align(b.value.align(dl)); let size = (b_offset + b.value.size(dl)).abi_align(align); LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { offsets: vec![Size::ZERO, b_offset], memory_index: vec![0, 1] @@ -454,7 +455,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } Ok(LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { offsets, memory_index @@ -499,7 +500,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { // The never type. ty::Never => { tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Union(0), abi: Abi::Uninhabited, align: dl.i8_align, @@ -555,7 +556,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { .ok_or(LayoutError::SizeOverflow(ty))?; tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Array { stride: element.size, count @@ -568,7 +569,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { ty::Slice(element) => { let element = self.layout_of(element)?; tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Array { stride: element.size, count: 0 @@ -580,7 +581,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } ty::Str => { tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Array { stride: Size::from_bytes(1), count: 0 @@ -650,7 +651,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let size = size.abi_align(align); tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Array { stride: element.size, count @@ -671,7 +672,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { v.fields.iter().map(|field| { self.layout_of(field.ty(tcx, substs)) }).collect::<Result<Vec<_>, _>>() - }).collect::<Result<Vec<_>, _>>()?; + }).collect::<Result<IndexVec<VariantIdx, _>, _>>()?; if def.is_union() { let packed = def.repr.packed(); @@ -697,7 +698,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } let mut size = Size::ZERO; - for field in &variants[0] { + let index = VariantIdx::new(0); + for field in &variants[index] { assert!(!field.is_unsized()); if packed { @@ -710,8 +712,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } return Ok(tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: 0 }, - fields: FieldPlacement::Union(variants[0].len()), + variants: Variants::Single { index }, + fields: FieldPlacement::Union(variants[index].len()), abi: Abi::Aggregate { sized: true }, align, size: size.abi_align(align) @@ -729,8 +731,12 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { uninhabited && is_zst }; let (present_first, present_second) = { - let mut present_variants = (0..variants.len()).filter(|&v| { - !absent(&variants[v]) + let mut present_variants = variants.iter_enumerated().filter_map(|(i, v)| { + if absent(v) { + None + } else { + Some(i) + } }); (present_variants.next(), present_variants.next()) }; @@ -792,16 +798,16 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { // The current code for niche-filling relies on variant indices // instead of actual discriminants, so dataful enums with // explicit discriminants (RFC #2363) would misbehave. - let no_explicit_discriminants = def.variants.iter().enumerate() - .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i)); + let no_explicit_discriminants = def.variants.iter_enumerated() + .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32())); // Niche-filling enum optimization. if !def.repr.inhibit_enum_layout_opt() && no_explicit_discriminants { let mut dataful_variant = None; - let mut niche_variants = usize::max_value()..=0; + let mut niche_variants = VariantIdx::MAX..=VariantIdx::new(0); // Find one non-ZST variant. - 'variants: for (v, fields) in variants.iter().enumerate() { + 'variants: for (v, fields) in variants.iter_enumerated() { if absent(fields) { continue 'variants; } @@ -824,7 +830,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } if let Some(i) = dataful_variant { - let count = (niche_variants.end() - niche_variants.start() + 1) as u128; + let count = ( + niche_variants.end().as_u32() - niche_variants.start().as_u32() + 1 + ) as u128; for (field_index, &field) in variants[i].iter().enumerate() { let niche = match self.find_niche(field)? { Some(niche) => niche, @@ -836,7 +844,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { }; let mut align = dl.aggregate_align; - let st = variants.iter().enumerate().map(|(j, v)| { + let st = variants.iter_enumerated().map(|(j, v)| { let mut st = univariant_uninterned(v, &def.repr, StructKind::AlwaysSized)?; st.variants = Variants::Single { index: j }; @@ -844,7 +852,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { align = align.max(st.align); Ok(st) - }).collect::<Result<Vec<_>, _>>()?; + }).collect::<Result<IndexVec<VariantIdx, _>, _>>()?; let offset = st[i].fields.offset(field_index) + niche.offset; let size = st[i].size; @@ -899,7 +907,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let (mut min, mut max) = (i128::max_value(), i128::min_value()); let discr_type = def.repr.discr_type(); let bits = Integer::from_attr(self, discr_type).size().bits(); - for (i, discr) in def.discriminants(tcx).enumerate() { + for (i, discr) in def.discriminants(tcx) { if variants[i].iter().any(|f| f.abi.is_uninhabited()) { continue; } @@ -941,7 +949,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } // Create the set of structs that represent each variant. - let mut layout_variants = variants.iter().enumerate().map(|(i, field_layouts)| { + let mut layout_variants = variants.iter_enumerated().map(|(i, field_layouts)| { let mut st = univariant_uninterned(&field_layouts, &def.repr, StructKind::Prefixed(min_ity.size(), prefix_align))?; st.variants = Variants::Single { index: i }; @@ -956,7 +964,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { size = cmp::max(size, st.size); align = align.max(st.align); Ok(st) - }).collect::<Result<Vec<_>, _>>()?; + }).collect::<Result<IndexVec<VariantIdx, _>, _>>()?; // Align the maximum variant size to the largest alignment. size = size.abi_align(align); @@ -1259,7 +1267,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { debug!("print-type-size `{:#?}` adt general variants def {}", layout.ty, adt_def.variants.len()); let variant_infos: Vec<_> = - adt_def.variants.iter().enumerate().map(|(i, variant_def)| { + adt_def.variants.iter_enumerated().map(|(i, variant_def)| { let fields: Vec<_> = variant_def.fields.iter().map(|f| f.ident.name).collect(); build_variant_info(Some(variant_def.name), @@ -1339,7 +1347,8 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { } // Get a zero-sized variant or a pointer newtype. - let zero_or_ptr_variant = |i: usize| { + let zero_or_ptr_variant = |i| { + let i = VariantIdx::new(i); let fields = def.variants[i].fields.iter().map(|field| { SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env) }); @@ -1562,7 +1571,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> where C: LayoutOf<Ty = Ty<'tcx>> + HasTyCtxt<'tcx>, C::TyLayout: MaybeResult<TyLayout<'tcx>> { - fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: usize) -> TyLayout<'tcx> { + fn for_variant(this: TyLayout<'tcx>, cx: &C, variant_index: VariantIdx) -> TyLayout<'tcx> { let details = match this.variants { Variants::Single { index } if index == variant_index => this.details, @@ -1882,6 +1891,16 @@ impl<'a> HashStable<StableHashingContext<'a>> for FieldPlacement { } } +impl<'a> HashStable<StableHashingContext<'a>> for VariantIdx { + fn hash_stable<W: StableHasherResult>( + &self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher<W>, + ) { + self.as_u32().hash_stable(hcx, hasher) + } +} + impl<'a> HashStable<StableHashingContext<'a>> for Abi { fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0ba28811a90..6d59457cc74 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -32,6 +32,7 @@ use mir::GeneratorLayout; use session::CrateDisambiguator; use traits::{self, Reveal}; use ty; +use ty::layout::VariantIdx; use ty::subst::{Subst, Substs}; use ty::util::{IntTypeExt, Discr}; use ty::walk::TypeWalker; @@ -57,7 +58,7 @@ use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString}; use syntax_pos::{DUMMY_SP, Span}; use smallvec; -use rustc_data_structures::indexed_vec::Idx; +use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, HashStable}; @@ -1785,7 +1786,7 @@ pub enum VariantDiscr { /// For efficiency reasons, the distance from the /// last `Explicit` discriminant is being stored, /// or `0` for the first variant, if it has none. - Relative(usize), + Relative(u32), } #[derive(Debug)] @@ -1801,8 +1802,7 @@ pub struct FieldDef { /// table. pub struct AdtDef { pub did: DefId, - // TODO: make this an IndexVec - pub variants: Vec<VariantDef>, + pub variants: IndexVec<self::layout::VariantIdx, VariantDef>, flags: AdtFlags, pub repr: ReprOptions, } @@ -2000,7 +2000,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { fn new(tcx: TyCtxt<'_, '_, '_>, did: DefId, kind: AdtKind, - variants: Vec<VariantDef>, + variants: IndexVec<VariantIdx, VariantDef>, repr: ReprOptions) -> Self { debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr); let mut flags = AdtFlags::NO_ADT_FLAGS; @@ -2122,7 +2122,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { /// Asserts this is a struct or union and returns its unique variant. pub fn non_enum_variant(&self) -> &VariantDef { assert!(self.is_struct() || self.is_union()); - &self.variants[0] + &self.variants[VariantIdx::new(0)] } #[inline] @@ -2217,11 +2217,11 @@ impl<'a, 'gcx, 'tcx> AdtDef { pub fn discriminants( &'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - ) -> impl Iterator<Item=Discr<'tcx>> + Captures<'gcx> + 'a { + ) -> impl Iterator<Item=(VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a { let repr_type = self.repr.discr_type(); let initial = repr_type.initial_discriminant(tcx.global_tcx()); let mut prev_discr = None::<Discr<'tcx>>; - self.variants.iter().map(move |v| { + self.variants.iter_enumerated().map(move |(i, v)| { let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx)); if let VariantDiscr::Explicit(expr_did) = v.discr { if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) { @@ -2230,7 +2230,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } prev_discr = Some(discr); - discr + (i, discr) }) } @@ -2241,7 +2241,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { /// assuming there are no constant-evaluation errors there. pub fn discriminant_for_variant(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - variant_index: usize) + variant_index: VariantIdx) -> Discr<'tcx> { let (val, offset) = self.discriminant_def_for_variant(variant_index); let explicit_value = val @@ -2255,12 +2255,12 @@ impl<'a, 'gcx, 'tcx> AdtDef { /// inferred discriminant directly pub fn discriminant_def_for_variant( &self, - variant_index: usize, - ) -> (Option<DefId>, usize) { - let mut explicit_index = variant_index; + variant_index: VariantIdx, + ) -> (Option<DefId>, u32) { + let mut explicit_index = variant_index.as_u32(); let expr_did; loop { - match self.variants[explicit_index].discr { + match self.variants[VariantIdx::from_u32(explicit_index)].discr { ty::VariantDiscr::Relative(0) => { expr_did = None; break; @@ -2274,7 +2274,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } } } - (expr_did, variant_index - explicit_index) + (expr_did, variant_index.as_u32() - explicit_index) } pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 17a5f0999e7..e92f92dce63 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -33,7 +33,7 @@ CloneTypeFoldableAndLiftImpls! { (), bool, usize, - u32, + ::ty::layout::VariantIdx, u64, ::middle::region::Scope, ::syntax::ast::FloatTy, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 011887090ee..8020893634c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -481,7 +481,7 @@ pub fn const_field<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, - variant: Option<usize>, + variant: Option<u32>, field: mir::Field, value: &'tcx ty::Const<'tcx>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml index 684ea4c7897..dfdd7f0ae58 100644 --- a/src/librustc_target/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -12,4 +12,5 @@ crate-type = ["dylib"] bitflags = "1.0" log = "0.4" rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } +rustc_data_structures = { path = "../librustc_data_structures" } serialize = { path = "../libserialize" } diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 15f61a03344..01811aced73 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -16,6 +16,8 @@ use spec::Target; use std::{cmp, fmt}; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; +use rustc_data_structures::indexed_vec::{Idx, IndexVec}; + pub mod call; /// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout) @@ -825,11 +827,15 @@ impl Abi { } } +newtype_index! { + pub struct VariantIdx { .. } +} + #[derive(PartialEq, Eq, Hash, Debug)] pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { - index: usize + index: VariantIdx, }, /// General-case enums: for each case there is a struct, and they all have @@ -837,7 +843,7 @@ pub enum Variants { /// at a non-0 offset, after where the tag would go. Tagged { tag: Scalar, - variants: Vec<LayoutDetails>, + variants: IndexVec<VariantIdx, LayoutDetails>, }, /// Multiple cases distinguished by a niche (values invalid for a type): @@ -849,11 +855,11 @@ pub enum Variants { /// `None` has a null pointer for the second tuple field, and /// `Some` is the identity function (with a non-null reference). NicheFilling { - dataful_variant: usize, - niche_variants: RangeInclusive<usize>, + dataful_variant: VariantIdx, + niche_variants: RangeInclusive<VariantIdx>, niche: Scalar, niche_start: u128, - variants: Vec<LayoutDetails>, + variants: IndexVec<VariantIdx, LayoutDetails>, } } @@ -871,7 +877,7 @@ impl LayoutDetails { let size = scalar.value.size(cx); let align = scalar.value.align(cx); LayoutDetails { - variants: Variants::Single { index: 0 }, + variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Union(0), abi: Abi::Scalar(scalar), size, @@ -908,12 +914,12 @@ pub trait LayoutOf { } pub trait TyLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized { - fn for_variant(this: TyLayout<'a, Self>, cx: &C, variant_index: usize) -> TyLayout<'a, Self>; + fn for_variant(this: TyLayout<'a, Self>, cx: &C, variant_index: VariantIdx) -> TyLayout<'a, Self>; fn field(this: TyLayout<'a, Self>, cx: &C, i: usize) -> C::TyLayout; } impl<'a, Ty> TyLayout<'a, Ty> { - pub fn for_variant<C>(self, cx: &C, variant_index: usize) -> Self + pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> { Ty::for_variant(self, cx, variant_index) } diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index e60c9922d46..813b39de064 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -23,7 +23,9 @@ #![feature(box_syntax)] #![feature(nll)] +#![feature(rustc_attrs)] #![feature(slice_patterns)] +#![feature(step_trait)] #[macro_use] extern crate bitflags; @@ -36,5 +38,8 @@ extern crate serialize as rustc_serialize; // used by deriving #[allow(unused_extern_crates)] extern crate rustc_cratesio_shim; +#[macro_use] +extern crate rustc_data_structures; + pub mod abi; pub mod spec; |
