11
11
use graphviz:: IntoCow ;
12
12
use middle:: const_val:: ConstVal ;
13
13
use rustc_const_math:: { ConstUsize , ConstInt , ConstMathErr } ;
14
+ use rustc_data_structures:: indexed_vec:: { IdxVec , Idx } ;
14
15
use hir:: def_id:: DefId ;
15
16
use ty:: subst:: Substs ;
16
17
use ty:: { self , AdtDef , ClosureSubsts , FnOutput , Region , Ty } ;
@@ -25,37 +26,61 @@ use std::ops::{Index, IndexMut};
25
26
use syntax:: ast:: { self , Name } ;
26
27
use syntax:: codemap:: Span ;
27
28
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
+
28
53
/// Lowered representation of a single function.
29
54
#[ derive( Clone , RustcEncodable , RustcDecodable ) ]
30
55
pub struct Mir < ' tcx > {
31
56
/// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
32
57
/// that indexes into this vector.
33
- pub basic_blocks : Vec < BasicBlockData < ' tcx > > ,
58
+ pub basic_blocks : IdxVec < BasicBlock , BasicBlockData < ' tcx > > ,
34
59
35
60
/// List of lexical scopes; these are referenced by statements and
36
61
/// used (eventually) for debuginfo. Indexed by a `ScopeId`.
37
- pub scopes : Vec < ScopeData > ,
62
+ pub scopes : IdxVec < ScopeId , ScopeData > ,
38
63
39
64
/// Rvalues promoted from this function, such as borrows of constants.
40
65
/// Each of them is the Mir of a constant with the fn's type parameters
41
66
/// 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 > > ,
43
68
44
69
/// Return type of the function.
45
70
pub return_ty : FnOutput < ' tcx > ,
46
71
47
72
/// Variables: these are stack slots corresponding to user variables. They may be
48
73
/// assigned many times.
49
- pub var_decls : Vec < VarDecl < ' tcx > > ,
74
+ pub var_decls : IdxVec < Var , VarDecl < ' tcx > > ,
50
75
51
76
/// 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 > > ,
53
78
54
79
/// Temp declarations: stack slots that for temporaries created by
55
80
/// the compiler. These are assigned once, but they are not SSA
56
81
/// values in that it is possible to borrow them and mutate them
57
82
/// through the resulting reference.
58
- pub temp_decls : Vec < TempDecl < ' tcx > > ,
83
+ pub temp_decls : IdxVec < Temp , TempDecl < ' tcx > > ,
59
84
60
85
/// Names and capture modes of all the closure upvars, assuming
61
86
/// the first argument is either the closure or a reference to it.
@@ -76,11 +101,11 @@ impl<'tcx> Mir<'tcx> {
76
101
}
77
102
78
103
pub fn basic_block_data ( & self , bb : BasicBlock ) -> & BasicBlockData < ' tcx > {
79
- & self . basic_blocks [ bb. index ( ) ]
104
+ & self . basic_blocks [ bb]
80
105
}
81
106
82
107
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]
84
109
}
85
110
}
86
111
@@ -222,31 +247,7 @@ pub struct UpvarDecl {
222
247
///////////////////////////////////////////////////////////////////////////
223
248
// BasicBlock
224
249
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" ) ;
250
251
251
252
///////////////////////////////////////////////////////////////////////////
252
253
// BasicBlockData and Terminator
@@ -609,19 +610,23 @@ impl<'tcx> Debug for Statement<'tcx> {
609
610
///////////////////////////////////////////////////////////////////////////
610
611
// Lvalues
611
612
613
+ newtype_index ! ( Var , "var" ) ;
614
+ newtype_index ! ( Temp , "tmp" ) ;
615
+ newtype_index ! ( Arg , "arg" ) ;
616
+
612
617
/// A path to a value; something that can be evaluated without
613
618
/// changing or disturbing program state.
614
619
#[ derive( Clone , PartialEq , RustcEncodable , RustcDecodable ) ]
615
620
pub enum Lvalue < ' tcx > {
616
621
/// local variable declared by the user
617
- Var ( u32 ) ,
622
+ Var ( Var ) ,
618
623
619
624
/// temporary introduced during lowering into MIR
620
- Temp ( u32 ) ,
625
+ Temp ( Temp ) ,
621
626
622
627
/// formal parameter of the function; note that these are NOT the
623
628
/// bindings that the user declares, which are vars
624
- Arg ( u32 ) ,
629
+ Arg ( Arg ) ,
625
630
626
631
/// static or static mut variable
627
632
Static ( DefId ) ,
@@ -681,20 +686,7 @@ pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
681
686
/// and the index is an operand.
682
687
pub type LvalueElem < ' tcx > = ProjectionElem < ' tcx , Operand < ' tcx > > ;
683
688
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" ) ;
698
690
699
691
impl < ' tcx > Lvalue < ' tcx > {
700
692
pub fn field ( self , f : Field , ty : Ty < ' tcx > ) -> Lvalue < ' tcx > {
@@ -722,12 +714,9 @@ impl<'tcx> Debug for Lvalue<'tcx> {
722
714
use self :: Lvalue :: * ;
723
715
724
716
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) ,
731
720
Static ( def_id) =>
732
721
write ! ( fmt, "{}" , ty:: tls:: with( |tcx| tcx. item_path_str( def_id) ) ) ,
733
722
ReturnPointer =>
@@ -754,35 +743,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
754
743
///////////////////////////////////////////////////////////////////////////
755
744
// Scopes
756
745
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 ) ;
786
748
787
749
#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
788
750
pub struct ScopeData {
@@ -1067,6 +1029,8 @@ impl<'tcx> Debug for TypedConstVal<'tcx> {
1067
1029
}
1068
1030
}
1069
1031
1032
+ newtype_index ! ( Promoted , "promoted" ) ;
1033
+
1070
1034
#[ derive( Clone , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1071
1035
pub enum Literal < ' tcx > {
1072
1036
Item {
@@ -1078,7 +1042,7 @@ pub enum Literal<'tcx> {
1078
1042
} ,
1079
1043
Promoted {
1080
1044
// Index into the `promoted` vector of `Mir`.
1081
- index : usize
1045
+ index : Promoted
1082
1046
} ,
1083
1047
}
1084
1048
@@ -1102,7 +1066,7 @@ impl<'tcx> Debug for Literal<'tcx> {
1102
1066
fmt_const_val ( fmt, value)
1103
1067
}
1104
1068
Promoted { index } => {
1105
- write ! ( fmt, "promoted{ }" , index)
1069
+ write ! ( fmt, "{:? }" , index)
1106
1070
}
1107
1071
}
1108
1072
}
0 commit comments