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:: { IndexVec , 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 : IndexVec < BasicBlock , BasicBlockData < ' tcx > > ,
34
59
35
60
/// List of visibility (lexical) scopes; these are referenced by statements
36
61
/// and used (eventually) for debuginfo. Indexed by a `VisibilityScope`.
37
- pub visibility_scopes : Vec < VisibilityScopeData > ,
62
+ pub visibility_scopes : IndexVec < VisibilityScope , VisibilityScopeData > ,
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 : IndexVec < 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 : IndexVec < 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 : IndexVec < 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 : IndexVec < 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
@@ -231,31 +256,7 @@ pub struct UpvarDecl {
231
256
///////////////////////////////////////////////////////////////////////////
232
257
// BasicBlock
233
258
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" ) ;
259
260
260
261
///////////////////////////////////////////////////////////////////////////
261
262
// BasicBlockData and Terminator
@@ -616,19 +617,23 @@ impl<'tcx> Debug for Statement<'tcx> {
616
617
///////////////////////////////////////////////////////////////////////////
617
618
// Lvalues
618
619
620
+ newtype_index ! ( Var , "var" ) ;
621
+ newtype_index ! ( Temp , "tmp" ) ;
622
+ newtype_index ! ( Arg , "arg" ) ;
623
+
619
624
/// A path to a value; something that can be evaluated without
620
625
/// changing or disturbing program state.
621
626
#[ derive( Clone , PartialEq , RustcEncodable , RustcDecodable ) ]
622
627
pub enum Lvalue < ' tcx > {
623
628
/// local variable declared by the user
624
- Var ( u32 ) ,
629
+ Var ( Var ) ,
625
630
626
631
/// temporary introduced during lowering into MIR
627
- Temp ( u32 ) ,
632
+ Temp ( Temp ) ,
628
633
629
634
/// formal parameter of the function; note that these are NOT the
630
635
/// bindings that the user declares, which are vars
631
- Arg ( u32 ) ,
636
+ Arg ( Arg ) ,
632
637
633
638
/// static or static mut variable
634
639
Static ( DefId ) ,
@@ -696,20 +701,7 @@ pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
696
701
/// and the index is an operand.
697
702
pub type LvalueElem < ' tcx > = ProjectionElem < ' tcx , Operand < ' tcx > > ;
698
703
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" ) ;
713
705
714
706
impl < ' tcx > Lvalue < ' tcx > {
715
707
pub fn field ( self , f : Field , ty : Ty < ' tcx > ) -> Lvalue < ' tcx > {
@@ -737,12 +729,9 @@ impl<'tcx> Debug for Lvalue<'tcx> {
737
729
use self :: Lvalue :: * ;
738
730
739
731
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) ,
746
735
Static ( def_id) =>
747
736
write ! ( fmt, "{}" , ty:: tls:: with( |tcx| tcx. item_path_str( def_id) ) ) ,
748
737
ReturnPointer =>
@@ -777,38 +766,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
777
766
///////////////////////////////////////////////////////////////////////////
778
767
// Scopes
779
768
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 ) ;
812
771
813
772
#[ derive( Clone , Debug , RustcEncodable , RustcDecodable ) ]
814
773
pub struct VisibilityScopeData {
@@ -1080,6 +1039,8 @@ impl<'tcx> Debug for TypedConstVal<'tcx> {
1080
1039
}
1081
1040
}
1082
1041
1042
+ newtype_index ! ( Promoted , "promoted" ) ;
1043
+
1083
1044
#[ derive( Clone , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1084
1045
pub enum Literal < ' tcx > {
1085
1046
Item {
@@ -1091,7 +1052,7 @@ pub enum Literal<'tcx> {
1091
1052
} ,
1092
1053
Promoted {
1093
1054
// Index into the `promoted` vector of `Mir`.
1094
- index : usize
1055
+ index : Promoted
1095
1056
} ,
1096
1057
}
1097
1058
@@ -1115,7 +1076,7 @@ impl<'tcx> Debug for Literal<'tcx> {
1115
1076
fmt_const_val ( fmt, value)
1116
1077
}
1117
1078
Promoted { index } => {
1118
- write ! ( fmt, "promoted{ }" , index)
1079
+ write ! ( fmt, "{:? }" , index)
1119
1080
}
1120
1081
}
1121
1082
}
0 commit comments