@@ -151,7 +151,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
151
151
"Unexpected cast from type {:?}" , src_layout. ty
152
152
) ;
153
153
match val. to_bits_or_ptr ( src_layout. size , self ) {
154
- Err ( ptr) => self . cast_from_ptr ( ptr, dest_layout. ty ) ,
154
+ Err ( ptr) => self . cast_from_ptr ( ptr, src_layout , dest_layout) ,
155
155
Ok ( data) => self . cast_from_int ( data, src_layout, dest_layout) ,
156
156
}
157
157
}
@@ -239,34 +239,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
239
239
fn cast_from_ptr (
240
240
& self ,
241
241
ptr : Pointer < M :: PointerTag > ,
242
- ty : Ty < ' tcx >
242
+ src_layout : TyLayout < ' tcx > ,
243
+ dest_layout : TyLayout < ' tcx > ,
243
244
) -> InterpResult < ' tcx , Scalar < M :: PointerTag > > {
244
245
use rustc:: ty:: TyKind :: * ;
245
246
246
- let size = match ty. sty {
247
+ fn int_size < ' tcx > ( layout : TyLayout < ' tcx > ) -> Option < usize > {
248
+ match layout. ty . sty {
249
+ Int ( i) => i. bit_width ( ) ,
250
+ Uint ( i) => i. bit_width ( ) ,
251
+ _ => bug ! ( "Not an integer" ) ,
252
+ }
253
+ }
254
+
255
+ match dest_layout. ty . sty {
247
256
// Casting to a reference or fn pointer is not permitted by rustc,
248
257
// no need to support it here.
249
- RawPtr ( _) => return Ok ( ptr. into ( ) ) ,
258
+ RawPtr ( _) => Ok ( ptr. into ( ) ) ,
250
259
Int ( IntTy :: Isize ) | Uint ( UintTy :: Usize ) => {
251
260
let size = self . memory . pointer_size ( ) ;
261
+
252
262
if let Ok ( bits) = self . force_bits ( Scalar :: Ptr ( ptr) , size) {
253
- return Ok ( Scalar :: from_uint ( bits, size) ) ;
254
- }
255
- return Ok ( ptr. into ( ) ) ;
263
+ self . cast_from_int ( bits, src_layout, dest_layout)
264
+ } else {
265
+ Ok ( ptr. into ( ) )
266
+ }
256
267
}
257
- // If the target type is a sized integer, we need the its size to perform the pointer cast
258
- Int ( i) => i. bit_width ( ) . unwrap ( ) ,
259
- Uint ( i) => i. bit_width ( ) . unwrap ( ) ,
268
+ Int ( _) | Uint ( _) => {
269
+ let size = Size :: from_bits ( int_size ( dest_layout) . unwrap ( ) as u64 ) ;
270
+
271
+ if let Ok ( bits) = self . force_bits ( Scalar :: Ptr ( ptr) , size) {
272
+ self . cast_from_int ( bits, src_layout, dest_layout)
273
+ } else {
274
+ err ! ( ReadPointerAsBytes )
275
+ }
276
+ } ,
260
277
// Casting to any other type is not implemented
261
- _ => return err ! ( Unimplemented ( format!( "ptr to {:?} cast" , ty) ) ) ,
262
- } ;
263
-
264
- let size = Size :: from_bits ( size as u64 ) ;
265
-
266
- if let Ok ( bits) = self . force_bits ( Scalar :: Ptr ( ptr) , size) {
267
- Ok ( Scalar :: from_uint ( bits, size) )
268
- } else {
269
- err ! ( ReadPointerAsBytes )
278
+ _ => return err ! ( Unimplemented ( format!( "ptr to {:?} cast" , dest_layout. ty) ) ) ,
270
279
}
271
280
}
272
281
0 commit comments