Skip to content

Commit bc1eb67

Browse files
arielb1Ariel Ben-Yehuda
authored and
Ariel Ben-Yehuda
committed
introduce the type-safe IdxVec and use it instead of loose indexes
1 parent e9003c5 commit bc1eb67

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

+594
-437
lines changed

src/librustc/mir/repr.rs

+51-90
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::{IndexVec, 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: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
3459

3560
/// List of visibility (lexical) scopes; these are referenced by statements
3661
/// and used (eventually) for debuginfo. Indexed by a `VisibilityScope`.
37-
pub visibility_scopes: Vec<VisibilityScopeData>,
62+
pub visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
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: IndexVec<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: IndexVec<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: IndexVec<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: IndexVec<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

@@ -231,31 +256,7 @@ pub struct UpvarDecl {
231256
///////////////////////////////////////////////////////////////////////////
232257
// BasicBlock
233258

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

260261
///////////////////////////////////////////////////////////////////////////
261262
// BasicBlockData and Terminator
@@ -616,19 +617,23 @@ impl<'tcx> Debug for Statement<'tcx> {
616617
///////////////////////////////////////////////////////////////////////////
617618
// Lvalues
618619

620+
newtype_index!(Var, "var");
621+
newtype_index!(Temp, "tmp");
622+
newtype_index!(Arg, "arg");
623+
619624
/// A path to a value; something that can be evaluated without
620625
/// changing or disturbing program state.
621626
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
622627
pub enum Lvalue<'tcx> {
623628
/// local variable declared by the user
624-
Var(u32),
629+
Var(Var),
625630

626631
/// temporary introduced during lowering into MIR
627-
Temp(u32),
632+
Temp(Temp),
628633

629634
/// formal parameter of the function; note that these are NOT the
630635
/// bindings that the user declares, which are vars
631-
Arg(u32),
636+
Arg(Arg),
632637

633638
/// static or static mut variable
634639
Static(DefId),
@@ -696,20 +701,7 @@ pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
696701
/// and the index is an operand.
697702
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>>;
698703

699-
/// Index into the list of fields found in a `VariantDef`
700-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
701-
pub struct Field(u32);
702-
703-
impl Field {
704-
pub fn new(value: usize) -> Field {
705-
assert!(value < (u32::MAX) as usize);
706-
Field(value as u32)
707-
}
708-
709-
pub fn index(self) -> usize {
710-
self.0 as usize
711-
}
712-
}
704+
newtype_index!(Field, "field");
713705

714706
impl<'tcx> Lvalue<'tcx> {
715707
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> {
@@ -737,12 +729,9 @@ impl<'tcx> Debug for Lvalue<'tcx> {
737729
use self::Lvalue::*;
738730

739731
match *self {
740-
Var(id) =>
741-
write!(fmt, "var{:?}", id),
742-
Arg(id) =>
743-
write!(fmt, "arg{:?}", id),
744-
Temp(id) =>
745-
write!(fmt, "tmp{:?}", id),
732+
Var(id) => write!(fmt, "{:?}", id),
733+
Arg(id) => write!(fmt, "{:?}", id),
734+
Temp(id) => write!(fmt, "{:?}", id),
746735
Static(def_id) =>
747736
write!(fmt, "{}", ty::tls::with(|tcx| tcx.item_path_str(def_id))),
748737
ReturnPointer =>
@@ -777,38 +766,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
777766
///////////////////////////////////////////////////////////////////////////
778767
// Scopes
779768

780-
impl Index<VisibilityScope> for Vec<VisibilityScopeData> {
781-
type Output = VisibilityScopeData;
782-
783-
#[inline]
784-
fn index(&self, index: VisibilityScope) -> &VisibilityScopeData {
785-
&self[index.index()]
786-
}
787-
}
788-
789-
impl IndexMut<VisibilityScope> for Vec<VisibilityScopeData> {
790-
#[inline]
791-
fn index_mut(&mut self, index: VisibilityScope) -> &mut VisibilityScopeData {
792-
&mut self[index.index()]
793-
}
794-
}
795-
796-
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
797-
pub struct VisibilityScope(u32);
798-
799-
/// The visibility scope all arguments go into.
800-
pub const ARGUMENT_VISIBILITY_SCOPE: VisibilityScope = VisibilityScope(0);
801-
802-
impl VisibilityScope {
803-
pub fn new(index: usize) -> VisibilityScope {
804-
assert!(index < (u32::MAX as usize));
805-
VisibilityScope(index as u32)
806-
}
807-
808-
pub fn index(self) -> usize {
809-
self.0 as usize
810-
}
811-
}
769+
newtype_index!(VisibilityScope, "scope");
770+
pub const ARGUMENT_VISIBILITY_SCOPE : VisibilityScope = VisibilityScope(0);
812771

813772
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
814773
pub struct VisibilityScopeData {
@@ -1080,6 +1039,8 @@ impl<'tcx> Debug for TypedConstVal<'tcx> {
10801039
}
10811040
}
10821041

1042+
newtype_index!(Promoted, "promoted");
1043+
10831044
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
10841045
pub enum Literal<'tcx> {
10851046
Item {
@@ -1091,7 +1052,7 @@ pub enum Literal<'tcx> {
10911052
},
10921053
Promoted {
10931054
// Index into the `promoted` vector of `Mir`.
1094-
index: usize
1055+
index: Promoted
10951056
},
10961057
}
10971058

@@ -1115,7 +1076,7 @@ impl<'tcx> Debug for Literal<'tcx> {
11151076
fmt_const_val(fmt, value)
11161077
}
11171078
Promoted { index } => {
1118-
write!(fmt, "promoted{}", index)
1079+
write!(fmt, "{:?}", index)
11191080
}
11201081
}
11211082
}

src/librustc/mir/tcx.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,11 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
154154
{
155155
match *lvalue {
156156
Lvalue::Var(index) =>
157-
LvalueTy::Ty { ty: self.var_decls[index as usize].ty },
157+
LvalueTy::Ty { ty: self.var_decls[index].ty },
158158
Lvalue::Temp(index) =>
159-
LvalueTy::Ty { ty: self.temp_decls[index as usize].ty },
159+
LvalueTy::Ty { ty: self.temp_decls[index].ty },
160160
Lvalue::Arg(index) =>
161-
LvalueTy::Ty { ty: self.arg_decls[index as usize].ty },
161+
LvalueTy::Ty { ty: self.arg_decls[index].ty },
162162
Lvalue::Static(def_id) =>
163163
LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
164164
Lvalue::ReturnPointer =>

src/librustc/mir/traversal.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::vec;
1212

1313
use rustc_data_structures::bitvec::BitVector;
14+
use rustc_data_structures::indexed_vec::Idx;
1415

1516
use super::repr::*;
1617

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;

0 commit comments

Comments
 (0)