@@ -9,7 +9,7 @@ use rustc::ty::layout::{self, Size, Align, HasDataLayout, LayoutOf, TyLayout};
9
9
use rustc:: ty:: subst:: { Subst , Substs } ;
10
10
use rustc:: ty:: { self , Ty , TyCtxt } ;
11
11
use rustc:: ty:: maps:: TyCtxtAt ;
12
- use rustc_data_structures:: indexed_vec:: Idx ;
12
+ use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
13
13
use rustc:: middle:: const_val:: FrameInfo ;
14
14
use syntax:: codemap:: { self , Span } ;
15
15
use syntax:: ast:: Mutability ;
@@ -71,12 +71,12 @@ pub struct Frame<'mir, 'tcx: 'mir> {
71
71
pub return_place : Place ,
72
72
73
73
/// 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.
75
75
/// `None` represents a local that is currently dead, while a live local
76
76
/// can either directly contain `PrimVal` or refer to some part of an `Allocation`.
77
77
///
78
78
/// 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 > > ,
80
80
81
81
////////////////////////////////////////////////////////////////////////////////
82
82
// Current position within the function
@@ -383,11 +383,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
383
383
) -> EvalResult < ' tcx > {
384
384
:: log_settings:: settings ( ) . indentation += 1 ;
385
385
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 ) ;
391
387
match self . tcx . describe_def ( instance. def_id ( ) ) {
392
388
// statics and constants don't have `Storage*` statements, no need to look for them
393
389
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
397
393
for stmt in block. statements . iter ( ) {
398
394
use rustc:: mir:: StatementKind :: { StorageDead , StorageLive } ;
399
395
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 ,
403
398
_ => { }
404
399
}
405
400
}
@@ -962,8 +957,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
962
957
pub fn force_allocation ( & mut self , place : Place ) -> EvalResult < ' tcx , Place > {
963
958
let new_place = match place {
964
959
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] {
967
961
None => return err ! ( DeadLocal ) ,
968
962
Some ( Value :: ByRef ( ptr, align) ) => {
969
963
Place :: Ptr {
@@ -977,7 +971,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
977
971
let ty = self . monomorphize ( ty, self . stack [ frame] . instance . substs ) ;
978
972
let layout = self . layout_of ( ty) ?;
979
973
let ptr = self . alloc_ptr ( ty) ?;
980
- self . stack [ frame] . locals [ local. index ( ) - 1 ] =
974
+ self . stack [ frame] . locals [ local] =
981
975
Some ( Value :: ByRef ( ptr. into ( ) , layout. align ) ) ; // it stays live
982
976
let place = Place :: from_ptr ( ptr, layout. align ) ;
983
977
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
1691
1685
1692
1686
impl < ' mir , ' tcx > Frame < ' mir , ' tcx > {
1693
1687
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 ( ) )
1696
1689
}
1697
1690
1698
1691
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] {
1701
1693
None => err ! ( DeadLocal ) ,
1702
1694
Some ( ref mut local) => {
1703
1695
* local = value;
@@ -1709,17 +1701,17 @@ impl<'mir, 'tcx> Frame<'mir, 'tcx> {
1709
1701
pub fn storage_live ( & mut self , local : mir:: Local ) -> EvalResult < ' tcx , Option < Value > > {
1710
1702
trace ! ( "{:?} is now live" , local) ;
1711
1703
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
1714
1706
return Ok ( old) ;
1715
1707
}
1716
1708
1717
1709
/// Returns the old value of the local
1718
1710
pub fn storage_dead ( & mut self , local : mir:: Local ) -> EvalResult < ' tcx , Option < Value > > {
1719
1711
trace ! ( "{:?} is now dead" , local) ;
1720
1712
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 ;
1723
1715
return Ok ( old) ;
1724
1716
}
1725
1717
}
0 commit comments