Use type safe `VariantIdx` instead of `usize` everywhere
This commit is contained in:
parent
740fb0cbaa
commit
4a9ed3f25a
|
@ -2246,6 +2246,7 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc 0.0.0",
|
"rustc 0.0.0",
|
||||||
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_mir 0.0.0",
|
"rustc_mir 0.0.0",
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
"syntax 0.0.0",
|
"syntax 0.0.0",
|
||||||
|
|
|
@ -1754,7 +1754,7 @@ pub enum StatementKind<'tcx> {
|
||||||
/// Write the discriminant for a variant to the enum Place.
|
/// Write the discriminant for a variant to the enum Place.
|
||||||
SetDiscriminant {
|
SetDiscriminant {
|
||||||
place: Place<'tcx>,
|
place: Place<'tcx>,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Start a live range for the storage of the local.
|
/// Start a live range for the storage of the local.
|
||||||
|
|
|
@ -2149,11 +2149,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
.expect("variant_with_id: unknown variant")
|
.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
|
self.variants
|
||||||
.iter()
|
.iter_enumerated()
|
||||||
.position(|v| v.did == vid)
|
.find(|(_, v)| v.did == vid)
|
||||||
.expect("variant_index_with_id: unknown variant")
|
.expect("variant_index_with_id: unknown variant")
|
||||||
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variant_of_def(&self, def: Def) -> &VariantDef {
|
pub fn variant_of_def(&self, def: Def) -> &VariantDef {
|
||||||
|
|
|
@ -39,7 +39,7 @@ use rustc::middle::weak_lang_items;
|
||||||
use rustc::mir::mono::{Linkage, Visibility, Stats, CodegenUnitNameBuilder};
|
use rustc::mir::mono::{Linkage, Visibility, Stats, CodegenUnitNameBuilder};
|
||||||
use rustc::middle::cstore::{EncodedMetadata};
|
use rustc::middle::cstore::{EncodedMetadata};
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
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::ty::query::Providers;
|
||||||
use rustc::middle::cstore::{self, LinkagePreference};
|
use rustc::middle::cstore::{self, LinkagePreference};
|
||||||
use rustc::middle::exported_symbols;
|
use rustc::middle::exported_symbols;
|
||||||
|
@ -73,6 +73,7 @@ use rustc::util::nodemap::FxHashMap;
|
||||||
use CrateInfo;
|
use CrateInfo;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
@ -309,7 +310,7 @@ pub fn coerce_unsized_into(
|
||||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
||||||
assert_eq!(def_a, 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 src_f = src.project_field(bx, i);
|
||||||
let dst_f = dst.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::mir::mono::Stats;
|
||||||
use rustc::session::config::{self, DebugInfo};
|
use rustc::session::config::{self, DebugInfo};
|
||||||
use rustc::session::Session;
|
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::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use rustc_target::spec::{HasTargetSpec, Target};
|
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
|
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
|
||||||
pub used_statics: RefCell<Vec<&'a Value>>,
|
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 scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
|
||||||
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
||||||
pub isize_ty: &'a Type,
|
pub isize_ty: &'a Type,
|
||||||
|
|
|
@ -1241,7 +1241,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
// This doesn't matter in this case.
|
// This doesn't matter in this case.
|
||||||
NoDiscriminant
|
NoDiscriminant
|
||||||
};
|
};
|
||||||
(0..variants.len()).map(|i| {
|
variants.iter_enumerated().map(|(i, _)| {
|
||||||
let variant = self.layout.for_variant(cx, i);
|
let variant = self.layout.for_variant(cx, i);
|
||||||
let (variant_type_metadata, member_desc_factory) =
|
let (variant_type_metadata, member_desc_factory) =
|
||||||
describe_enum_variant(cx,
|
describe_enum_variant(cx,
|
||||||
|
@ -1341,7 +1341,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
(0..variants.len()).map(|i| {
|
variants.iter_enumerated().map(|(i, _)| {
|
||||||
let variant = self.layout.for_variant(cx, i);
|
let variant = self.layout.for_variant(cx, i);
|
||||||
let (variant_type_metadata, member_desc_factory) =
|
let (variant_type_metadata, member_desc_factory) =
|
||||||
describe_enum_variant(cx,
|
describe_enum_variant(cx,
|
||||||
|
@ -1361,8 +1361,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
||||||
let niche_value = if i == dataful_variant {
|
let niche_value = if i == dataful_variant {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let value = (i as u128)
|
let value = (i.as_u32() as u128)
|
||||||
.wrapping_sub(*niche_variants.start() as u128)
|
.wrapping_sub(niche_variants.start().as_u32() as u128)
|
||||||
.wrapping_add(niche_start);
|
.wrapping_add(niche_start);
|
||||||
let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
|
let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
|
||||||
Some(value as u64)
|
Some(value as u64)
|
||||||
|
@ -1530,7 +1530,7 @@ fn prepare_enum_metadata(
|
||||||
let def = enum_type.ty_adt_def().unwrap();
|
let def = enum_type.ty_adt_def().unwrap();
|
||||||
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
|
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
|
||||||
.zip(&def.variants)
|
.zip(&def.variants)
|
||||||
.map(|(discr, v)| {
|
.map(|((_, discr), v)| {
|
||||||
let name = SmallCStr::new(&v.name.as_str());
|
let name = SmallCStr::new(&v.name.as_str());
|
||||||
unsafe {
|
unsafe {
|
||||||
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
use llvm::{self, LLVMConstInBoundsGEP};
|
use llvm::{self, LLVMConstInBoundsGEP};
|
||||||
use rustc::ty::{self, Ty};
|
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;
|
||||||
use rustc::mir::tcx::PlaceTy;
|
use rustc::mir::tcx::PlaceTy;
|
||||||
use base;
|
use base;
|
||||||
|
@ -281,7 +281,7 @@ impl PlaceRef<'ll, 'tcx> {
|
||||||
match self.layout.variants {
|
match self.layout.variants {
|
||||||
layout::Variants::Single { index } => {
|
layout::Variants::Single { index } => {
|
||||||
let discr_val = self.layout.ty.ty_adt_def().map_or(
|
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);
|
|def| def.discriminant_for_variant(bx.cx.tcx, index).val);
|
||||||
return C_uint_big(cast_to, discr_val);
|
return C_uint_big(cast_to, discr_val);
|
||||||
}
|
}
|
||||||
|
@ -320,16 +320,16 @@ impl PlaceRef<'ll, 'tcx> {
|
||||||
C_uint_big(niche_llty, niche_start)
|
C_uint_big(niche_llty, niche_start)
|
||||||
};
|
};
|
||||||
bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval),
|
bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval),
|
||||||
C_uint(cast_to, *niche_variants.start() as u64),
|
C_uint(cast_to, niche_variants.start().as_u32() as u64),
|
||||||
C_uint(cast_to, dataful_variant as u64))
|
C_uint(cast_to, dataful_variant.as_u32() as u64))
|
||||||
} else {
|
} else {
|
||||||
// Rebase from niche values to discriminant values.
|
// 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 = 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.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max),
|
||||||
bx.intcast(lldiscr, cast_to, false),
|
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
|
/// Set the discriminant for a new value of the given case of the given
|
||||||
/// representation.
|
/// 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() {
|
if self.layout.for_variant(bx.cx, variant_index).abi.is_uninhabited() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,8 @@ impl PlaceRef<'ll, 'tcx> {
|
||||||
|
|
||||||
let niche = self.project_field(bx, 0);
|
let niche = self.project_field(bx, 0);
|
||||||
let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
|
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);
|
.wrapping_add(niche_start);
|
||||||
// FIXME(eddyb) Check the actual primitive type here.
|
// FIXME(eddyb) Check the actual primitive type here.
|
||||||
let niche_llval = if niche_value == 0 {
|
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> {
|
-> PlaceRef<'ll, 'tcx> {
|
||||||
let mut downcast = *self;
|
let mut downcast = *self;
|
||||||
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
|
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
|
||||||
|
|
|
@ -16,3 +16,4 @@ rustc_mir = { path = "../librustc_mir"}
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
syntax_pos = { path = "../libsyntax_pos" }
|
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_mir;
|
||||||
extern crate rustc_target;
|
extern crate rustc_target;
|
||||||
extern crate syntax_pos;
|
extern crate syntax_pos;
|
||||||
|
extern crate rustc_data_structures;
|
||||||
|
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray};
|
use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray};
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
use rustc::hir::Node;
|
use rustc::hir::Node;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
|
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 util::nodemap::FxHashSet;
|
||||||
use lint::{LateContext, LintContext, LintArray};
|
use lint::{LateContext, LintContext, LintArray};
|
||||||
use lint::{LintPass, LateLintPass};
|
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 {
|
if def.variants.len() == 2 {
|
||||||
let data_idx;
|
let data_idx;
|
||||||
|
|
||||||
if def.variants[0].fields.is_empty() {
|
let zero = VariantIdx::new(0);
|
||||||
data_idx = 1;
|
let one = VariantIdx::new(1);
|
||||||
} else if def.variants[1].fields.is_empty() {
|
|
||||||
data_idx = 0;
|
if def.variants[zero].fields.is_empty() {
|
||||||
|
data_idx = one;
|
||||||
|
} else if def.variants[one].fields.is_empty() {
|
||||||
|
data_idx = zero;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -601,7 +601,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} 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)
|
tcx.alloc_adt_def(did, kind, variants, repr)
|
||||||
|
|
|
@ -27,6 +27,7 @@ use rustc::mir::{self, interpret};
|
||||||
use rustc::traits::specialization_graph;
|
use rustc::traits::specialization_graph;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, ReprOptions, SymbolName};
|
use rustc::ty::{self, Ty, TyCtxt, ReprOptions, SymbolName};
|
||||||
use rustc::ty::codec::{self as ty_codec, TyEncoder};
|
use rustc::ty::codec::{self as ty_codec, TyEncoder};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
|
|
||||||
use rustc::session::config::{self, CrateType};
|
use rustc::session::config::{self, CrateType};
|
||||||
use rustc::util::nodemap::FxHashMap;
|
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,
|
/// the right to access any information in the adt-def (including,
|
||||||
/// e.g., the length of the various vectors).
|
/// e.g., the length of the various vectors).
|
||||||
fn encode_enum_variant_info(&mut self,
|
fn encode_enum_variant_info(&mut self,
|
||||||
(enum_did, Untracked(index)): (DefId, Untracked<usize>))
|
(enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>))
|
||||||
-> Entry<'tcx> {
|
-> Entry<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let def = tcx.adt_def(enum_did);
|
let def = tcx.adt_def(enum_did);
|
||||||
|
@ -675,7 +676,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||||
/// vectors).
|
/// vectors).
|
||||||
fn encode_field(&mut self,
|
fn encode_field(&mut self,
|
||||||
(adt_def_id, Untracked((variant_index, field_index))): (DefId,
|
(adt_def_id, Untracked((variant_index, field_index))): (DefId,
|
||||||
Untracked<(usize,
|
Untracked<(VariantIdx,
|
||||||
usize)>))
|
usize)>))
|
||||||
-> Entry<'tcx> {
|
-> Entry<'tcx> {
|
||||||
let tcx = self.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> {
|
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||||
fn encode_fields(&mut self, adt_def_id: DefId) {
|
fn encode_fields(&mut self, adt_def_id: DefId) {
|
||||||
let def = self.tcx.adt_def(adt_def_id);
|
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() {
|
for (field_index, field) in variant.fields.iter().enumerate() {
|
||||||
self.record(field.did,
|
self.record(field.did,
|
||||||
IsolatedEncoder::encode_field,
|
IsolatedEncoder::encode_field,
|
||||||
|
@ -1734,7 +1735,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||||
self.encode_fields(def_id);
|
self.encode_fields(def_id);
|
||||||
|
|
||||||
let def = self.tcx.adt_def(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,
|
self.record(variant.did,
|
||||||
IsolatedEncoder::encode_enum_variant_info,
|
IsolatedEncoder::encode_enum_variant_info,
|
||||||
(def_id, Untracked(i)));
|
(def_id, Untracked(i)));
|
||||||
|
|
|
@ -47,7 +47,8 @@ use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
|
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
|
||||||
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
|
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
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::rc::Rc;
|
||||||
use std::{fmt, iter};
|
use std::{fmt, iter};
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
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 {
|
ProjectionElem::Downcast(adt_def1, index) => match base_ty.sty {
|
||||||
ty::Adt(adt_def, substs) if adt_def.is_enum() && adt_def == adt_def1 => {
|
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 {
|
PlaceTy::Ty {
|
||||||
ty: span_mirbug_and_err!(
|
ty: span_mirbug_and_err!(
|
||||||
self,
|
self,
|
||||||
|
@ -654,7 +655,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||||
variant_index,
|
variant_index,
|
||||||
} => (&adt_def.variants[variant_index], substs),
|
} => (&adt_def.variants[variant_index], substs),
|
||||||
PlaceTy::Ty { ty } => match ty.sty {
|
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) => {
|
ty::Closure(def_id, substs) => {
|
||||||
return match substs.upvar_tys(def_id, tcx).nth(field.index()) {
|
return match substs.upvar_tys(def_id, tcx).nth(field.index()) {
|
||||||
Some(ty) => Ok(ty),
|
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!(
|
span_bug!(
|
||||||
stmt.source_info.span,
|
stmt.source_info.span,
|
||||||
"bad set discriminant ({:?} = {:?}): value of of range",
|
"bad set discriminant ({:?} = {:?}): value of of range",
|
||||||
|
|
|
@ -22,6 +22,7 @@ use hair::pattern::PatternTypeProjections;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc_data_structures::bit_set::BitSet;
|
use rustc_data_structures::bit_set::BitSet;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use syntax::ast::{Name, NodeId};
|
use syntax::ast::{Name, NodeId};
|
||||||
|
@ -663,7 +664,7 @@ enum TestKind<'tcx> {
|
||||||
// test the branches of enum
|
// test the branches of enum
|
||||||
Switch {
|
Switch {
|
||||||
adt_def: &'tcx ty::AdtDef,
|
adt_def: &'tcx ty::AdtDef,
|
||||||
variants: BitSet<usize>,
|
variants: BitSet<VariantIdx>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// test the branches of enum
|
// 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 } => {
|
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 || {
|
i == variant_index || {
|
||||||
self.hir.tcx().features().never_type &&
|
self.hir.tcx().features().never_type &&
|
||||||
self.hir.tcx().features().exhaustive_patterns &&
|
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_data_structures::fx::FxHashMap;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::util::IntTypeExt;
|
use rustc::ty::util::IntTypeExt;
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::hir::{RangeEnd, Mutability};
|
use rustc::hir::{RangeEnd, Mutability};
|
||||||
use syntax_pos::Span;
|
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,
|
pub fn add_variants_to_switch<'pat>(&mut self,
|
||||||
test_place: &Place<'tcx>,
|
test_place: &Place<'tcx>,
|
||||||
candidate: &Candidate<'pat, 'tcx>,
|
candidate: &Candidate<'pat, 'tcx>,
|
||||||
variants: &mut BitSet<usize>)
|
variants: &mut BitSet<VariantIdx>)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
|
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 targets = Vec::with_capacity(used_variants + 1);
|
||||||
let mut values = Vec::with_capacity(used_variants);
|
let mut values = Vec::with_capacity(used_variants);
|
||||||
let tcx = self.hir.tcx();
|
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) {
|
target_blocks.push(if variants.contains(idx) {
|
||||||
values.push(discr.val);
|
values.push(discr.val);
|
||||||
targets.push(self.cfg.start_new_block());
|
targets.push(self.cfg.start_new_block());
|
||||||
|
@ -512,7 +513,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
variant_index,
|
variant_index,
|
||||||
subpatterns,
|
subpatterns,
|
||||||
candidate);
|
candidate);
|
||||||
resulting_candidates[variant_index].push(new_candidate);
|
resulting_candidates[variant_index.as_usize()].push(new_candidate);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
(&TestKind::Switch { .. }, _) => false,
|
(&TestKind::Switch { .. }, _) => false,
|
||||||
|
@ -673,7 +674,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
fn candidate_after_variant_switch<'pat>(&mut self,
|
fn candidate_after_variant_switch<'pat>(&mut self,
|
||||||
match_pair_index: usize,
|
match_pair_index: usize,
|
||||||
adt_def: &'tcx ty::AdtDef,
|
adt_def: &'tcx ty::AdtDef,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
subpatterns: &'pat [FieldPattern<'tcx>],
|
subpatterns: &'pat [FieldPattern<'tcx>],
|
||||||
candidate: &Candidate<'pat, 'tcx>)
|
candidate: &Candidate<'pat, 'tcx>)
|
||||||
-> Candidate<'pat, 'tcx> {
|
-> Candidate<'pat, 'tcx> {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use build::matches::MatchPair;
|
||||||
use hair::*;
|
use hair::*;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
pub fn field_match_pairs<'pat>(&mut self,
|
pub fn field_match_pairs<'pat>(&mut self,
|
||||||
|
|
|
@ -21,7 +21,7 @@ use rustc::hir::def::Def;
|
||||||
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
|
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
|
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::ty::subst::Subst;
|
||||||
use rustc::traits::Reveal;
|
use rustc::traits::Reveal;
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
|
@ -481,7 +481,7 @@ pub fn const_field<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
variant: Option<u32>,
|
variant: Option<VariantIdx>,
|
||||||
field: mir::Field,
|
field: mir::Field,
|
||||||
value: &'tcx ty::Const<'tcx>,
|
value: &'tcx ty::Const<'tcx>,
|
||||||
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
|
||||||
|
@ -513,7 +513,7 @@ pub fn const_variant_index<'a, 'tcx>(
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
val: &'tcx ty::Const<'tcx>,
|
val: &'tcx ty::Const<'tcx>,
|
||||||
) -> EvalResult<'tcx, usize> {
|
) -> EvalResult<'tcx, VariantIdx> {
|
||||||
trace!("const_variant_index: {:?}, {:?}", instance, val);
|
trace!("const_variant_index: {:?}, {:?}", instance, val);
|
||||||
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
|
||||||
let op = ecx.const_to_op(val)?;
|
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)))
|
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
|
||||||
}
|
}
|
||||||
Def::StructCtor(_, CtorKind::Fn) |
|
Def::StructCtor(_, CtorKind::Fn) |
|
||||||
Def::SelfCtor(..) => Some((adt_def, 0)),
|
Def::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -468,7 +468,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
AdtKind::Struct | AdtKind::Union => {
|
AdtKind::Struct | AdtKind::Union => {
|
||||||
ExprKind::Adt {
|
ExprKind::Adt {
|
||||||
adt_def: adt,
|
adt_def: adt,
|
||||||
variant_index: 0,
|
variant_index: VariantIdx::new(0),
|
||||||
substs,
|
substs,
|
||||||
user_ty: cx.user_substs_applied_to_adt(expr.hir_id, adt),
|
user_ty: cx.user_substs_applied_to_adt(expr.hir_id, adt),
|
||||||
fields: field_refs(cx, fields),
|
fields: field_refs(cx, fields),
|
||||||
|
|
|
@ -25,6 +25,7 @@ use rustc::infer::InferCtxt;
|
||||||
use rustc::ty::subst::Subst;
|
use rustc::ty::subst::Subst;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::subst::{Kind, Substs};
|
use rustc::ty::subst::{Kind, Substs};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use syntax::ast::{self, LitKind};
|
use syntax::ast::{self, LitKind};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::symbol::Symbol;
|
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);
|
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())
|
(0..adt_def.variants[variant_index].fields.len())
|
||||||
.map(Field::new)
|
.map(Field::new)
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -19,6 +19,7 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const};
|
use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
@ -264,7 +265,7 @@ pub enum ExprKind<'tcx> {
|
||||||
},
|
},
|
||||||
Adt {
|
Adt {
|
||||||
adt_def: &'tcx AdtDef,
|
adt_def: &'tcx AdtDef,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
|
|
||||||
/// Optional user-given substs: for something like `let x =
|
/// 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::def_id::DefId;
|
||||||
use rustc::hir::RangeEnd;
|
use rustc::hir::RangeEnd;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
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::Field;
|
||||||
use rustc::mir::interpret::ConstValue;
|
use rustc::mir::interpret::ConstValue;
|
||||||
|
@ -422,12 +422,12 @@ pub enum Constructor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> 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 {
|
match self {
|
||||||
&Variant(vid) => adt.variant_index_with_id(vid),
|
&Variant(vid) => adt.variant_index_with_id(vid),
|
||||||
&Single => {
|
&Single => {
|
||||||
assert!(!adt.is_enum());
|
assert!(!adt.is_enum());
|
||||||
0
|
VariantIdx::new(0)
|
||||||
}
|
}
|
||||||
_ => bug!("bad constructor {:?} for adt {:?}", self, adt)
|
_ => 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::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
|
||||||
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
|
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
|
||||||
use rustc::ty::subst::{Substs, Kind};
|
use rustc::ty::subst::{Substs, Kind};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::hir::{self, PatKind, RangeEnd};
|
use rustc::hir::{self, PatKind, RangeEnd};
|
||||||
use rustc::hir::def::{Def, CtorKind};
|
use rustc::hir::def::{Def, CtorKind};
|
||||||
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||||
|
@ -111,7 +112,7 @@ impl<'tcx> PatternTypeProjections<'tcx> {
|
||||||
|
|
||||||
pub(crate) fn variant(&self,
|
pub(crate) fn variant(&self,
|
||||||
adt_def: &'tcx AdtDef,
|
adt_def: &'tcx AdtDef,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
field: Field) -> Self {
|
field: Field) -> Self {
|
||||||
self.map_projs(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
|
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,
|
pub(crate) fn variant(&self,
|
||||||
adt_def: &'tcx AdtDef,
|
adt_def: &'tcx AdtDef,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
field: Field) -> Self {
|
field: Field) -> Self {
|
||||||
let mut new = self.clone();
|
let mut new = self.clone();
|
||||||
new.0.projs.push(ProjectionElem::Downcast(adt_def, variant_index));
|
new.0.projs.push(ProjectionElem::Downcast(adt_def, variant_index));
|
||||||
|
@ -200,7 +201,7 @@ pub enum PatternKind<'tcx> {
|
||||||
Variant {
|
Variant {
|
||||||
adt_def: &'tcx AdtDef,
|
adt_def: &'tcx AdtDef,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
subpatterns: Vec<FieldPattern<'tcx>>,
|
subpatterns: Vec<FieldPattern<'tcx>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -273,7 +274,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
|
||||||
}
|
}
|
||||||
_ => if let ty::Adt(adt, _) = self.ty.sty {
|
_ => if let ty::Adt(adt, _) = self.ty.sty {
|
||||||
if !adt.is_enum() {
|
if !adt.is_enum() {
|
||||||
Some(&adt.variants[0])
|
Some(&adt.variants[VariantIdx::new(0)])
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -1160,7 +1161,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
|
||||||
} => PatternKind::Variant {
|
} => PatternKind::Variant {
|
||||||
adt_def: adt_def.fold_with(folder),
|
adt_def: adt_def.fold_with(folder),
|
||||||
substs: substs.fold_with(folder),
|
substs: substs.fold_with(folder),
|
||||||
variant_index: variant_index.fold_with(folder),
|
variant_index,
|
||||||
subpatterns: subpatterns.fold_with(folder)
|
subpatterns: subpatterns.fold_with(folder)
|
||||||
},
|
},
|
||||||
PatternKind::Leaf {
|
PatternKind::Leaf {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use rustc::{mir, ty};
|
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::{
|
use rustc::mir::interpret::{
|
||||||
GlobalId, AllocId,
|
GlobalId, AllocId,
|
||||||
|
@ -417,7 +417,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||||
pub fn operand_downcast(
|
pub fn operand_downcast(
|
||||||
&self,
|
&self,
|
||||||
op: OpTy<'tcx, M::PointerTag>,
|
op: OpTy<'tcx, M::PointerTag>,
|
||||||
variant: usize,
|
variant: VariantIdx,
|
||||||
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||||
// Downcasts only change the layout
|
// Downcasts only change the layout
|
||||||
Ok(match op.try_as_mplace() {
|
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(
|
pub fn read_discriminant(
|
||||||
&self,
|
&self,
|
||||||
rval: OpTy<'tcx, M::PointerTag>,
|
rval: OpTy<'tcx, M::PointerTag>,
|
||||||
) -> EvalResult<'tcx, (u128, usize)> {
|
) -> EvalResult<'tcx, (u128, VariantIdx)> {
|
||||||
trace!("read_discriminant_value {:#?}", rval.layout);
|
trace!("read_discriminant_value {:#?}", rval.layout);
|
||||||
|
|
||||||
match rval.layout.variants {
|
match rval.layout.variants {
|
||||||
layout::Variants::Single { index } => {
|
layout::Variants::Single { index } => {
|
||||||
let discr_val = rval.layout.ty.ty_adt_def().map_or(
|
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);
|
|def| def.discriminant_for_variant(*self.tcx, index).val);
|
||||||
return Ok((discr_val, index));
|
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()
|
.ty_adt_def()
|
||||||
.expect("tagged layout for non adt")
|
.expect("tagged layout for non adt")
|
||||||
.discriminants(self.tcx.tcx)
|
.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()))?;
|
.ok_or_else(|| EvalErrorKind::InvalidDiscriminant(raw_discr.erase_tag()))?;
|
||||||
(real_discr, index)
|
(real_discr, index.0)
|
||||||
},
|
},
|
||||||
layout::Variants::NicheFilling {
|
layout::Variants::NicheFilling {
|
||||||
dataful_variant,
|
dataful_variant,
|
||||||
|
@ -655,33 +655,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||||
niche_start,
|
niche_start,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let variants_start = *niche_variants.start() as u128;
|
let variants_start = niche_variants.start().as_u32() as u128;
|
||||||
let variants_end = *niche_variants.end() as u128;
|
let variants_end = niche_variants.end().as_u32() as u128;
|
||||||
let real_discr = match raw_discr {
|
match raw_discr {
|
||||||
Scalar::Ptr(_) => {
|
Scalar::Ptr(_) => {
|
||||||
// The niche must be just 0 (which a pointer value never is)
|
// The niche must be just 0 (which a pointer value never is)
|
||||||
assert!(niche_start == 0);
|
assert!(niche_start == 0);
|
||||||
assert!(variants_start == variants_end);
|
assert!(variants_start == variants_end);
|
||||||
dataful_variant as u128
|
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||||
},
|
},
|
||||||
Scalar::Bits { bits: raw_discr, size } => {
|
Scalar::Bits { bits: raw_discr, size } => {
|
||||||
assert_eq!(size as u64, discr_val.layout.size.bytes());
|
assert_eq!(size as u64, discr_val.layout.size.bytes());
|
||||||
let discr = raw_discr.wrapping_sub(niche_start)
|
let discr = raw_discr.wrapping_sub(niche_start)
|
||||||
.wrapping_add(variants_start);
|
.wrapping_add(variants_start);
|
||||||
if variants_start <= discr && discr <= variants_end {
|
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 {
|
} 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::hir;
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{self, Ty};
|
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::{
|
use rustc::mir::interpret::{
|
||||||
GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic
|
GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic
|
||||||
|
@ -431,7 +431,7 @@ where
|
||||||
pub fn mplace_downcast(
|
pub fn mplace_downcast(
|
||||||
&self,
|
&self,
|
||||||
base: MPlaceTy<'tcx, M::PointerTag>,
|
base: MPlaceTy<'tcx, M::PointerTag>,
|
||||||
variant: usize,
|
variant: VariantIdx,
|
||||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||||
// Downcasts only change the layout
|
// Downcasts only change the layout
|
||||||
assert!(base.meta.is_none());
|
assert!(base.meta.is_none());
|
||||||
|
@ -498,7 +498,7 @@ where
|
||||||
pub fn place_downcast(
|
pub fn place_downcast(
|
||||||
&self,
|
&self,
|
||||||
base: PlaceTy<'tcx, M::PointerTag>,
|
base: PlaceTy<'tcx, M::PointerTag>,
|
||||||
variant: usize,
|
variant: VariantIdx,
|
||||||
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||||
// Downcast just changes the layout
|
// Downcast just changes the layout
|
||||||
Ok(match base.place {
|
Ok(match base.place {
|
||||||
|
@ -901,7 +901,7 @@ where
|
||||||
|
|
||||||
pub fn write_discriminant_index(
|
pub fn write_discriminant_index(
|
||||||
&mut self,
|
&mut self,
|
||||||
variant_index: usize,
|
variant_index: VariantIdx,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> EvalResult<'tcx> {
|
) -> EvalResult<'tcx> {
|
||||||
match dest.layout.variants {
|
match dest.layout.variants {
|
||||||
|
@ -910,7 +910,7 @@ where
|
||||||
}
|
}
|
||||||
layout::Variants::Tagged { ref tag, .. } => {
|
layout::Variants::Tagged { ref tag, .. } => {
|
||||||
let adt_def = dest.layout.ty.ty_adt_def().unwrap();
|
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
|
let discr_val = adt_def
|
||||||
.discriminant_for_variant(*self.tcx, variant_index)
|
.discriminant_for_variant(*self.tcx, variant_index)
|
||||||
.val;
|
.val;
|
||||||
|
@ -931,11 +931,14 @@ where
|
||||||
niche_start,
|
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 {
|
if variant_index != dataful_variant {
|
||||||
let niche_dest =
|
let niche_dest =
|
||||||
self.place_field(dest, 0)?;
|
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);
|
.wrapping_add(niche_start);
|
||||||
self.write_scalar(
|
self.write_scalar(
|
||||||
Scalar::from_uint(niche_value, niche_dest.layout.size),
|
Scalar::from_uint(niche_value, niche_dest.layout.size),
|
||||||
|
|
|
@ -13,6 +13,7 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::infer;
|
use rustc::infer;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
|
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::ty::subst::{Subst, Substs};
|
use rustc::ty::subst::{Subst, Substs};
|
||||||
use rustc::ty::query::Providers;
|
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> {
|
fn deref_subpath(&self, _path: Self::Path) -> Option<Self::Path> {
|
||||||
None
|
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(())
|
Some(())
|
||||||
}
|
}
|
||||||
fn array_subpath(&self, _path: Self::Path, _index: u32, _size: u32) -> Option<Self::Path> {
|
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() {
|
let variant_no = if adt_def.is_enum() {
|
||||||
adt_def.variant_index_with_id(def_id)
|
adt_def.variant_index_with_id(def_id)
|
||||||
} else {
|
} else {
|
||||||
0
|
VariantIdx::new(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
// return = ADT(arg0, arg1, ...); return
|
// 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::MoveDataParamEnv;
|
||||||
use dataflow::{self, do_dataflow, DebugFormatted};
|
use dataflow::{self, do_dataflow, DebugFormatted};
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use rustc_data_structures::bit_set::BitSet;
|
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| {
|
dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
|
||||||
match p {
|
match p {
|
||||||
&Projection {
|
&Projection {
|
||||||
|
|
|
@ -64,6 +64,7 @@ use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor};
|
use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor};
|
||||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty};
|
use rustc::ty::{self, TyCtxt, AdtDef, Ty};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use util::dump_mir;
|
use util::dump_mir;
|
||||||
use util::liveness::{self, IdentityMap};
|
use util::liveness::{self, IdentityMap};
|
||||||
|
@ -158,7 +159,7 @@ struct TransformVisitor<'a, 'tcx: 'a> {
|
||||||
|
|
||||||
impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
||||||
// Make a GeneratorState rvalue
|
// 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);
|
let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None, None);
|
||||||
Rvalue::Aggregate(box adt, vec![val])
|
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 {
|
let ret_val = match data.terminator().kind {
|
||||||
TerminatorKind::Return => Some((1,
|
TerminatorKind::Return => Some((VariantIdx::new(1),
|
||||||
None,
|
None,
|
||||||
Operand::Move(Place::Local(self.new_ret_local)),
|
Operand::Move(Place::Local(self.new_ret_local)),
|
||||||
None)),
|
None)),
|
||||||
TerminatorKind::Yield { ref value, resume, drop } => Some((0,
|
TerminatorKind::Yield { ref value, resume, drop } => Some((VariantIdx::new(0),
|
||||||
Some(resume),
|
Some(resume),
|
||||||
value.clone(),
|
value.clone(),
|
||||||
drop)),
|
drop)),
|
||||||
|
|
|
@ -14,6 +14,7 @@ use rustc::mir::*;
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
use rustc::traits::Reveal;
|
use rustc::traits::Reveal;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::util::IntTypeExt;
|
use rustc::ty::util::IntTypeExt;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
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 field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path>;
|
||||||
fn deref_subpath(&self, path: Self::Path) -> 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>;
|
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(
|
let fields = self.move_paths_for_fields(
|
||||||
self.place,
|
self.place,
|
||||||
self.path,
|
self.path,
|
||||||
&adt.variants[0],
|
&adt.variants[VariantIdx::new(0)],
|
||||||
substs
|
substs
|
||||||
);
|
);
|
||||||
self.drop_ladder(fields, succ, unwind)
|
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;
|
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(
|
let subpath = self.elaborator.downcast_subpath(
|
||||||
self.path, variant_index);
|
self.path, variant_index);
|
||||||
if let Some(variant_path) = subpath {
|
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 tcx = self.tcx();
|
||||||
let unit_temp = Place::Local(self.new_temp(tcx.mk_unit()));
|
let unit_temp = Place::Local(self.new_temp(tcx.mk_unit()));
|
||||||
let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
|
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 = Field::new(i);
|
||||||
let field_ty = f.ty(self.tcx(), substs);
|
let field_ty = f.ty(self.tcx(), substs);
|
||||||
Operand::Move(self.place.clone().field(field, field_ty))
|
Operand::Move(self.place.clone().field(field, field_ty))
|
||||||
|
|
|
@ -914,7 +914,11 @@ pub trait LayoutOf {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TyLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
|
pub trait TyLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
|
||||||
fn for_variant(this: TyLayout<'a, Self>, cx: &C, variant_index: VariantIdx) -> 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;
|
fn field(this: TyLayout<'a, Self>, cx: &C, i: usize) -> C::TyLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,8 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoB
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc::ty::util::{Representability, IntTypeExt, Discr};
|
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 errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
||||||
|
|
||||||
use require_c_abi_if_variadic;
|
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());
|
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
|
// Check for duplicate discriminant values
|
||||||
if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
|
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 variant_i = tcx.hir.expect_variant(variant_i_node_id);
|
||||||
let i_span = match variant_i.node.disr_expr {
|
let i_span = match variant_i.node.disr_expr {
|
||||||
Some(ref expr) => tcx.hir.span(expr.id),
|
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,
|
AdtKind::Struct,
|
||||||
vec![convert_variant(
|
std::iter::once(convert_variant(
|
||||||
tcx,
|
tcx,
|
||||||
ctor_id.unwrap_or(def_id),
|
ctor_id.unwrap_or(def_id),
|
||||||
item.name,
|
item.name,
|
||||||
|
@ -659,12 +659,12 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
|
||||||
def,
|
def,
|
||||||
AdtKind::Struct,
|
AdtKind::Struct,
|
||||||
def_id
|
def_id
|
||||||
)],
|
)).collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ItemKind::Union(ref def, _) => (
|
ItemKind::Union(ref def, _) => (
|
||||||
AdtKind::Union,
|
AdtKind::Union,
|
||||||
vec![convert_variant(
|
std::iter::once(convert_variant(
|
||||||
tcx,
|
tcx,
|
||||||
def_id,
|
def_id,
|
||||||
item.name,
|
item.name,
|
||||||
|
@ -672,7 +672,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
|
||||||
def,
|
def,
|
||||||
AdtKind::Union,
|
AdtKind::Union,
|
||||||
def_id
|
def_id
|
||||||
)],
|
)).collect(),
|
||||||
),
|
),
|
||||||
_ => bug!(),
|
_ => 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::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
||||||
|
use rustc::ty::layout::VariantIdx;
|
||||||
use rustc::middle::stability;
|
use rustc::middle::stability;
|
||||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||||
use rustc_typeck::hir_ty_to_ty;
|
use rustc_typeck::hir_ty_to_ty;
|
||||||
use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
|
use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
|
||||||
|
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||||
|
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::fmt;
|
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> {
|
impl<T: Clean<U>, U> Clean<U> for P<T> {
|
||||||
fn clean(&self, cx: &DocContext) -> U {
|
fn clean(&self, cx: &DocContext) -> U {
|
||||||
(**self).clean(cx)
|
(**self).clean(cx)
|
||||||
|
@ -2886,7 +2894,7 @@ impl Clean<VariantStruct> for ::rustc::hir::VariantData {
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Enum {
|
pub struct Enum {
|
||||||
pub variants: Vec<Item>,
|
pub variants: IndexVec<VariantIdx, Item>,
|
||||||
pub generics: Generics,
|
pub generics: Generics,
|
||||||
pub variants_stripped: bool,
|
pub variants_stripped: bool,
|
||||||
}
|
}
|
||||||
|
@ -2902,7 +2910,7 @@ impl Clean<Item> for doctree::Enum {
|
||||||
stability: self.stab.clean(cx),
|
stability: self.stab.clean(cx),
|
||||||
deprecation: self.depr.clean(cx),
|
deprecation: self.depr.clean(cx),
|
||||||
inner: EnumItem(Enum {
|
inner: EnumItem(Enum {
|
||||||
variants: self.variants.clean(cx),
|
variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
|
||||||
generics: self.generics.clean(cx),
|
generics: self.generics.clean(cx),
|
||||||
variants_stripped: false,
|
variants_stripped: false,
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue