@@ -9,7 +9,7 @@ use rustc::ty::layout::{self, Size, Align, HasDataLayout, LayoutOf, TyLayout};
99use rustc:: ty:: subst:: { Subst , Substs } ;
1010use rustc:: ty:: { self , Ty , TyCtxt } ;
1111use rustc:: ty:: maps:: TyCtxtAt ;
12- use rustc_data_structures:: indexed_vec:: Idx ;
12+ use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
1313use rustc:: middle:: const_val:: FrameInfo ;
1414use syntax:: codemap:: { self , Span } ;
1515use syntax:: ast:: Mutability ;
@@ -71,12 +71,12 @@ pub struct Frame<'mir, 'tcx: 'mir> {
7171 pub return_place : Place ,
7272
7373 /// The list of locals for this stack frame, stored in order as
74- /// `[arguments..., variables..., temporaries...]`. The locals are stored as `Option<Value>`s.
74+ /// `[return_ptr, arguments..., variables..., temporaries...]`. The locals are stored as `Option<Value>`s.
7575 /// `None` represents a local that is currently dead, while a live local
7676 /// can either directly contain `PrimVal` or refer to some part of an `Allocation`.
7777 ///
7878 /// Before being initialized, arguments are `Value::ByVal(PrimVal::Undef)` and other locals are `None`.
79- pub locals : Vec < Option < Value > > ,
79+ pub locals : IndexVec < mir :: Local , Option < Value > > ,
8080
8181 ////////////////////////////////////////////////////////////////////////////////
8282 // Current position within the function
@@ -383,11 +383,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
383383 ) -> EvalResult < ' tcx > {
384384 :: log_settings:: settings ( ) . indentation += 1 ;
385385
386- // Subtract 1 because `local_decls` includes the ReturnMemoryPointer, but we don't store a local
387- // `Value` for that.
388- let num_locals = mir. local_decls . len ( ) - 1 ;
389-
390- let mut locals = vec ! [ Some ( Value :: ByVal ( PrimVal :: Undef ) ) ; num_locals] ;
386+ let mut locals = IndexVec :: from_elem ( Some ( Value :: ByVal ( PrimVal :: Undef ) ) , & mir. local_decls ) ;
391387 match self . tcx . describe_def ( instance. def_id ( ) ) {
392388 // statics and constants don't have `Storage*` statements, no need to look for them
393389 Some ( Def :: Static ( ..) ) | Some ( Def :: Const ( ..) ) | Some ( Def :: AssociatedConst ( ..) ) => { } ,
@@ -397,9 +393,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
397393 for stmt in block. statements . iter ( ) {
398394 use rustc:: mir:: StatementKind :: { StorageDead , StorageLive } ;
399395 match stmt. kind {
400- StorageLive ( local) | StorageDead ( local) => if local. index ( ) > 0 {
401- locals[ local. index ( ) - 1 ] = None ;
402- } ,
396+ StorageLive ( local) |
397+ StorageDead ( local) => locals[ local] = None ,
403398 _ => { }
404399 }
405400 }
@@ -962,8 +957,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
962957 pub fn force_allocation ( & mut self , place : Place ) -> EvalResult < ' tcx , Place > {
963958 let new_place = match place {
964959 Place :: Local { frame, local } => {
965- // -1 since we don't store the return value
966- match self . stack [ frame] . locals [ local. index ( ) - 1 ] {
960+ match self . stack [ frame] . locals [ local] {
967961 None => return err ! ( DeadLocal ) ,
968962 Some ( Value :: ByRef ( ptr, align) ) => {
969963 Place :: Ptr {
@@ -977,7 +971,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
977971 let ty = self . monomorphize ( ty, self . stack [ frame] . instance . substs ) ;
978972 let layout = self . layout_of ( ty) ?;
979973 let ptr = self . alloc_ptr ( ty) ?;
980- self . stack [ frame] . locals [ local. index ( ) - 1 ] =
974+ self . stack [ frame] . locals [ local] =
981975 Some ( Value :: ByRef ( ptr. into ( ) , layout. align ) ) ; // it stays live
982976 let place = Place :: from_ptr ( ptr, layout. align ) ;
983977 self . write_value ( ValTy { value : val, ty } , place) ?;
@@ -1691,13 +1685,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
16911685
16921686impl < ' mir , ' tcx > Frame < ' mir , ' tcx > {
16931687 pub fn get_local ( & self , local : mir:: Local ) -> EvalResult < ' tcx , Value > {
1694- // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
1695- self . locals [ local. index ( ) - 1 ] . ok_or ( EvalErrorKind :: DeadLocal . into ( ) )
1688+ self . locals [ local] . ok_or ( EvalErrorKind :: DeadLocal . into ( ) )
16961689 }
16971690
16981691 fn set_local ( & mut self , local : mir:: Local , value : Value ) -> EvalResult < ' tcx > {
1699- // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
1700- match self . locals [ local. index ( ) - 1 ] {
1692+ match self . locals [ local] {
17011693 None => err ! ( DeadLocal ) ,
17021694 Some ( ref mut local) => {
17031695 * local = value;
@@ -1709,17 +1701,17 @@ impl<'mir, 'tcx> Frame<'mir, 'tcx> {
17091701 pub fn storage_live ( & mut self , local : mir:: Local ) -> EvalResult < ' tcx , Option < Value > > {
17101702 trace ! ( "{:?} is now live" , local) ;
17111703
1712- let old = self . locals [ local. index ( ) - 1 ] ;
1713- self . locals [ local. index ( ) - 1 ] = Some ( Value :: ByVal ( PrimVal :: Undef ) ) ; // StorageLive *always* kills the value that's currently stored
1704+ let old = self . locals [ local] ;
1705+ self . locals [ local] = Some ( Value :: ByVal ( PrimVal :: Undef ) ) ; // StorageLive *always* kills the value that's currently stored
17141706 return Ok ( old) ;
17151707 }
17161708
17171709 /// Returns the old value of the local
17181710 pub fn storage_dead ( & mut self , local : mir:: Local ) -> EvalResult < ' tcx , Option < Value > > {
17191711 trace ! ( "{:?} is now dead" , local) ;
17201712
1721- let old = self . locals [ local. index ( ) - 1 ] ;
1722- self . locals [ local. index ( ) - 1 ] = None ;
1713+ let old = self . locals [ local] ;
1714+ self . locals [ local] = None ;
17231715 return Ok ( old) ;
17241716 }
17251717}
0 commit comments