Skip to content

Commit a47f179

Browse files
committed
introduce the type-safe IdxVec and use it instead of loose indexes
1 parent b1db8a4 commit a47f179

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+596
-434
lines changed

src/librustc/mir/repr.rs

+51-87
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use graphviz::IntoCow;
1212
use middle::const_val::ConstVal;
1313
use rustc_const_math::{ConstUsize, ConstInt, ConstMathErr};
14+
use rustc_data_structures::indexed_vec::{IdxVec, Idx};
1415
use hir::def_id::DefId;
1516
use ty::subst::Substs;
1617
use ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty};
@@ -25,37 +26,61 @@ use std::ops::{Index, IndexMut};
2526
use syntax::ast::{self, Name};
2627
use syntax::codemap::Span;
2728

29+
macro_rules! newtype_index {
30+
($name:ident, $debug_name:expr) => (
31+
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
32+
RustcEncodable, RustcDecodable)]
33+
pub struct $name(u32);
34+
35+
impl Idx for $name {
36+
fn new(value: usize) -> Self {
37+
assert!(value < (u32::MAX) as usize);
38+
$name(value as u32)
39+
}
40+
fn index(self) -> usize {
41+
self.0 as usize
42+
}
43+
}
44+
45+
impl Debug for $name {
46+
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
47+
write!(fmt, "{}{}", $debug_name, self.0)
48+
}
49+
}
50+
)
51+
}
52+
2853
/// Lowered representation of a single function.
2954
#[derive(Clone, RustcEncodable, RustcDecodable)]
3055
pub struct Mir<'tcx> {
3156
/// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
3257
/// that indexes into this vector.
33-
pub basic_blocks: Vec<BasicBlockData<'tcx>>,
58+
pub basic_blocks: IdxVec<BasicBlock, BasicBlockData<'tcx>>,
3459

3560
/// List of lexical scopes; these are referenced by statements and
3661
/// used (eventually) for debuginfo. Indexed by a `ScopeId`.
37-
pub scopes: Vec<ScopeData>,
62+
pub scopes: IdxVec<ScopeId, ScopeData>,
3863

3964
/// Rvalues promoted from this function, such as borrows of constants.
4065
/// Each of them is the Mir of a constant with the fn's type parameters
4166
/// in scope, but no vars or args and a separate set of temps.
42-
pub promoted: Vec<Mir<'tcx>>,
67+
pub promoted: IdxVec<Promoted, Mir<'tcx>>,
4368

4469
/// Return type of the function.
4570
pub return_ty: FnOutput<'tcx>,
4671

4772
/// Variables: these are stack slots corresponding to user variables. They may be
4873
/// assigned many times.
49-
pub var_decls: Vec<VarDecl<'tcx>>,
74+
pub var_decls: IdxVec<Var, VarDecl<'tcx>>,
5075

5176
/// Args: these are stack slots corresponding to the input arguments.
52-
pub arg_decls: Vec<ArgDecl<'tcx>>,
77+
pub arg_decls: IdxVec<Arg, ArgDecl<'tcx>>,
5378

5479
/// Temp declarations: stack slots that for temporaries created by
5580
/// the compiler. These are assigned once, but they are not SSA
5681
/// values in that it is possible to borrow them and mutate them
5782
/// through the resulting reference.
58-
pub temp_decls: Vec<TempDecl<'tcx>>,
83+
pub temp_decls: IdxVec<Temp, TempDecl<'tcx>>,
5984

6085
/// Names and capture modes of all the closure upvars, assuming
6186
/// the first argument is either the closure or a reference to it.
@@ -76,11 +101,11 @@ impl<'tcx> Mir<'tcx> {
76101
}
77102

78103
pub fn basic_block_data(&self, bb: BasicBlock) -> &BasicBlockData<'tcx> {
79-
&self.basic_blocks[bb.index()]
104+
&self.basic_blocks[bb]
80105
}
81106

82107
pub fn basic_block_data_mut(&mut self, bb: BasicBlock) -> &mut BasicBlockData<'tcx> {
83-
&mut self.basic_blocks[bb.index()]
108+
&mut self.basic_blocks[bb]
84109
}
85110
}
86111

@@ -222,31 +247,7 @@ pub struct UpvarDecl {
222247
///////////////////////////////////////////////////////////////////////////
223248
// BasicBlock
224249

225-
/// The index of a particular basic block. The index is into the `basic_blocks`
226-
/// list of the `Mir`.
227-
///
228-
/// (We use a `u32` internally just to save memory.)
229-
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
230-
RustcEncodable, RustcDecodable)]
231-
pub struct BasicBlock(u32);
232-
233-
impl BasicBlock {
234-
pub fn new(index: usize) -> BasicBlock {
235-
assert!(index < (u32::MAX as usize));
236-
BasicBlock(index as u32)
237-
}
238-
239-
/// Extract the index.
240-
pub fn index(self) -> usize {
241-
self.0 as usize
242-
}
243-
}
244-
245-
impl Debug for BasicBlock {
246-
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
247-
write!(fmt, "bb{}", self.0)
248-
}
249-
}
250+
newtype_index!(BasicBlock, "bb");
250251

251252
///////////////////////////////////////////////////////////////////////////
252253
// BasicBlockData and Terminator
@@ -609,19 +610,23 @@ impl<'tcx> Debug for Statement<'tcx> {
609610
///////////////////////////////////////////////////////////////////////////
610611
// Lvalues
611612

613+
newtype_index!(Var, "var");
614+
newtype_index!(Temp, "tmp");
615+
newtype_index!(Arg, "arg");
616+
612617
/// A path to a value; something that can be evaluated without
613618
/// changing or disturbing program state.
614619
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
615620
pub enum Lvalue<'tcx> {
616621
/// local variable declared by the user
617-
Var(u32),
622+
Var(Var),
618623

619624
/// temporary introduced during lowering into MIR
620-
Temp(u32),
625+
Temp(Temp),
621626

622627
/// formal parameter of the function; note that these are NOT the
623628
/// bindings that the user declares, which are vars
624-
Arg(u32),
629+
Arg(Arg),
625630

626631
/// static or static mut variable
627632
Static(DefId),
@@ -681,20 +686,7 @@ pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
681686
/// and the index is an operand.
682687
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>>;
683688

684-
/// Index into the list of fields found in a `VariantDef`
685-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
686-
pub struct Field(u32);
687-
688-
impl Field {
689-
pub fn new(value: usize) -> Field {
690-
assert!(value < (u32::MAX) as usize);
691-
Field(value as u32)
692-
}
693-
694-
pub fn index(self) -> usize {
695-
self.0 as usize
696-
}
697-
}
689+
newtype_index!(Field, "field");
698690

699691
impl<'tcx> Lvalue<'tcx> {
700692
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> {
@@ -722,12 +714,9 @@ impl<'tcx> Debug for Lvalue<'tcx> {
722714
use self::Lvalue::*;
723715

724716
match *self {
725-
Var(id) =>
726-
write!(fmt, "var{:?}", id),
727-
Arg(id) =>
728-
write!(fmt, "arg{:?}", id),
729-
Temp(id) =>
730-
write!(fmt, "tmp{:?}", id),
717+
Var(id) => write!(fmt, "{:?}", id),
718+
Arg(id) => write!(fmt, "{:?}", id),
719+
Temp(id) => write!(fmt, "{:?}", id),
731720
Static(def_id) =>
732721
write!(fmt, "{}", ty::tls::with(|tcx| tcx.item_path_str(def_id))),
733722
ReturnPointer =>
@@ -754,35 +743,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
754743
///////////////////////////////////////////////////////////////////////////
755744
// Scopes
756745

757-
impl Index<ScopeId> for Vec<ScopeData> {
758-
type Output = ScopeData;
759-
760-
#[inline]
761-
fn index(&self, index: ScopeId) -> &ScopeData {
762-
&self[index.index()]
763-
}
764-
}
765-
766-
impl IndexMut<ScopeId> for Vec<ScopeData> {
767-
#[inline]
768-
fn index_mut(&mut self, index: ScopeId) -> &mut ScopeData {
769-
&mut self[index.index()]
770-
}
771-
}
772-
773-
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
774-
pub struct ScopeId(u32);
775-
776-
impl ScopeId {
777-
pub fn new(index: usize) -> ScopeId {
778-
assert!(index < (u32::MAX as usize));
779-
ScopeId(index as u32)
780-
}
781-
782-
pub fn index(self) -> usize {
783-
self.0 as usize
784-
}
785-
}
746+
newtype_index!(ScopeId, "scope");
747+
pub const TOPMOST_SCOPE : ScopeId = ScopeId(0);
786748

787749
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
788750
pub struct ScopeData {
@@ -1067,6 +1029,8 @@ impl<'tcx> Debug for TypedConstVal<'tcx> {
10671029
}
10681030
}
10691031

1032+
newtype_index!(Promoted, "promoted");
1033+
10701034
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
10711035
pub enum Literal<'tcx> {
10721036
Item {
@@ -1078,7 +1042,7 @@ pub enum Literal<'tcx> {
10781042
},
10791043
Promoted {
10801044
// Index into the `promoted` vector of `Mir`.
1081-
index: usize
1045+
index: Promoted
10821046
},
10831047
}
10841048

@@ -1102,7 +1066,7 @@ impl<'tcx> Debug for Literal<'tcx> {
11021066
fmt_const_val(fmt, value)
11031067
}
11041068
Promoted { index } => {
1105-
write!(fmt, "promoted{}", index)
1069+
write!(fmt, "{:?}", index)
11061070
}
11071071
}
11081072
}

src/librustc/mir/tcx.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
140140
{
141141
match *lvalue {
142142
Lvalue::Var(index) =>
143-
LvalueTy::Ty { ty: self.var_decls[index as usize].ty },
143+
LvalueTy::Ty { ty: self.var_decls[index].ty },
144144
Lvalue::Temp(index) =>
145-
LvalueTy::Ty { ty: self.temp_decls[index as usize].ty },
145+
LvalueTy::Ty { ty: self.temp_decls[index].ty },
146146
Lvalue::Arg(index) =>
147-
LvalueTy::Ty { ty: self.arg_decls[index as usize].ty },
147+
LvalueTy::Ty { ty: self.arg_decls[index].ty },
148148
Lvalue::Static(def_id) =>
149149
LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
150150
Lvalue::ReturnPointer =>

src/librustc/mir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use ty::{ClosureSubsts, FnOutput, Region, Ty};
1515
use mir::repr::*;
1616
use rustc_const_math::ConstUsize;
1717
use rustc_data_structures::tuple_slice::TupleSlice;
18+
use rustc_data_structures::indexed_vec::Idx;
1819
use syntax::codemap::Span;
1920

2021
// # The MIR Visitor

src/librustc_borrowck/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ log = { path = "../liblog" }
1414
syntax = { path = "../libsyntax" }
1515
graphviz = { path = "../libgraphviz" }
1616
rustc = { path = "../librustc" }
17+
rustc_data_structures = { path = "../librustc_data_structures" }
1718
rustc_mir = { path = "../librustc_mir" }

src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
use syntax::ast::NodeId;
1414
use rustc::mir::repr::{BasicBlock, Mir};
15+
use rustc_data_structures::indexed_vec::Idx;
1516

1617
use dot;
1718
use dot::IntoCow;
@@ -27,7 +28,7 @@ use std::path::Path;
2728
use super::super::MoveDataParamEnv;
2829
use super::super::MirBorrowckCtxtPreDataflow;
2930
use bitslice::bits_to_string;
30-
use indexed_set::{Idx, IdxSet};
31+
use indexed_set::{IdxSet};
3132
use super::{BitDenotation, DataflowState};
3233

3334
impl<O: BitDenotation> DataflowState<O> {

src/librustc_borrowck/borrowck/mir/dataflow/impls.rs

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

1111
use rustc::ty::TyCtxt;
1212
use rustc::mir::repr::{self, Mir};
13+
use rustc_data_structures::indexed_vec::Idx;
1314

1415
use super::super::gather_moves::{Location};
1516
use super::super::gather_moves::{MoveOutIndex, MovePathIndex};
@@ -23,7 +24,7 @@ use super::{BitDenotation, BlockSets, DataflowOperator};
2324

2425
use bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
2526
use bitslice::{BitwiseOperator};
26-
use indexed_set::{Idx, IdxSet};
27+
use indexed_set::{IdxSet};
2728

2829
// Dataflow analyses are built upon some interpretation of the
2930
// bitvectors attached to each basic block, represented via a
@@ -451,7 +452,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
451452
move_data,
452453
move_path_index,
453454
|mpi| for moi in &path_map[mpi] {
454-
assert!(moi.idx() < bits_per_block);
455+
assert!(moi.index() < bits_per_block);
455456
sets.kill_set.add(&moi);
456457
});
457458
}
@@ -472,7 +473,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
472473
term, loc, &loc_map[loc]);
473474
let bits_per_block = self.bits_per_block(ctxt);
474475
for move_index in &loc_map[loc] {
475-
assert!(move_index.idx() < bits_per_block);
476+
assert!(move_index.index() < bits_per_block);
476477
zero_to_one(sets.gen_set.words_mut(), *move_index);
477478
}
478479
}
@@ -493,14 +494,14 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
493494
move_data,
494495
move_path_index,
495496
|mpi| for moi in &path_map[mpi] {
496-
assert!(moi.idx() < bits_per_block);
497+
assert!(moi.index() < bits_per_block);
497498
in_out.remove(&moi);
498499
});
499500
}
500501
}
501502

502503
fn zero_to_one(bitvec: &mut [usize], move_index: MoveOutIndex) {
503-
let retval = bitvec.set_bit(move_index.idx());
504+
let retval = bitvec.set_bit(move_index.index());
504505
assert!(retval);
505506
}
506507

src/librustc_borrowck/borrowck/mir/dataflow/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use rustc_data_structures::indexed_vec::Idx;
12+
1113
use rustc::ty::TyCtxt;
1214
use rustc::mir::repr::{self, Mir};
1315

@@ -21,7 +23,7 @@ use super::MirBorrowckCtxtPreDataflow;
2123
use super::MoveDataParamEnv;
2224

2325
use bitslice::{bitwise, BitwiseOperator};
24-
use indexed_set::{Idx, IdxSet, IdxSetBuf};
26+
use indexed_set::{IdxSet, IdxSetBuf};
2527

2628
pub use self::sanity_check::sanity_check_via_rustc_peek;
2729
pub use self::impls::{MaybeInitializedLvals, MaybeUninitializedLvals};

src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use syntax::codemap::Span;
1414

1515
use rustc::ty::{self, TyCtxt};
1616
use rustc::mir::repr::{self, Mir};
17+
use rustc_data_structures::indexed_vec::Idx;
1718

1819
use super::super::gather_moves::{MovePathIndex};
1920
use super::super::MoveDataParamEnv;

src/librustc_borrowck/borrowck/mir/elaborate_drops.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::mir::transform::{Pass, MirPass, MirSource};
2222
use rustc::middle::const_val::ConstVal;
2323
use rustc::middle::lang_items;
2424
use rustc::util::nodemap::FnvHashMap;
25+
use rustc_data_structures::indexed_vec::Idx;
2526
use rustc_mir::pretty;
2627
use syntax::codemap::Span;
2728

@@ -118,7 +119,7 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
118119
env: &'a MoveDataParamEnv<'tcx>,
119120
flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>,
120121
flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>>,
121-
drop_flags: FnvHashMap<MovePathIndex, u32>,
122+
drop_flags: FnvHashMap<MovePathIndex, Temp>,
122123
patch: MirPatch<'tcx>,
123124
}
124125

0 commit comments

Comments
 (0)