mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
Auto merge of #55589 - oli-obk:min_length_💣, r=pnkfelix
Add `VariantIdx` type and use instead of `usize`
This commit is contained in:
commit
485397e49a
@ -2246,6 +2246,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
"rustc_data_structures 0.0.0",
|
||||
"rustc_mir 0.0.0",
|
||||
"rustc_target 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
@ -2400,6 +2401,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;
|
||||
@ -1753,7 +1754,7 @@ pub enum StatementKind<'tcx> {
|
||||
/// Write the discriminant for a variant to the enum Place.
|
||||
SetDiscriminant {
|
||||
place: Place<'tcx>,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
},
|
||||
|
||||
/// Start a live range for the storage of the local.
|
||||
@ -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, usize),
|
||||
Downcast(&'tcx AdtDef, VariantIdx),
|
||||
}
|
||||
|
||||
/// Alias for projections as they appear in places, where the base is a place
|
||||
@ -1950,6 +1951,11 @@ pub type PlaceProjection<'tcx> = Projection<'tcx, Place<'tcx>, Local, Ty<'tcx>>;
|
||||
/// and the index is a local.
|
||||
pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
|
||||
|
||||
// at least on 64 bit systems, `PlaceElem` should not be larger than two pointers
|
||||
static_assert!(PROJECTION_ELEM_IS_2_PTRS_LARGE:
|
||||
mem::size_of::<PlaceElem<'_>>() <= 16
|
||||
);
|
||||
|
||||
/// Alias for projections as they appear in `UserTypeProjection`, where we
|
||||
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
|
||||
pub type ProjectionKind<'tcx> = ProjectionElem<'tcx, (), ()>;
|
||||
@ -1969,7 +1975,7 @@ impl<'tcx> Place<'tcx> {
|
||||
self.elem(ProjectionElem::Deref)
|
||||
}
|
||||
|
||||
pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> {
|
||||
pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Place<'tcx> {
|
||||
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
|
||||
}
|
||||
|
||||
@ -2211,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,9 +28,13 @@ pub enum PlaceTy<'tcx> {
|
||||
/// Downcast to a particular variant of an enum.
|
||||
Downcast { adt_def: &'tcx AdtDef,
|
||||
substs: &'tcx Substs<'tcx>,
|
||||
variant_index: usize },
|
||||
variant_index: VariantIdx },
|
||||
}
|
||||
|
||||
static_assert!(PLACE_TY_IS_3_PTRS_LARGE:
|
||||
mem::size_of::<PlaceTy<'_>>() <= 24
|
||||
);
|
||||
|
||||
impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
|
||||
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
|
||||
PlaceTy::Ty { ty }
|
||||
@ -54,7 +59,7 @@ 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 }, _) => {
|
||||
@ -134,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());
|
||||
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,7 +1802,7 @@ pub struct FieldDef {
|
||||
/// table.
|
||||
pub struct AdtDef {
|
||||
pub did: DefId,
|
||||
pub variants: Vec<VariantDef>,
|
||||
pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
|
||||
flags: AdtFlags,
|
||||
pub repr: ReprOptions,
|
||||
}
|
||||
@ -1999,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;
|
||||
@ -2121,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]
|
||||
@ -2148,11 +2149,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||
.expect("variant_with_id: unknown variant")
|
||||
}
|
||||
|
||||
pub fn variant_index_with_id(&self, vid: DefId) -> usize {
|
||||
pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
|
||||
self.variants
|
||||
.iter()
|
||||
.position(|v| v.did == vid)
|
||||
.iter_enumerated()
|
||||
.find(|(_, v)| v.did == vid)
|
||||
.expect("variant_index_with_id: unknown variant")
|
||||
.0
|
||||
}
|
||||
|
||||
pub fn variant_of_def(&self, def: Def) -> &VariantDef {
|
||||
@ -2216,11 +2218,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) {
|
||||
@ -2229,7 +2231,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||
}
|
||||
prev_discr = Some(discr);
|
||||
|
||||
discr
|
||||
(i, discr)
|
||||
})
|
||||
}
|
||||
|
||||
@ -2240,7 +2242,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
|
||||
@ -2254,12 +2256,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;
|
||||
@ -2273,7 +2275,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,6 +33,7 @@ CloneTypeFoldableAndLiftImpls! {
|
||||
(),
|
||||
bool,
|
||||
usize,
|
||||
::ty::layout::VariantIdx,
|
||||
u64,
|
||||
::middle::region::Scope,
|
||||
::syntax::ast::FloatTy,
|
||||
|
@ -39,7 +39,7 @@ use rustc::middle::weak_lang_items;
|
||||
use rustc::mir::mono::{Linkage, Visibility, Stats, CodegenUnitNameBuilder};
|
||||
use rustc::middle::cstore::{EncodedMetadata};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf};
|
||||
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx};
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::middle::cstore::{self, LinkagePreference};
|
||||
use rustc::middle::exported_symbols;
|
||||
@ -73,6 +73,7 @@ use rustc::util::nodemap::FxHashMap;
|
||||
use CrateInfo;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
use std::any::Any;
|
||||
use std::cmp;
|
||||
@ -309,7 +310,7 @@ pub fn coerce_unsized_into(
|
||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
||||
assert_eq!(def_a, def_b);
|
||||
|
||||
for i in 0..def_a.variants[0].fields.len() {
|
||||
for i in 0..def_a.variants[VariantIdx::new(0)].fields.len() {
|
||||
let src_f = src.project_field(bx, i);
|
||||
let dst_f = dst.project_field(bx, i);
|
||||
|
||||
|
@ -29,7 +29,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc::mir::mono::Stats;
|
||||
use rustc::session::config::{self, DebugInfo};
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout};
|
||||
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout, VariantIdx};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
@ -87,7 +87,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
|
||||
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
|
||||
pub used_statics: RefCell<Vec<&'a Value>>,
|
||||
|
||||
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), &'a Type>>,
|
||||
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'a Type>>,
|
||||
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
|
||||
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
||||
pub isize_ty: &'a Type,
|
||||
|
@ -1241,7 +1241,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||
// This doesn't matter in this case.
|
||||
NoDiscriminant
|
||||
};
|
||||
(0..variants.len()).map(|i| {
|
||||
variants.iter_enumerated().map(|(i, _)| {
|
||||
let variant = self.layout.for_variant(cx, i);
|
||||
let (variant_type_metadata, member_desc_factory) =
|
||||
describe_enum_variant(cx,
|
||||
@ -1341,7 +1341,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||
}
|
||||
]
|
||||
} else {
|
||||
(0..variants.len()).map(|i| {
|
||||
variants.iter_enumerated().map(|(i, _)| {
|
||||
let variant = self.layout.for_variant(cx, i);
|
||||
let (variant_type_metadata, member_desc_factory) =
|
||||
describe_enum_variant(cx,
|
||||
@ -1361,8 +1361,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||
let niche_value = if i == dataful_variant {
|
||||
None
|
||||
} else {
|
||||
let value = (i as u128)
|
||||
.wrapping_sub(*niche_variants.start() as u128)
|
||||
let value = (i.as_u32() as u128)
|
||||
.wrapping_sub(niche_variants.start().as_u32() as u128)
|
||||
.wrapping_add(niche_start);
|
||||
let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
|
||||
Some(value as u64)
|
||||
@ -1530,7 +1530,7 @@ fn prepare_enum_metadata(
|
||||
let def = enum_type.ty_adt_def().unwrap();
|
||||
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
|
||||
.zip(&def.variants)
|
||||
.map(|(discr, v)| {
|
||||
.map(|((_, discr), v)| {
|
||||
let name = SmallCStr::new(&v.name.as_str());
|
||||
unsafe {
|
||||
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use llvm::{self, LLVMConstInBoundsGEP};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size};
|
||||
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx};
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::PlaceTy;
|
||||
use base;
|
||||
@ -281,7 +281,7 @@ impl PlaceRef<'ll, 'tcx> {
|
||||
match self.layout.variants {
|
||||
layout::Variants::Single { index } => {
|
||||
let discr_val = self.layout.ty.ty_adt_def().map_or(
|
||||
index as u128,
|
||||
index.as_u32() as u128,
|
||||
|def| def.discriminant_for_variant(bx.cx.tcx, index).val);
|
||||
return C_uint_big(cast_to, discr_val);
|
||||
}
|
||||
@ -320,16 +320,16 @@ impl PlaceRef<'ll, 'tcx> {
|
||||
C_uint_big(niche_llty, niche_start)
|
||||
};
|
||||
bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval),
|
||||
C_uint(cast_to, *niche_variants.start() as u64),
|
||||
C_uint(cast_to, dataful_variant as u64))
|
||||
C_uint(cast_to, niche_variants.start().as_u32() as u64),
|
||||
C_uint(cast_to, dataful_variant.as_u32() as u64))
|
||||
} else {
|
||||
// Rebase from niche values to discriminant values.
|
||||
let delta = niche_start.wrapping_sub(*niche_variants.start() as u128);
|
||||
let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128);
|
||||
let lldiscr = bx.sub(lldiscr, C_uint_big(niche_llty, delta));
|
||||
let lldiscr_max = C_uint(niche_llty, *niche_variants.end() as u64);
|
||||
let lldiscr_max = C_uint(niche_llty, niche_variants.end().as_u32() as u64);
|
||||
bx.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max),
|
||||
bx.intcast(lldiscr, cast_to, false),
|
||||
C_uint(cast_to, dataful_variant as u64))
|
||||
C_uint(cast_to, dataful_variant.as_u32() as u64))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,7 +337,7 @@ impl PlaceRef<'ll, 'tcx> {
|
||||
|
||||
/// Set the discriminant for a new value of the given case of the given
|
||||
/// representation.
|
||||
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) {
|
||||
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: VariantIdx) {
|
||||
if self.layout.for_variant(bx.cx, variant_index).abi.is_uninhabited() {
|
||||
return;
|
||||
}
|
||||
@ -376,7 +376,8 @@ impl PlaceRef<'ll, 'tcx> {
|
||||
|
||||
let niche = self.project_field(bx, 0);
|
||||
let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
|
||||
let niche_value = ((variant_index - *niche_variants.start()) as u128)
|
||||
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
|
||||
let niche_value = (niche_value as u128)
|
||||
.wrapping_add(niche_start);
|
||||
// FIXME(eddyb) Check the actual primitive type here.
|
||||
let niche_llval = if niche_value == 0 {
|
||||
@ -401,7 +402,7 @@ impl PlaceRef<'ll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize)
|
||||
pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: VariantIdx)
|
||||
-> PlaceRef<'ll, 'tcx> {
|
||||
let mut downcast = *self;
|
||||
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
|
||||
|
@ -16,3 +16,4 @@ rustc_mir = { path = "../librustc_mir"}
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
|
@ -40,6 +40,7 @@ extern crate log;
|
||||
extern crate rustc_mir;
|
||||
extern crate rustc_target;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_data_structures;
|
||||
|
||||
use rustc::lint;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray};
|
||||
|
@ -13,7 +13,8 @@
|
||||
use rustc::hir::Node;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{self, IntegerExt, LayoutOf};
|
||||
use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use util::nodemap::FxHashSet;
|
||||
use lint::{LateContext, LintContext, LintArray};
|
||||
use lint::{LintPass, LateLintPass};
|
||||
@ -452,10 +453,13 @@ fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
if def.variants.len() == 2 {
|
||||
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 zero = VariantIdx::new(0);
|
||||
let one = VariantIdx::new(1);
|
||||
|
||||
if def.variants[zero].fields.is_empty() {
|
||||
data_idx = one;
|
||||
} else if def.variants[one].fields.is_empty() {
|
||||
data_idx = zero;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -601,7 +601,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
vec![self.get_variant(tcx, &item, item_id, kind)]
|
||||
std::iter::once(self.get_variant(tcx, &item, item_id, kind)).collect()
|
||||
};
|
||||
|
||||
tcx.alloc_adt_def(did, kind, variants, repr)
|
||||
|
@ -27,6 +27,7 @@ use rustc::mir::{self, interpret};
|
||||
use rustc::traits::specialization_graph;
|
||||
use rustc::ty::{self, Ty, TyCtxt, ReprOptions, SymbolName};
|
||||
use rustc::ty::codec::{self as ty_codec, TyEncoder};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
|
||||
use rustc::session::config::{self, CrateType};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
@ -580,7 +581,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
/// the right to access any information in the adt-def (including,
|
||||
/// e.g., the length of the various vectors).
|
||||
fn encode_enum_variant_info(&mut self,
|
||||
(enum_did, Untracked(index)): (DefId, Untracked<usize>))
|
||||
(enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>))
|
||||
-> Entry<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let def = tcx.adt_def(enum_did);
|
||||
@ -675,7 +676,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
/// vectors).
|
||||
fn encode_field(&mut self,
|
||||
(adt_def_id, Untracked((variant_index, field_index))): (DefId,
|
||||
Untracked<(usize,
|
||||
Untracked<(VariantIdx,
|
||||
usize)>))
|
||||
-> Entry<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
@ -1667,7 +1668,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
|
||||
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||
fn encode_fields(&mut self, adt_def_id: DefId) {
|
||||
let def = self.tcx.adt_def(adt_def_id);
|
||||
for (variant_index, variant) in def.variants.iter().enumerate() {
|
||||
for (variant_index, variant) in def.variants.iter_enumerated() {
|
||||
for (field_index, field) in variant.fields.iter().enumerate() {
|
||||
self.record(field.did,
|
||||
IsolatedEncoder::encode_field,
|
||||
@ -1734,7 +1735,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||
self.encode_fields(def_id);
|
||||
|
||||
let def = self.tcx.adt_def(def_id);
|
||||
for (i, variant) in def.variants.iter().enumerate() {
|
||||
for (i, variant) in def.variants.iter_enumerated() {
|
||||
self.record(variant.did,
|
||||
IsolatedEncoder::encode_enum_variant_info,
|
||||
(def_id, Untracked(i)));
|
||||
|
@ -47,7 +47,8 @@ use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
|
||||
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use std::rc::Rc;
|
||||
use std::{fmt, iter};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
@ -574,7 +575,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
},
|
||||
ProjectionElem::Downcast(adt_def1, index) => match base_ty.sty {
|
||||
ty::Adt(adt_def, substs) if adt_def.is_enum() && adt_def == adt_def1 => {
|
||||
if index >= adt_def.variants.len() {
|
||||
if index.as_usize() >= adt_def.variants.len() {
|
||||
PlaceTy::Ty {
|
||||
ty: span_mirbug_and_err!(
|
||||
self,
|
||||
@ -654,7 +655,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
variant_index,
|
||||
} => (&adt_def.variants[variant_index], substs),
|
||||
PlaceTy::Ty { ty } => match ty.sty {
|
||||
ty::Adt(adt_def, substs) if !adt_def.is_enum() => (&adt_def.variants[0], substs),
|
||||
ty::Adt(adt_def, substs) if !adt_def.is_enum() =>
|
||||
(&adt_def.variants[VariantIdx::new(0)], substs),
|
||||
ty::Closure(def_id, substs) => {
|
||||
return match substs.upvar_tys(def_id, tcx).nth(field.index()) {
|
||||
Some(ty) => Ok(ty),
|
||||
@ -1280,7 +1282,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
);
|
||||
}
|
||||
};
|
||||
if variant_index >= adt.variants.len() {
|
||||
if variant_index.as_usize() >= adt.variants.len() {
|
||||
span_bug!(
|
||||
stmt.source_info.span,
|
||||
"bad set discriminant ({:?} = {:?}): value of of range",
|
||||
|
@ -22,6 +22,7 @@ use hair::pattern::PatternTypeProjections;
|
||||
use rustc::hir;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc_data_structures::bit_set::BitSet;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use syntax::ast::{Name, NodeId};
|
||||
@ -663,7 +664,7 @@ enum TestKind<'tcx> {
|
||||
// test the branches of enum
|
||||
Switch {
|
||||
adt_def: &'tcx ty::AdtDef,
|
||||
variants: BitSet<usize>,
|
||||
variants: BitSet<VariantIdx>,
|
||||
},
|
||||
|
||||
// test the branches of enum
|
||||
|
@ -123,7 +123,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
|
||||
let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| {
|
||||
let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| {
|
||||
i == variant_index || {
|
||||
self.hir.tcx().features().never_type &&
|
||||
self.hir.tcx().features().exhaustive_patterns &&
|
||||
|
@ -22,6 +22,7 @@ use rustc_data_structures::bit_set::BitSet;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::mir::*;
|
||||
use rustc::hir::{RangeEnd, Mutability};
|
||||
use syntax_pos::Span;
|
||||
@ -152,7 +153,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn add_variants_to_switch<'pat>(&mut self,
|
||||
test_place: &Place<'tcx>,
|
||||
candidate: &Candidate<'pat, 'tcx>,
|
||||
variants: &mut BitSet<usize>)
|
||||
variants: &mut BitSet<VariantIdx>)
|
||||
-> bool
|
||||
{
|
||||
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
|
||||
@ -196,7 +197,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
let mut targets = Vec::with_capacity(used_variants + 1);
|
||||
let mut values = Vec::with_capacity(used_variants);
|
||||
let tcx = self.hir.tcx();
|
||||
for (idx, discr) in adt_def.discriminants(tcx).enumerate() {
|
||||
for (idx, discr) in adt_def.discriminants(tcx) {
|
||||
target_blocks.push(if variants.contains(idx) {
|
||||
values.push(discr.val);
|
||||
targets.push(self.cfg.start_new_block());
|
||||
@ -512,7 +513,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
variant_index,
|
||||
subpatterns,
|
||||
candidate);
|
||||
resulting_candidates[variant_index].push(new_candidate);
|
||||
resulting_candidates[variant_index.as_usize()].push(new_candidate);
|
||||
true
|
||||
}
|
||||
(&TestKind::Switch { .. }, _) => false,
|
||||
@ -673,7 +674,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
fn candidate_after_variant_switch<'pat>(&mut self,
|
||||
match_pair_index: usize,
|
||||
adt_def: &'tcx ty::AdtDef,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
subpatterns: &'pat [FieldPattern<'tcx>],
|
||||
candidate: &Candidate<'pat, 'tcx>)
|
||||
-> Candidate<'pat, 'tcx> {
|
||||
|
@ -13,6 +13,7 @@ use build::matches::MatchPair;
|
||||
use hair::*;
|
||||
use rustc::mir::*;
|
||||
use std::u32;
|
||||
use std::convert::TryInto;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
pub fn field_match_pairs<'pat>(&mut self,
|
||||
@ -35,8 +36,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
opt_slice: Option<&'pat Pattern<'tcx>>,
|
||||
suffix: &'pat [Pattern<'tcx>]) {
|
||||
let min_length = prefix.len() + suffix.len();
|
||||
assert!(min_length < u32::MAX as usize);
|
||||
let min_length = min_length as u32;
|
||||
let min_length = min_length.try_into().unwrap();
|
||||
|
||||
match_pairs.extend(
|
||||
prefix.iter()
|
||||
|
@ -21,7 +21,7 @@ use rustc::hir::def::Def;
|
||||
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
|
||||
use rustc::ty::layout::{self, LayoutOf, TyLayout};
|
||||
use rustc::ty::layout::{self, LayoutOf, TyLayout, VariantIdx};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::traits::Reveal;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
@ -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<VariantIdx>,
|
||||
field: mir::Field,
|
||||
value: &'tcx ty::Const<'tcx>,
|
||||
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||
@ -513,7 +513,7 @@ pub fn const_variant_index<'a, 'tcx>(
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
val: &'tcx ty::Const<'tcx>,
|
||||
) -> EvalResult<'tcx, usize> {
|
||||
) -> EvalResult<'tcx, VariantIdx> {
|
||||
trace!("const_variant_index: {:?}, {:?}", instance, val);
|
||||
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
||||
let op = ecx.const_to_op(val)?;
|
||||
|
@ -284,7 +284,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
|
||||
}
|
||||
Def::StructCtor(_, CtorKind::Fn) |
|
||||
Def::SelfCtor(..) => Some((adt_def, 0)),
|
||||
Def::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
@ -468,7 +468,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
AdtKind::Struct | AdtKind::Union => {
|
||||
ExprKind::Adt {
|
||||
adt_def: adt,
|
||||
variant_index: 0,
|
||||
variant_index: VariantIdx::new(0),
|
||||
substs,
|
||||
user_ty: cx.user_substs_applied_to_adt(expr.hir_id, adt),
|
||||
fields: field_refs(cx, fields),
|
||||
|
@ -25,6 +25,7 @@ use rustc::infer::InferCtxt;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::{Kind, Substs};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use syntax::ast::{self, LitKind};
|
||||
use syntax::attr;
|
||||
use syntax::symbol::Symbol;
|
||||
@ -228,7 +229,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||
bug!("found no method `{}` in `{:?}`", method_name, trait_def_id);
|
||||
}
|
||||
|
||||
pub fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: usize) -> Vec<Field> {
|
||||
pub fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: VariantIdx) -> Vec<Field> {
|
||||
(0..adt_def.variants[variant_index].fields.len())
|
||||
.map(Field::new)
|
||||
.collect()
|
||||
|
@ -19,6 +19,7 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::region;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::hir;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
@ -264,7 +265,7 @@ pub enum ExprKind<'tcx> {
|
||||
},
|
||||
Adt {
|
||||
adt_def: &'tcx AdtDef,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
substs: &'tcx Substs<'tcx>,
|
||||
|
||||
/// Optional user-given substs: for something like `let x =
|
||||
|
@ -179,7 +179,7 @@ use super::{PatternFoldable, PatternFolder, compare_const_vals};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::RangeEnd;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::layout::{Integer, IntegerExt};
|
||||
use rustc::ty::layout::{Integer, IntegerExt, VariantIdx};
|
||||
|
||||
use rustc::mir::Field;
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
@ -422,12 +422,12 @@ pub enum Constructor<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Constructor<'tcx> {
|
||||
fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> usize {
|
||||
fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx {
|
||||
match self {
|
||||
&Variant(vid) => adt.variant_index_with_id(vid),
|
||||
&Single => {
|
||||
assert!(!adt.is_enum());
|
||||
0
|
||||
VariantIdx::new(0)
|
||||
}
|
||||
_ => bug!("bad constructor {:?} for adt {:?}", self, adt)
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use rustc::mir::{ProjectionElem, UserTypeAnnotation, UserTypeProjection, UserTyp
|
||||
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
|
||||
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
|
||||
use rustc::ty::subst::{Substs, Kind};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::hir::{self, PatKind, RangeEnd};
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||
@ -111,7 +112,7 @@ impl<'tcx> PatternTypeProjections<'tcx> {
|
||||
|
||||
pub(crate) fn variant(&self,
|
||||
adt_def: &'tcx AdtDef,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
field: Field) -> Self {
|
||||
self.map_projs(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
|
||||
}
|
||||
@ -153,7 +154,7 @@ impl<'tcx> PatternTypeProjection<'tcx> {
|
||||
|
||||
pub(crate) fn variant(&self,
|
||||
adt_def: &'tcx AdtDef,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
field: Field) -> Self {
|
||||
let mut new = self.clone();
|
||||
new.0.projs.push(ProjectionElem::Downcast(adt_def, variant_index));
|
||||
@ -200,7 +201,7 @@ pub enum PatternKind<'tcx> {
|
||||
Variant {
|
||||
adt_def: &'tcx AdtDef,
|
||||
substs: &'tcx Substs<'tcx>,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
subpatterns: Vec<FieldPattern<'tcx>>,
|
||||
},
|
||||
|
||||
@ -273,7 +274,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
|
||||
}
|
||||
_ => if let ty::Adt(adt, _) = self.ty.sty {
|
||||
if !adt.is_enum() {
|
||||
Some(&adt.variants[0])
|
||||
Some(&adt.variants[VariantIdx::new(0)])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -1160,7 +1161,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
|
||||
} => PatternKind::Variant {
|
||||
adt_def: adt_def.fold_with(folder),
|
||||
substs: substs.fold_with(folder),
|
||||
variant_index: variant_index.fold_with(folder),
|
||||
variant_index,
|
||||
subpatterns: subpatterns.fold_with(folder)
|
||||
},
|
||||
PatternKind::Leaf {
|
||||
|
@ -14,7 +14,7 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use rustc::{mir, ty};
|
||||
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt};
|
||||
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx};
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
GlobalId, AllocId,
|
||||
@ -417,7 +417,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
pub fn operand_downcast(
|
||||
&self,
|
||||
op: OpTy<'tcx, M::PointerTag>,
|
||||
variant: usize,
|
||||
variant: VariantIdx,
|
||||
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||
// Downcasts only change the layout
|
||||
Ok(match op.try_as_mplace() {
|
||||
@ -596,13 +596,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
pub fn read_discriminant(
|
||||
&self,
|
||||
rval: OpTy<'tcx, M::PointerTag>,
|
||||
) -> EvalResult<'tcx, (u128, usize)> {
|
||||
) -> EvalResult<'tcx, (u128, VariantIdx)> {
|
||||
trace!("read_discriminant_value {:#?}", rval.layout);
|
||||
|
||||
match rval.layout.variants {
|
||||
layout::Variants::Single { index } => {
|
||||
let discr_val = rval.layout.ty.ty_adt_def().map_or(
|
||||
index as u128,
|
||||
index.as_u32() as u128,
|
||||
|def| def.discriminant_for_variant(*self.tcx, index).val);
|
||||
return Ok((discr_val, index));
|
||||
}
|
||||
@ -645,9 +645,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
.ty_adt_def()
|
||||
.expect("tagged layout for non adt")
|
||||
.discriminants(self.tcx.tcx)
|
||||
.position(|var| var.val == real_discr)
|
||||
.find(|(_, var)| var.val == real_discr)
|
||||
.ok_or_else(|| EvalErrorKind::InvalidDiscriminant(raw_discr.erase_tag()))?;
|
||||
(real_discr, index)
|
||||
(real_discr, index.0)
|
||||
},
|
||||
layout::Variants::NicheFilling {
|
||||
dataful_variant,
|
||||
@ -655,33 +655,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
niche_start,
|
||||
..
|
||||
} => {
|
||||
let variants_start = *niche_variants.start() as u128;
|
||||
let variants_end = *niche_variants.end() as u128;
|
||||
let real_discr = match raw_discr {
|
||||
let variants_start = niche_variants.start().as_u32() as u128;
|
||||
let variants_end = niche_variants.end().as_u32() as u128;
|
||||
match raw_discr {
|
||||
Scalar::Ptr(_) => {
|
||||
// The niche must be just 0 (which a pointer value never is)
|
||||
assert!(niche_start == 0);
|
||||
assert!(variants_start == variants_end);
|
||||
dataful_variant as u128
|
||||
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||
},
|
||||
Scalar::Bits { bits: raw_discr, size } => {
|
||||
assert_eq!(size as u64, discr_val.layout.size.bytes());
|
||||
let discr = raw_discr.wrapping_sub(niche_start)
|
||||
.wrapping_add(variants_start);
|
||||
if variants_start <= discr && discr <= variants_end {
|
||||
discr
|
||||
let index = discr as usize;
|
||||
assert_eq!(index as u128, discr);
|
||||
assert!(index < rval.layout.ty
|
||||
.ty_adt_def()
|
||||
.expect("tagged layout for non adt")
|
||||
.variants.len());
|
||||
(discr, VariantIdx::from_usize(index))
|
||||
} else {
|
||||
dataful_variant as u128
|
||||
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||
}
|
||||
},
|
||||
};
|
||||
let index = real_discr as usize;
|
||||
assert_eq!(index as u128, real_discr);
|
||||
assert!(index < rval.layout.ty
|
||||
.ty_adt_def()
|
||||
.expect("tagged layout for non adt")
|
||||
.variants.len());
|
||||
(real_discr, index)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use std::hash::Hash;
|
||||
use rustc::hir;
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout};
|
||||
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx};
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic
|
||||
@ -431,7 +431,7 @@ where
|
||||
pub fn mplace_downcast(
|
||||
&self,
|
||||
base: MPlaceTy<'tcx, M::PointerTag>,
|
||||
variant: usize,
|
||||
variant: VariantIdx,
|
||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
// Downcasts only change the layout
|
||||
assert!(base.meta.is_none());
|
||||
@ -498,7 +498,7 @@ where
|
||||
pub fn place_downcast(
|
||||
&self,
|
||||
base: PlaceTy<'tcx, M::PointerTag>,
|
||||
variant: usize,
|
||||
variant: VariantIdx,
|
||||
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||
// Downcast just changes the layout
|
||||
Ok(match base.place {
|
||||
@ -901,7 +901,7 @@ where
|
||||
|
||||
pub fn write_discriminant_index(
|
||||
&mut self,
|
||||
variant_index: usize,
|
||||
variant_index: VariantIdx,
|
||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
||||
) -> EvalResult<'tcx> {
|
||||
match dest.layout.variants {
|
||||
@ -910,7 +910,7 @@ where
|
||||
}
|
||||
layout::Variants::Tagged { ref tag, .. } => {
|
||||
let adt_def = dest.layout.ty.ty_adt_def().unwrap();
|
||||
assert!(variant_index < adt_def.variants.len());
|
||||
assert!(variant_index.as_usize() < adt_def.variants.len());
|
||||
let discr_val = adt_def
|
||||
.discriminant_for_variant(*self.tcx, variant_index)
|
||||
.val;
|
||||
@ -931,11 +931,14 @@ where
|
||||
niche_start,
|
||||
..
|
||||
} => {
|
||||
assert!(variant_index < dest.layout.ty.ty_adt_def().unwrap().variants.len());
|
||||
assert!(
|
||||
variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(),
|
||||
);
|
||||
if variant_index != dataful_variant {
|
||||
let niche_dest =
|
||||
self.place_field(dest, 0)?;
|
||||
let niche_value = ((variant_index - niche_variants.start()) as u128)
|
||||
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
|
||||
let niche_value = (niche_value as u128)
|
||||
.wrapping_add(niche_start);
|
||||
self.write_scalar(
|
||||
Scalar::from_uint(niche_value, niche_dest.layout.size),
|
||||
|
@ -13,7 +13,7 @@ use std::hash::Hash;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf};
|
||||
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
|
||||
use rustc::ty;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc::mir::interpret::{
|
||||
@ -74,6 +74,7 @@ macro_rules! try_validation {
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum PathElem {
|
||||
Field(Symbol),
|
||||
Variant(Symbol),
|
||||
ClosureVar(Symbol),
|
||||
ArrayElem(usize),
|
||||
TupleElem(usize),
|
||||
@ -107,6 +108,7 @@ fn path_format(path: &Vec<PathElem>) -> String {
|
||||
for elem in path.iter() {
|
||||
match elem {
|
||||
Field(name) => write!(out, ".{}", name),
|
||||
Variant(name) => write!(out, ".<downcast-variant({})>", name),
|
||||
ClosureVar(name) => write!(out, ".<closure-var({})>", name),
|
||||
TupleElem(idx) => write!(out, ".{}", idx),
|
||||
ArrayElem(idx) => write!(out, "[{}]", idx),
|
||||
@ -165,12 +167,12 @@ struct ValidityVisitor<'rt, 'a: 'rt, 'mir: 'rt, 'tcx: 'a+'rt+'mir, M: Machine<'a
|
||||
}
|
||||
|
||||
impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, 'mir, 'tcx, M> {
|
||||
fn push_aggregate_field_path_elem(
|
||||
fn aggregate_field_path_elem(
|
||||
&mut self,
|
||||
layout: TyLayout<'tcx>,
|
||||
field: usize,
|
||||
) {
|
||||
let elem = match layout.ty.sty {
|
||||
) -> PathElem {
|
||||
match layout.ty.sty {
|
||||
// generators and closures.
|
||||
ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
|
||||
if let Some(upvar) = self.ecx.tcx.optimized_mir(def_id).upvar_decls.get(field) {
|
||||
@ -192,9 +194,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, '
|
||||
layout::Variants::Single { index } =>
|
||||
// Inside a variant
|
||||
PathElem::Field(def.variants[index].fields[field].ident.name),
|
||||
_ =>
|
||||
// To a variant
|
||||
PathElem::Field(def.variants[field].name)
|
||||
_ => bug!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,8 +209,22 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, '
|
||||
|
||||
// nothing else has an aggregate layout
|
||||
_ => bug!("aggregate_field_path_elem: got non-aggregate type {:?}", layout.ty),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_elem(
|
||||
&mut self,
|
||||
new_op: OpTy<'tcx, M::PointerTag>,
|
||||
elem: PathElem,
|
||||
) -> EvalResult<'tcx> {
|
||||
// Remember the old state
|
||||
let path_len = self.path.len();
|
||||
// Perform operation
|
||||
self.path.push(elem);
|
||||
self.visit_value(new_op)?;
|
||||
// Undo changes
|
||||
self.path.truncate(path_len);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,14 +245,19 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
|
||||
field: usize,
|
||||
new_op: OpTy<'tcx, M::PointerTag>
|
||||
) -> EvalResult<'tcx> {
|
||||
// Remember the old state
|
||||
let path_len = self.path.len();
|
||||
// Perform operation
|
||||
self.push_aggregate_field_path_elem(old_op.layout, field);
|
||||
self.visit_value(new_op)?;
|
||||
// Undo changes
|
||||
self.path.truncate(path_len);
|
||||
Ok(())
|
||||
let elem = self.aggregate_field_path_elem(old_op.layout, field);
|
||||
self.visit_elem(new_op, elem)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_variant(
|
||||
&mut self,
|
||||
old_op: OpTy<'tcx, M::PointerTag>,
|
||||
variant_id: VariantIdx,
|
||||
new_op: OpTy<'tcx, M::PointerTag>
|
||||
) -> EvalResult<'tcx> {
|
||||
let name = old_op.layout.ty.ty_adt_def().unwrap().variants[variant_id].name;
|
||||
self.visit_elem(new_op, PathElem::Variant(name))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
|
||||
//! types until we arrive at the leaves, with custom handling for primitive types.
|
||||
|
||||
use rustc::ty::layout::{self, TyLayout};
|
||||
use rustc::ty::layout::{self, TyLayout, VariantIdx};
|
||||
use rustc::ty;
|
||||
use rustc::mir::interpret::{
|
||||
EvalResult,
|
||||
@ -32,7 +32,7 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
|
||||
fn project_downcast(
|
||||
self,
|
||||
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
|
||||
variant: usize,
|
||||
variant: VariantIdx,
|
||||
) -> EvalResult<'tcx, Self>;
|
||||
|
||||
/// Project to the n-th field.
|
||||
@ -70,7 +70,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
|
||||
fn project_downcast(
|
||||
self,
|
||||
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
|
||||
variant: usize,
|
||||
variant: VariantIdx,
|
||||
) -> EvalResult<'tcx, Self> {
|
||||
ecx.operand_downcast(self, variant)
|
||||
}
|
||||
@ -109,7 +109,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
|
||||
fn project_downcast(
|
||||
self,
|
||||
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
|
||||
variant: usize,
|
||||
variant: VariantIdx,
|
||||
) -> EvalResult<'tcx, Self> {
|
||||
ecx.mplace_downcast(self, variant)
|
||||
}
|
||||
@ -171,6 +171,16 @@ macro_rules! make_value_visitor {
|
||||
self.visit_value(new_val)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_variant(
|
||||
&mut self,
|
||||
_old_val: Self::V,
|
||||
_variant: VariantIdx,
|
||||
new_val: Self::V,
|
||||
) -> EvalResult<'tcx> {
|
||||
self.visit_value(new_val)
|
||||
}
|
||||
|
||||
/// Called whenever we reach a value with uninhabited layout.
|
||||
/// Recursing to fields will *always* continue after this! This is not meant to control
|
||||
/// whether and how we descend recursively/ into the scalar's fields if there are any,
|
||||
@ -221,7 +231,7 @@ macro_rules! make_value_visitor {
|
||||
let inner = v.project_downcast(self.ecx(), idx)?;
|
||||
trace!("walk_value: variant layout: {:#?}", inner.layout());
|
||||
// recurse with the inner type
|
||||
return self.visit_field(v, idx, inner);
|
||||
return self.visit_variant(v, idx, inner);
|
||||
}
|
||||
layout::Variants::Single { .. } => {}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::infer;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::query::Providers;
|
||||
|
||||
@ -291,7 +292,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
|
||||
fn deref_subpath(&self, _path: Self::Path) -> Option<Self::Path> {
|
||||
None
|
||||
}
|
||||
fn downcast_subpath(&self, _path: Self::Path, _variant: usize) -> Option<Self::Path> {
|
||||
fn downcast_subpath(&self, _path: Self::Path, _variant: VariantIdx) -> Option<Self::Path> {
|
||||
Some(())
|
||||
}
|
||||
fn array_subpath(&self, _path: Self::Path, _index: u32, _size: u32) -> Option<Self::Path> {
|
||||
@ -867,7 +868,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
|
||||
let variant_no = if adt_def.is_enum() {
|
||||
adt_def.variant_index_with_id(def_id)
|
||||
} else {
|
||||
0
|
||||
VariantIdx::new(0)
|
||||
};
|
||||
|
||||
// return = ADT(arg0, arg1, ...); return
|
||||
|
@ -16,6 +16,7 @@ use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
|
||||
use dataflow::MoveDataParamEnv;
|
||||
use dataflow::{self, do_dataflow, DebugFormatted};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::mir::*;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_data_structures::bit_set::BitSet;
|
||||
@ -282,7 +283,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn downcast_subpath(&self, path: Self::Path, variant: usize) -> Option<Self::Path> {
|
||||
fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path> {
|
||||
dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
|
||||
match p {
|
||||
&Projection {
|
||||
|
@ -64,6 +64,7 @@ use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor};
|
||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::ty::subst::Substs;
|
||||
use util::dump_mir;
|
||||
use util::liveness::{self, IdentityMap};
|
||||
@ -158,7 +159,7 @@ struct TransformVisitor<'a, 'tcx: 'a> {
|
||||
|
||||
impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
||||
// Make a GeneratorState rvalue
|
||||
fn make_state(&self, idx: usize, val: Operand<'tcx>) -> Rvalue<'tcx> {
|
||||
fn make_state(&self, idx: VariantIdx, val: Operand<'tcx>) -> Rvalue<'tcx> {
|
||||
let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None, None);
|
||||
Rvalue::Aggregate(box adt, vec![val])
|
||||
}
|
||||
@ -229,11 +230,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
|
||||
});
|
||||
|
||||
let ret_val = match data.terminator().kind {
|
||||
TerminatorKind::Return => Some((1,
|
||||
TerminatorKind::Return => Some((VariantIdx::new(1),
|
||||
None,
|
||||
Operand::Move(Place::Local(self.new_ret_local)),
|
||||
None)),
|
||||
TerminatorKind::Yield { ref value, resume, drop } => Some((0,
|
||||
TerminatorKind::Yield { ref value, resume, drop } => Some((VariantIdx::new(0),
|
||||
Some(resume),
|
||||
value.clone(),
|
||||
drop)),
|
||||
|
@ -14,6 +14,7 @@ use rustc::mir::*;
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
@ -94,7 +95,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug {
|
||||
|
||||
fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path>;
|
||||
fn deref_subpath(&self, path: Self::Path) -> Option<Self::Path>;
|
||||
fn downcast_subpath(&self, path: Self::Path, variant: usize) -> Option<Self::Path>;
|
||||
fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path>;
|
||||
fn array_subpath(&self, path: Self::Path, index: u32, size: u32) -> Option<Self::Path>;
|
||||
}
|
||||
|
||||
@ -392,7 +393,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
let fields = self.move_paths_for_fields(
|
||||
self.place,
|
||||
self.path,
|
||||
&adt.variants[0],
|
||||
&adt.variants[VariantIdx::new(0)],
|
||||
substs
|
||||
);
|
||||
self.drop_ladder(fields, succ, unwind)
|
||||
@ -416,7 +417,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
|
||||
let mut have_otherwise = false;
|
||||
|
||||
for (variant_index, discr) in adt.discriminants(self.tcx()).enumerate() {
|
||||
for (variant_index, discr) in adt.discriminants(self.tcx()) {
|
||||
let subpath = self.elaborator.downcast_subpath(
|
||||
self.path, variant_index);
|
||||
if let Some(variant_path) = subpath {
|
||||
@ -894,7 +895,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
||||
let tcx = self.tcx();
|
||||
let unit_temp = Place::Local(self.new_temp(tcx.mk_unit()));
|
||||
let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
|
||||
let args = adt.variants[0].fields.iter().enumerate().map(|(i, f)| {
|
||||
let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| {
|
||||
let field = Field::new(i);
|
||||
let field_ty = f.ty(self.tcx(), substs);
|
||||
Operand::Move(self.place.clone().field(field, field_ty))
|
||||
|
@ -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,16 @@ 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;
|
||||
|
@ -103,6 +103,8 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoB
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::util::{Representability, IntTypeExt, Discr};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
||||
|
||||
use require_c_abi_if_variadic;
|
||||
@ -1837,10 +1839,11 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
|
||||
for (discr, v) in def.discriminants(tcx).zip(vs) {
|
||||
for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
|
||||
// Check for duplicate discriminant values
|
||||
if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
|
||||
let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
|
||||
let variant_did = def.variants[VariantIdx::new(i)].did;
|
||||
let variant_i_node_id = tcx.hir.as_local_node_id(variant_did).unwrap();
|
||||
let variant_i = tcx.hir.expect_variant(variant_i_node_id);
|
||||
let i_span = match variant_i.node.disr_expr {
|
||||
Some(ref expr) => tcx.hir.span(expr.id),
|
||||
|
@ -651,7 +651,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
|
||||
};
|
||||
(
|
||||
AdtKind::Struct,
|
||||
vec![convert_variant(
|
||||
std::iter::once(convert_variant(
|
||||
tcx,
|
||||
ctor_id.unwrap_or(def_id),
|
||||
item.name,
|
||||
@ -659,12 +659,12 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
|
||||
def,
|
||||
AdtKind::Struct,
|
||||
def_id
|
||||
)],
|
||||
)).collect(),
|
||||
)
|
||||
}
|
||||
ItemKind::Union(ref def, _) => (
|
||||
AdtKind::Union,
|
||||
vec![convert_variant(
|
||||
std::iter::once(convert_variant(
|
||||
tcx,
|
||||
def_id,
|
||||
item.name,
|
||||
@ -672,7 +672,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
|
||||
def,
|
||||
AdtKind::Union,
|
||||
def_id
|
||||
)],
|
||||
)).collect(),
|
||||
),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -38,10 +38,12 @@ use rustc::hir::def::{self, Def, CtorKind};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::middle::stability;
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt;
|
||||
@ -98,6 +100,12 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clean<U>, U, V: Idx> Clean<IndexVec<V, U>> for IndexVec<V, T> {
|
||||
fn clean(&self, cx: &DocContext) -> IndexVec<V, U> {
|
||||
self.iter().map(|x| x.clean(cx)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clean<U>, U> Clean<U> for P<T> {
|
||||
fn clean(&self, cx: &DocContext) -> U {
|
||||
(**self).clean(cx)
|
||||
@ -2886,7 +2894,7 @@ impl Clean<VariantStruct> for ::rustc::hir::VariantData {
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Enum {
|
||||
pub variants: Vec<Item>,
|
||||
pub variants: IndexVec<VariantIdx, Item>,
|
||||
pub generics: Generics,
|
||||
pub variants_stripped: bool,
|
||||
}
|
||||
@ -2902,7 +2910,7 @@ impl Clean<Item> for doctree::Enum {
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
inner: EnumItem(Enum {
|
||||
variants: self.variants.clean(cx),
|
||||
variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
|
||||
generics: self.generics.clean(cx),
|
||||
variants_stripped: false,
|
||||
}),
|
||||
|
@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/ub-enum.rs:61:1
|
||||
|
|
||||
LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .Some.0.1, but expected something less or equal to 1114111
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user