Skip to content

Commit 4a9ed3f

Browse files
committed
Use type safe VariantIdx instead of usize everywhere
1 parent 740fb0c commit 4a9ed3f

File tree

33 files changed

+144
-104
lines changed

33 files changed

+144
-104
lines changed

src/Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -2246,6 +2246,7 @@ version = "0.0.0"
22462246
dependencies = [
22472247
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
22482248
"rustc 0.0.0",
2249+
"rustc_data_structures 0.0.0",
22492250
"rustc_mir 0.0.0",
22502251
"rustc_target 0.0.0",
22512252
"syntax 0.0.0",

src/librustc/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1754,7 +1754,7 @@ pub enum StatementKind<'tcx> {
17541754
/// Write the discriminant for a variant to the enum Place.
17551755
SetDiscriminant {
17561756
place: Place<'tcx>,
1757-
variant_index: usize,
1757+
variant_index: VariantIdx,
17581758
},
17591759

17601760
/// Start a live range for the storage of the local.

src/librustc/ty/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2149,11 +2149,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
21492149
.expect("variant_with_id: unknown variant")
21502150
}
21512151

2152-
pub fn variant_index_with_id(&self, vid: DefId) -> usize {
2152+
pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
21532153
self.variants
2154-
.iter()
2155-
.position(|v| v.did == vid)
2154+
.iter_enumerated()
2155+
.find(|(_, v)| v.did == vid)
21562156
.expect("variant_index_with_id: unknown variant")
2157+
.0
21572158
}
21582159

21592160
pub fn variant_of_def(&self, def: Def) -> &VariantDef {

src/librustc_codegen_llvm/base.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use rustc::middle::weak_lang_items;
3939
use rustc::mir::mono::{Linkage, Visibility, Stats, CodegenUnitNameBuilder};
4040
use rustc::middle::cstore::{EncodedMetadata};
4141
use rustc::ty::{self, Ty, TyCtxt};
42-
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf};
42+
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx};
4343
use rustc::ty::query::Providers;
4444
use rustc::middle::cstore::{self, LinkagePreference};
4545
use rustc::middle::exported_symbols;
@@ -73,6 +73,7 @@ use rustc::util::nodemap::FxHashMap;
7373
use CrateInfo;
7474
use rustc_data_structures::small_c_str::SmallCStr;
7575
use rustc_data_structures::sync::Lrc;
76+
use rustc_data_structures::indexed_vec::Idx;
7677

7778
use std::any::Any;
7879
use std::cmp;
@@ -309,7 +310,7 @@ pub fn coerce_unsized_into(
309310
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
310311
assert_eq!(def_a, def_b);
311312

312-
for i in 0..def_a.variants[0].fields.len() {
313+
for i in 0..def_a.variants[VariantIdx::new(0)].fields.len() {
313314
let src_f = src.project_field(bx, i);
314315
let dst_f = dst.project_field(bx, i);
315316

src/librustc_codegen_llvm/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
2929
use rustc::mir::mono::Stats;
3030
use rustc::session::config::{self, DebugInfo};
3131
use rustc::session::Session;
32-
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout};
32+
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout, VariantIdx};
3333
use rustc::ty::{self, Ty, TyCtxt};
3434
use rustc::util::nodemap::FxHashMap;
3535
use rustc_target::spec::{HasTargetSpec, Target};
@@ -87,7 +87,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
8787
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
8888
pub used_statics: RefCell<Vec<&'a Value>>,
8989

90-
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), &'a Type>>,
90+
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'a Type>>,
9191
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
9292
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
9393
pub isize_ty: &'a Type,

src/librustc_codegen_llvm/debuginfo/metadata.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12411241
// This doesn't matter in this case.
12421242
NoDiscriminant
12431243
};
1244-
(0..variants.len()).map(|i| {
1244+
variants.iter_enumerated().map(|(i, _)| {
12451245
let variant = self.layout.for_variant(cx, i);
12461246
let (variant_type_metadata, member_desc_factory) =
12471247
describe_enum_variant(cx,
@@ -1341,7 +1341,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13411341
}
13421342
]
13431343
} else {
1344-
(0..variants.len()).map(|i| {
1344+
variants.iter_enumerated().map(|(i, _)| {
13451345
let variant = self.layout.for_variant(cx, i);
13461346
let (variant_type_metadata, member_desc_factory) =
13471347
describe_enum_variant(cx,
@@ -1361,8 +1361,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13611361
let niche_value = if i == dataful_variant {
13621362
None
13631363
} else {
1364-
let value = (i as u128)
1365-
.wrapping_sub(*niche_variants.start() as u128)
1364+
let value = (i.as_u32() as u128)
1365+
.wrapping_sub(niche_variants.start().as_u32() as u128)
13661366
.wrapping_add(niche_start);
13671367
let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
13681368
Some(value as u64)
@@ -1530,7 +1530,7 @@ fn prepare_enum_metadata(
15301530
let def = enum_type.ty_adt_def().unwrap();
15311531
let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
15321532
.zip(&def.variants)
1533-
.map(|(discr, v)| {
1533+
.map(|((_, discr), v)| {
15341534
let name = SmallCStr::new(&v.name.as_str());
15351535
unsafe {
15361536
Some(llvm::LLVMRustDIBuilderCreateEnumerator(

src/librustc_codegen_llvm/mir/place.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use llvm::{self, LLVMConstInBoundsGEP};
1212
use rustc::ty::{self, Ty};
13-
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size};
13+
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx};
1414
use rustc::mir;
1515
use rustc::mir::tcx::PlaceTy;
1616
use base;
@@ -281,7 +281,7 @@ impl PlaceRef<'ll, 'tcx> {
281281
match self.layout.variants {
282282
layout::Variants::Single { index } => {
283283
let discr_val = self.layout.ty.ty_adt_def().map_or(
284-
index as u128,
284+
index.as_u32() as u128,
285285
|def| def.discriminant_for_variant(bx.cx.tcx, index).val);
286286
return C_uint_big(cast_to, discr_val);
287287
}
@@ -320,24 +320,24 @@ impl PlaceRef<'ll, 'tcx> {
320320
C_uint_big(niche_llty, niche_start)
321321
};
322322
bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval),
323-
C_uint(cast_to, *niche_variants.start() as u64),
324-
C_uint(cast_to, dataful_variant as u64))
323+
C_uint(cast_to, niche_variants.start().as_u32() as u64),
324+
C_uint(cast_to, dataful_variant.as_u32() as u64))
325325
} else {
326326
// Rebase from niche values to discriminant values.
327-
let delta = niche_start.wrapping_sub(*niche_variants.start() as u128);
327+
let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128);
328328
let lldiscr = bx.sub(lldiscr, C_uint_big(niche_llty, delta));
329-
let lldiscr_max = C_uint(niche_llty, *niche_variants.end() as u64);
329+
let lldiscr_max = C_uint(niche_llty, niche_variants.end().as_u32() as u64);
330330
bx.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max),
331331
bx.intcast(lldiscr, cast_to, false),
332-
C_uint(cast_to, dataful_variant as u64))
332+
C_uint(cast_to, dataful_variant.as_u32() as u64))
333333
}
334334
}
335335
}
336336
}
337337

338338
/// Set the discriminant for a new value of the given case of the given
339339
/// representation.
340-
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) {
340+
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: VariantIdx) {
341341
if self.layout.for_variant(bx.cx, variant_index).abi.is_uninhabited() {
342342
return;
343343
}
@@ -376,7 +376,8 @@ impl PlaceRef<'ll, 'tcx> {
376376

377377
let niche = self.project_field(bx, 0);
378378
let niche_llty = niche.layout.immediate_llvm_type(bx.cx);
379-
let niche_value = ((variant_index - *niche_variants.start()) as u128)
379+
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
380+
let niche_value = (niche_value as u128)
380381
.wrapping_add(niche_start);
381382
// FIXME(eddyb) Check the actual primitive type here.
382383
let niche_llval = if niche_value == 0 {
@@ -401,7 +402,7 @@ impl PlaceRef<'ll, 'tcx> {
401402
}
402403
}
403404

404-
pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize)
405+
pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: VariantIdx)
405406
-> PlaceRef<'ll, 'tcx> {
406407
let mut downcast = *self;
407408
downcast.layout = self.layout.for_variant(bx.cx, variant_index);

src/librustc_lint/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ rustc_mir = { path = "../librustc_mir"}
1616
rustc_target = { path = "../librustc_target" }
1717
syntax = { path = "../libsyntax" }
1818
syntax_pos = { path = "../libsyntax_pos" }
19+
rustc_data_structures = { path = "../librustc_data_structures" }

src/librustc_lint/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern crate log;
4040
extern crate rustc_mir;
4141
extern crate rustc_target;
4242
extern crate syntax_pos;
43+
extern crate rustc_data_structures;
4344

4445
use rustc::lint;
4546
use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray};

src/librustc_lint/types.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
use rustc::hir::Node;
1414
use rustc::ty::subst::Substs;
1515
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
16-
use rustc::ty::layout::{self, IntegerExt, LayoutOf};
16+
use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx};
17+
use rustc_data_structures::indexed_vec::Idx;
1718
use util::nodemap::FxHashSet;
1819
use lint::{LateContext, LintContext, LintArray};
1920
use lint::{LintPass, LateLintPass};
@@ -452,10 +453,13 @@ fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
452453
if def.variants.len() == 2 {
453454
let data_idx;
454455

455-
if def.variants[0].fields.is_empty() {
456-
data_idx = 1;
457-
} else if def.variants[1].fields.is_empty() {
458-
data_idx = 0;
456+
let zero = VariantIdx::new(0);
457+
let one = VariantIdx::new(1);
458+
459+
if def.variants[zero].fields.is_empty() {
460+
data_idx = one;
461+
} else if def.variants[one].fields.is_empty() {
462+
data_idx = zero;
459463
} else {
460464
return false;
461465
}

src/librustc_metadata/decoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ impl<'a, 'tcx> CrateMetadata {
601601
})
602602
.collect()
603603
} else {
604-
vec![self.get_variant(tcx, &item, item_id, kind)]
604+
std::iter::once(self.get_variant(tcx, &item, item_id, kind)).collect()
605605
};
606606

607607
tcx.alloc_adt_def(did, kind, variants, repr)

src/librustc_metadata/encoder.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc::mir::{self, interpret};
2727
use rustc::traits::specialization_graph;
2828
use rustc::ty::{self, Ty, TyCtxt, ReprOptions, SymbolName};
2929
use rustc::ty::codec::{self as ty_codec, TyEncoder};
30+
use rustc::ty::layout::VariantIdx;
3031

3132
use rustc::session::config::{self, CrateType};
3233
use rustc::util::nodemap::FxHashMap;
@@ -580,7 +581,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
580581
/// the right to access any information in the adt-def (including,
581582
/// e.g., the length of the various vectors).
582583
fn encode_enum_variant_info(&mut self,
583-
(enum_did, Untracked(index)): (DefId, Untracked<usize>))
584+
(enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>))
584585
-> Entry<'tcx> {
585586
let tcx = self.tcx;
586587
let def = tcx.adt_def(enum_did);
@@ -675,7 +676,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
675676
/// vectors).
676677
fn encode_field(&mut self,
677678
(adt_def_id, Untracked((variant_index, field_index))): (DefId,
678-
Untracked<(usize,
679+
Untracked<(VariantIdx,
679680
usize)>))
680681
-> Entry<'tcx> {
681682
let tcx = self.tcx;
@@ -1667,7 +1668,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
16671668
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
16681669
fn encode_fields(&mut self, adt_def_id: DefId) {
16691670
let def = self.tcx.adt_def(adt_def_id);
1670-
for (variant_index, variant) in def.variants.iter().enumerate() {
1671+
for (variant_index, variant) in def.variants.iter_enumerated() {
16711672
for (field_index, field) in variant.fields.iter().enumerate() {
16721673
self.record(field.did,
16731674
IsolatedEncoder::encode_field,
@@ -1734,7 +1735,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
17341735
self.encode_fields(def_id);
17351736

17361737
let def = self.tcx.adt_def(def_id);
1737-
for (i, variant) in def.variants.iter().enumerate() {
1738+
for (i, variant) in def.variants.iter_enumerated() {
17381739
self.record(variant.did,
17391740
IsolatedEncoder::encode_enum_variant_info,
17401741
(def_id, Untracked(i)));

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ use rustc::ty::fold::TypeFoldable;
4747
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
4848
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
4949
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
50-
use rustc_data_structures::indexed_vec::IndexVec;
50+
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
51+
use rustc::ty::layout::VariantIdx;
5152
use std::rc::Rc;
5253
use std::{fmt, iter};
5354
use syntax_pos::{Span, DUMMY_SP};
@@ -574,7 +575,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
574575
},
575576
ProjectionElem::Downcast(adt_def1, index) => match base_ty.sty {
576577
ty::Adt(adt_def, substs) if adt_def.is_enum() && adt_def == adt_def1 => {
577-
if index >= adt_def.variants.len() {
578+
if index.as_usize() >= adt_def.variants.len() {
578579
PlaceTy::Ty {
579580
ty: span_mirbug_and_err!(
580581
self,
@@ -654,7 +655,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
654655
variant_index,
655656
} => (&adt_def.variants[variant_index], substs),
656657
PlaceTy::Ty { ty } => match ty.sty {
657-
ty::Adt(adt_def, substs) if !adt_def.is_enum() => (&adt_def.variants[0], substs),
658+
ty::Adt(adt_def, substs) if !adt_def.is_enum() =>
659+
(&adt_def.variants[VariantIdx::new(0)], substs),
658660
ty::Closure(def_id, substs) => {
659661
return match substs.upvar_tys(def_id, tcx).nth(field.index()) {
660662
Some(ty) => Ok(ty),
@@ -1280,7 +1282,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
12801282
);
12811283
}
12821284
};
1283-
if variant_index >= adt.variants.len() {
1285+
if variant_index.as_usize() >= adt.variants.len() {
12841286
span_bug!(
12851287
stmt.source_info.span,
12861288
"bad set discriminant ({:?} = {:?}): value of of range",

src/librustc_mir/build/matches/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use hair::pattern::PatternTypeProjections;
2222
use rustc::hir;
2323
use rustc::mir::*;
2424
use rustc::ty::{self, Ty};
25+
use rustc::ty::layout::VariantIdx;
2526
use rustc_data_structures::bit_set::BitSet;
2627
use rustc_data_structures::fx::FxHashMap;
2728
use syntax::ast::{Name, NodeId};
@@ -663,7 +664,7 @@ enum TestKind<'tcx> {
663664
// test the branches of enum
664665
Switch {
665666
adt_def: &'tcx ty::AdtDef,
666-
variants: BitSet<usize>,
667+
variants: BitSet<VariantIdx>,
667668
},
668669

669670
// test the branches of enum

src/librustc_mir/build/matches/simplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
123123
}
124124

125125
PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
126-
let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| {
126+
let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| {
127127
i == variant_index || {
128128
self.hir.tcx().features().never_type &&
129129
self.hir.tcx().features().exhaustive_patterns &&

src/librustc_mir/build/matches/test.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_data_structures::bit_set::BitSet;
2222
use rustc_data_structures::fx::FxHashMap;
2323
use rustc::ty::{self, Ty};
2424
use rustc::ty::util::IntTypeExt;
25+
use rustc::ty::layout::VariantIdx;
2526
use rustc::mir::*;
2627
use rustc::hir::{RangeEnd, Mutability};
2728
use syntax_pos::Span;
@@ -152,7 +153,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
152153
pub fn add_variants_to_switch<'pat>(&mut self,
153154
test_place: &Place<'tcx>,
154155
candidate: &Candidate<'pat, 'tcx>,
155-
variants: &mut BitSet<usize>)
156+
variants: &mut BitSet<VariantIdx>)
156157
-> bool
157158
{
158159
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> {
196197
let mut targets = Vec::with_capacity(used_variants + 1);
197198
let mut values = Vec::with_capacity(used_variants);
198199
let tcx = self.hir.tcx();
199-
for (idx, discr) in adt_def.discriminants(tcx).enumerate() {
200+
for (idx, discr) in adt_def.discriminants(tcx) {
200201
target_blocks.push(if variants.contains(idx) {
201202
values.push(discr.val);
202203
targets.push(self.cfg.start_new_block());
@@ -512,7 +513,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
512513
variant_index,
513514
subpatterns,
514515
candidate);
515-
resulting_candidates[variant_index].push(new_candidate);
516+
resulting_candidates[variant_index.as_usize()].push(new_candidate);
516517
true
517518
}
518519
(&TestKind::Switch { .. }, _) => false,
@@ -673,7 +674,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
673674
fn candidate_after_variant_switch<'pat>(&mut self,
674675
match_pair_index: usize,
675676
adt_def: &'tcx ty::AdtDef,
676-
variant_index: usize,
677+
variant_index: VariantIdx,
677678
subpatterns: &'pat [FieldPattern<'tcx>],
678679
candidate: &Candidate<'pat, 'tcx>)
679680
-> Candidate<'pat, 'tcx> {

src/librustc_mir/build/matches/util.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use build::matches::MatchPair;
1313
use hair::*;
1414
use rustc::mir::*;
1515
use std::u32;
16+
use std::convert::TryInto;
1617

1718
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
1819
pub fn field_match_pairs<'pat>(&mut self,

0 commit comments

Comments
 (0)