@@ -91,42 +91,43 @@ pub trait PointerArithmetic: layout::HasDataLayout {
9191    } 
9292
9393    //// Trunace the given value to the pointer size; also return whether there was an overflow 
94+     #[ inline]  
9495    fn  truncate_to_ptr ( & self ,  val :  u128 )  -> ( u64 ,  bool )  { 
9596        let  max_ptr_plus_1 = 1u128  << self . pointer_size ( ) . bits ( ) ; 
9697        ( ( val % max_ptr_plus_1)  as  u64 ,  val >= max_ptr_plus_1) 
9798    } 
9899
99-     // Overflow checking only works properly on the range from -u64 to +u64. 
100-     fn  overflowing_signed_offset ( & self ,  val :  u64 ,  i :  i128 )  -> ( u64 ,  bool )  { 
101-         // FIXME: is it possible to over/underflow here? 
102-         if  i < 0  { 
103-             // trickery to ensure that i64::min_value() works fine 
104-             // this formula only works for true negative values, it panics for zero! 
105-             let  n = u64:: max_value ( )  - ( i as  u64 )  + 1 ; 
106-             val. overflowing_sub ( n) 
107-         }  else  { 
108-             self . overflowing_offset ( val,  i as  u64 ) 
109-         } 
100+     #[ inline]  
101+     fn  offset < ' tcx > ( & self ,  val :  u64 ,  i :  u64 )  -> EvalResult < ' tcx ,  u64 >  { 
102+         let  ( res,  over)  = self . overflowing_offset ( val,  i) ; 
103+         if  over {  err ! ( Overflow ( mir:: BinOp :: Add ) )  }  else  {  Ok ( res)  } 
110104    } 
111105
106+     #[ inline]  
112107    fn  overflowing_offset ( & self ,  val :  u64 ,  i :  u64 )  -> ( u64 ,  bool )  { 
113108        let  ( res,  over1)  = val. overflowing_add ( i) ; 
114-         let  ( res,  over2)  = self . truncate_to_ptr ( res  as   u128 ) ; 
109+         let  ( res,  over2)  = self . truncate_to_ptr ( u128:: from ( res ) ) ; 
115110        ( res,  over1 || over2) 
116111    } 
117112
113+     #[ inline]  
118114    fn  signed_offset < ' tcx > ( & self ,  val :  u64 ,  i :  i64 )  -> EvalResult < ' tcx ,  u64 >  { 
119-         let  ( res,  over)  = self . overflowing_signed_offset ( val,  i  as   i128 ) ; 
115+         let  ( res,  over)  = self . overflowing_signed_offset ( val,  i128:: from ( i ) ) ; 
120116        if  over {  err ! ( Overflow ( mir:: BinOp :: Add ) )  }  else  {  Ok ( res)  } 
121117    } 
122118
123-     fn  offset < ' tcx > ( & self ,  val :  u64 ,  i :  u64 )  -> EvalResult < ' tcx ,  u64 >  { 
124-         let  ( res,  over)  = self . overflowing_offset ( val,  i) ; 
125-         if  over {  err ! ( Overflow ( mir:: BinOp :: Add ) )  }  else  {  Ok ( res)  } 
126-     } 
127- 
128-     fn  wrapping_signed_offset ( & self ,  val :  u64 ,  i :  i64 )  -> u64  { 
129-         self . overflowing_signed_offset ( val,  i as  i128 ) . 0 
119+     // Overflow checking only works properly on the range from -u64 to +u64. 
120+     #[ inline]  
121+     fn  overflowing_signed_offset ( & self ,  val :  u64 ,  i :  i128 )  -> ( u64 ,  bool )  { 
122+         // FIXME: is it possible to over/underflow here? 
123+         if  i < 0  { 
124+             // trickery to ensure that i64::min_value() works fine 
125+             // this formula only works for true negative values, it panics for zero! 
126+             let  n = u64:: max_value ( )  - ( i as  u64 )  + 1 ; 
127+             val. overflowing_sub ( n) 
128+         }  else  { 
129+             self . overflowing_offset ( val,  i as  u64 ) 
130+         } 
130131    } 
131132} 
132133
@@ -176,19 +177,27 @@ impl<'tcx, Tag> Pointer<Tag> {
176177        Pointer  {  alloc_id,  offset,  tag } 
177178    } 
178179
179-     pub  fn  wrapping_signed_offset ( self ,  i :  i64 ,  cx :  & impl  HasDataLayout )  -> Self  { 
180-         Pointer :: new_with_tag ( 
180+     #[ inline]  
181+     pub  fn  offset ( self ,  i :  Size ,  cx :  & impl  HasDataLayout )  -> EvalResult < ' tcx ,  Self >  { 
182+         Ok ( Pointer :: new_with_tag ( 
181183            self . alloc_id , 
182-             Size :: from_bytes ( cx. data_layout ( ) . wrapping_signed_offset ( self . offset . bytes ( ) ,  i) ) , 
183-             self . tag , 
184-         ) 
184+             Size :: from_bytes ( cx. data_layout ( ) . offset ( self . offset . bytes ( ) ,  i. bytes ( ) ) ? ) , 
185+             self . tag 
186+         ) ) 
185187    } 
186188
187-     pub  fn  overflowing_signed_offset ( self ,  i :  i128 ,  cx :  & impl  HasDataLayout )  -> ( Self ,  bool )  { 
188-         let  ( res,  over)  = cx. data_layout ( ) . overflowing_signed_offset ( self . offset . bytes ( ) ,  i) ; 
189+     #[ inline]  
190+     pub  fn  overflowing_offset ( self ,  i :  Size ,  cx :  & impl  HasDataLayout )  -> ( Self ,  bool )  { 
191+         let  ( res,  over)  = cx. data_layout ( ) . overflowing_offset ( self . offset . bytes ( ) ,  i. bytes ( ) ) ; 
189192        ( Pointer :: new_with_tag ( self . alloc_id ,  Size :: from_bytes ( res) ,  self . tag ) ,  over) 
190193    } 
191194
195+     #[ inline( always) ]  
196+     pub  fn  wrapping_offset ( self ,  i :  Size ,  cx :  & impl  HasDataLayout )  -> Self  { 
197+         self . overflowing_offset ( i,  cx) . 0 
198+     } 
199+ 
200+     #[ inline]  
192201    pub  fn  signed_offset ( self ,  i :  i64 ,  cx :  & impl  HasDataLayout )  -> EvalResult < ' tcx ,  Self >  { 
193202        Ok ( Pointer :: new_with_tag ( 
194203            self . alloc_id , 
@@ -197,20 +206,18 @@ impl<'tcx, Tag> Pointer<Tag> {
197206        ) ) 
198207    } 
199208
200-     pub  fn  overflowing_offset ( self ,  i :  Size ,  cx :  & impl  HasDataLayout )  -> ( Self ,  bool )  { 
201-         let  ( res,  over)  = cx. data_layout ( ) . overflowing_offset ( self . offset . bytes ( ) ,  i. bytes ( ) ) ; 
209+     #[ inline]  
210+     pub  fn  overflowing_signed_offset ( self ,  i :  i128 ,  cx :  & impl  HasDataLayout )  -> ( Self ,  bool )  { 
211+         let  ( res,  over)  = cx. data_layout ( ) . overflowing_signed_offset ( self . offset . bytes ( ) ,  i) ; 
202212        ( Pointer :: new_with_tag ( self . alloc_id ,  Size :: from_bytes ( res) ,  self . tag ) ,  over) 
203213    } 
204214
205-     pub  fn  offset ( self ,  i :  Size ,  cx :  & impl  HasDataLayout )  -> EvalResult < ' tcx ,  Self >  { 
206-         Ok ( Pointer :: new_with_tag ( 
207-             self . alloc_id , 
208-             Size :: from_bytes ( cx. data_layout ( ) . offset ( self . offset . bytes ( ) ,  i. bytes ( ) ) ?) , 
209-             self . tag 
210-         ) ) 
215+     #[ inline( always) ]  
216+     pub  fn  wrapping_signed_offset ( self ,  i :  i64 ,  cx :  & impl  HasDataLayout )  -> Self  { 
217+         self . overflowing_signed_offset ( i128:: from ( i) ,  cx) . 0 
211218    } 
212219
213-     #[ inline]  
220+     #[ inline( always ) ]  
214221    pub  fn  erase_tag ( self )  -> Pointer  { 
215222        Pointer  {  alloc_id :  self . alloc_id ,  offset :  self . offset ,  tag :  ( )  } 
216223    } 
0 commit comments