Use IndexVec instead of `usize` in librustc

This commit is contained in:
Oliver Scherer 2018-11-01 16:01:24 +01:00
parent 19ae2b940c
commit 740fb0cbaa
13 changed files with 108 additions and 68 deletions

View File

@ -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",
]

View File

@ -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;
}

View File

@ -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]))

View File

@ -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>,

View File

@ -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,

View File

@ -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);

View File

@ -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>,

View File

@ -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> {

View File

@ -33,7 +33,7 @@ CloneTypeFoldableAndLiftImpls! {
(),
bool,
usize,
u32,
::ty::layout::VariantIdx,
u64,
::middle::region::Scope,
::syntax::ast::FloatTy,

View File

@ -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> {

View File

@ -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" }

View File

@ -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)
}

View File

@ -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;