1111use graphviz:: IntoCow ;
1212use middle:: const_val:: ConstVal ;
1313use rustc_const_math:: { ConstUsize , ConstInt , ConstMathErr } ;
14+ use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
1415use hir:: def_id:: DefId ;
1516use ty:: subst:: Substs ;
1617use ty:: { self , AdtDef , ClosureSubsts , FnOutput , Region , Ty } ;
@@ -25,37 +26,61 @@ use std::ops::{Index, IndexMut};
2526use syntax:: ast:: { self , Name } ;
2627use 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 ) ]
3055pub 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 ) ]
622627pub 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.
697702pub 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
714706impl < ' 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 ) ]
814773pub 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 ) ]
10841045pub 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 }
0 commit comments