@@ -1003,12 +1003,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10031003        lvalue :  Lvalue < ' tcx > , 
10041004    )  -> EvalResult < ' tcx ,  Lvalue < ' tcx > >  { 
10051005        let  new_lvalue = match  lvalue { 
1006-             Lvalue :: Local  {  frame,  local,  field  }  => { 
1006+             Lvalue :: Local  {  frame,  local }  => { 
10071007                // -1 since we don't store the return value 
10081008                match  self . stack [ frame] . locals [ local. index ( )  - 1 ]  { 
10091009                    None  => return  Err ( EvalError :: DeadLocal ) , 
10101010                    Some ( Value :: ByRef ( ptr) )  => { 
1011-                         assert ! ( field. is_none( ) ) ; 
10121011                        Lvalue :: from_ptr ( ptr) 
10131012                    } , 
10141013                    Some ( val)  => { 
@@ -1018,12 +1017,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10181017                        let  ptr = self . alloc_ptr_with_substs ( ty,  substs) ?; 
10191018                        self . stack [ frame] . locals [ local. index ( )  - 1 ]  = Some ( Value :: ByRef ( ptr) ) ;  // it stays live 
10201019                        self . write_value_to_ptr ( val,  PrimVal :: Ptr ( ptr) ,  ty) ?; 
1021-                         let  lval = Lvalue :: from_ptr ( ptr) ; 
1022-                         if  let  Some ( ( field,  field_ty) )  = field { 
1023-                             self . lvalue_field ( lval,  field,  ty,  field_ty) ?
1024-                         }  else  { 
1025-                             lval
1026-                         } 
1020+                         Lvalue :: from_ptr ( ptr) 
10271021                    } 
10281022                } 
10291023            } 
@@ -1110,11 +1104,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
11101104                self . write_value_to_ptr ( src_val,  ptr,  dest_ty) 
11111105            } 
11121106
1113-             Lvalue :: Local  {  frame,  local,  field  }  => { 
1114-                 let  dest = self . stack [ frame] . get_local ( local,  field . map ( | ( i ,  _ ) | i ) ) ?; 
1107+             Lvalue :: Local  {  frame,  local }  => { 
1108+                 let  dest = self . stack [ frame] . get_local ( local) ?; 
11151109                self . write_value_possibly_by_val ( 
11161110                    src_val, 
1117-                     |this,  val| this. stack [ frame] . set_local ( local,  field . map ( | ( i ,  _ ) | i ) ,   val) , 
1111+                     |this,  val| this. stack [ frame] . set_local ( local,  val) , 
11181112                    dest, 
11191113                    dest_ty, 
11201114                ) 
@@ -1353,7 +1347,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
13531347                    I128  => 16 , 
13541348                    Is  => self . memory . pointer_size ( ) , 
13551349                } ; 
1356-                 PrimVal :: from_i128 ( self . memory . read_int ( ptr,  size) ?) 
1350+                 // if we cast a ptr to an isize, reading it back into a primval shouldn't panic 
1351+                 // Due to read_ptr ignoring the sign, we need to jump around some hoops 
1352+                 match  self . memory . read_int ( ptr,  size)  { 
1353+                     Err ( EvalError :: ReadPointerAsBytes )  if  size == self . memory . pointer_size ( )  => self . memory . read_ptr ( ptr) ?, 
1354+                     other => PrimVal :: from_i128 ( other?) , 
1355+                 } 
13571356            } 
13581357
13591358            ty:: TyUint ( uint_ty)  => { 
@@ -1366,7 +1365,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
13661365                    U128  => 16 , 
13671366                    Us  => self . memory . pointer_size ( ) , 
13681367                } ; 
1369-                 PrimVal :: from_u128 ( self . memory . read_uint ( ptr,  size) ?) 
1368+                 if  size == self . memory . pointer_size ( )  { 
1369+                     // if we cast a ptr to an usize, reading it back into a primval shouldn't panic 
1370+                     self . memory . read_ptr ( ptr) ?
1371+                 }  else  { 
1372+                     PrimVal :: from_u128 ( self . memory . read_uint ( ptr,  size) ?) 
1373+                 } 
13701374            } 
13711375
13721376            ty:: TyFloat ( FloatTy :: F32 )  => PrimVal :: from_f32 ( self . memory . read_f32 ( ptr) ?) , 
@@ -1518,19 +1522,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
15181522
15191523    pub ( super )  fn  dump_local ( & self ,  lvalue :  Lvalue < ' tcx > )  { 
15201524        // Debug output 
1521-         if  let  Lvalue :: Local  {  frame,  local,  field  }  = lvalue { 
1525+         if  let  Lvalue :: Local  {  frame,  local }  = lvalue { 
15221526            let  mut  allocs = Vec :: new ( ) ; 
15231527            let  mut  msg = format ! ( "{:?}" ,  local) ; 
1524-             if  let  Some ( ( field,  _) )  = field { 
1525-                 write ! ( msg,  ".{}" ,  field) . unwrap ( ) ; 
1526-             } 
15271528            let  last_frame = self . stack . len ( )  - 1 ; 
15281529            if  frame != last_frame { 
15291530                write ! ( msg,  " ({} frames up)" ,  last_frame - frame) . unwrap ( ) ; 
15301531            } 
15311532            write ! ( msg,  ":" ) . unwrap ( ) ; 
15321533
1533-             match  self . stack [ frame] . get_local ( local,  field . map ( | ( i ,  _ ) | i ) )  { 
1534+             match  self . stack [ frame] . get_local ( local)  { 
15341535                Err ( EvalError :: DeadLocal )  => { 
15351536                    write ! ( msg,  " is dead" ) . unwrap ( ) ; 
15361537                } 
@@ -1575,14 +1576,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
15751576        & mut  self , 
15761577        frame :  usize , 
15771578        local :  mir:: Local , 
1578-         field :  Option < usize > , 
15791579        f :  F , 
15801580    )  -> EvalResult < ' tcx > 
15811581        where  F :  FnOnce ( & mut  Self ,  Value )  -> EvalResult < ' tcx ,  Value > , 
15821582    { 
1583-         let  val = self . stack [ frame] . get_local ( local,  field ) ?; 
1583+         let  val = self . stack [ frame] . get_local ( local) ?; 
15841584        let  new_val = f ( self ,  val) ?; 
1585-         self . stack [ frame] . set_local ( local,  field ,   new_val) ?; 
1585+         self . stack [ frame] . set_local ( local,  new_val) ?; 
15861586        // FIXME(solson): Run this when setting to Undef? (See previous version of this code.) 
15871587        // if let Value::ByRef(ptr) = self.stack[frame].get_local(local) { 
15881588        //     self.memory.deallocate(ptr)?; 
@@ -1598,59 +1598,20 @@ impl<'tcx> Frame<'tcx> {
15981598            _ => false , 
15991599        } 
16001600    } 
1601-     pub  fn  get_local ( & self ,  local :  mir:: Local ,   field :   Option < usize > )  -> EvalResult < ' tcx ,  Value >  { 
1601+     pub  fn  get_local ( & self ,  local :  mir:: Local )  -> EvalResult < ' tcx ,  Value >  { 
16021602        // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0. 
1603-         if  let  Some ( field)  = field { 
1604-             Ok ( match  self . locals [ local. index ( )  - 1 ]  { 
1605-                 None  => return  Err ( EvalError :: DeadLocal ) , 
1606-                 Some ( Value :: ByRef ( _) )  => bug ! ( "can't have lvalue fields for ByRef" ) , 
1607-                 Some ( val @ Value :: ByVal ( _) )  => { 
1608-                     assert_eq ! ( field,  0 ) ; 
1609-                     val
1610-                 } , 
1611-                 Some ( Value :: ByValPair ( a,  b) )  => { 
1612-                     match  field { 
1613-                         0  => Value :: ByVal ( a) , 
1614-                         1  => Value :: ByVal ( b) , 
1615-                         _ => bug ! ( "ByValPair has only two fields, tried to access {}" ,  field) , 
1616-                     } 
1617-                 } , 
1618-             } ) 
1619-         }  else  { 
1620-             self . locals [ local. index ( )  - 1 ] . ok_or ( EvalError :: DeadLocal ) 
1621-         } 
1603+         self . locals [ local. index ( )  - 1 ] . ok_or ( EvalError :: DeadLocal ) 
16221604    } 
16231605
1624-     fn  set_local ( & mut  self ,  local :  mir:: Local ,  field :   Option < usize > ,   value :  Value )  -> EvalResult < ' tcx >  { 
1606+     fn  set_local ( & mut  self ,  local :  mir:: Local ,  value :  Value )  -> EvalResult < ' tcx >  { 
16251607        // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0. 
1626-         if  let  Some ( field)  = field { 
1627-             match  self . locals [ local. index ( )  - 1 ]  { 
1628-                 None  => return  Err ( EvalError :: DeadLocal ) , 
1629-                 Some ( Value :: ByRef ( _) )  => bug ! ( "can't have lvalue fields for ByRef" ) , 
1630-                 Some ( Value :: ByVal ( _) )  => { 
1631-                     assert_eq ! ( field,  0 ) ; 
1632-                     self . set_local ( local,  None ,  value) ?; 
1633-                 } , 
1634-                 Some ( Value :: ByValPair ( a,  b) )  => { 
1635-                     let  prim = match  value { 
1636-                         Value :: ByRef ( _)  => bug ! ( "can't set ValPair field to ByRef" ) , 
1637-                         Value :: ByVal ( val)  => val, 
1638-                         Value :: ByValPair ( _,  _)  => bug ! ( "can't set ValPair field to ValPair" ) , 
1639-                     } ; 
1640-                     match  field { 
1641-                         0  => self . set_local ( local,  None ,  Value :: ByValPair ( prim,  b) ) ?, 
1642-                         1  => self . set_local ( local,  None ,  Value :: ByValPair ( a,  prim) ) ?, 
1643-                         _ => bug ! ( "ByValPair has only two fields, tried to access {}" ,  field) , 
1644-                     } 
1645-                 } , 
1646-             } 
1647-         }  else  { 
1648-             match  self . locals [ local. index ( )  - 1 ]  { 
1649-                 None  => return  Err ( EvalError :: DeadLocal ) , 
1650-                 Some ( ref  mut  local)  => {  * local = value;  } 
1608+         match  self . locals [ local. index ( )  - 1 ]  { 
1609+             None  => Err ( EvalError :: DeadLocal ) , 
1610+             Some ( ref  mut  local)  => { 
1611+                 * local = value; 
1612+                 Ok ( ( ) ) 
16511613            } 
16521614        } 
1653-         return  Ok ( ( ) ) ; 
16541615    } 
16551616
16561617    pub  fn  storage_live ( & mut  self ,  local :  mir:: Local )  -> EvalResult < ' tcx ,  Option < Value > >  { 
0 commit comments