Use IndexVec instead of usize
in librustc
This commit is contained in:
parent
19ae2b940c
commit
740fb0cbaa
@ -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",
|
||||
]
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]))
|
||||
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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>,
|
||||
|
@ -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> {
|
||||
|
@ -33,7 +33,7 @@ CloneTypeFoldableAndLiftImpls! {
|
||||
(),
|
||||
bool,
|
||||
usize,
|
||||
u32,
|
||||
::ty::layout::VariantIdx,
|
||||
u64,
|
||||
::middle::region::Scope,
|
||||
::syntax::ast::FloatTy,
|
||||
|
@ -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> {
|
||||
|
@ -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" }
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user