@@ -151,7 +151,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
151151 "Unexpected cast from type {:?}" , src_layout. ty
152152 ) ;
153153 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) ,
155155 Ok ( data) => self . cast_from_int ( data, src_layout, dest_layout) ,
156156 }
157157 }
@@ -239,34 +239,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
239239 fn cast_from_ptr (
240240 & self ,
241241 ptr : Pointer < M :: PointerTag > ,
242- ty : Ty < ' tcx >
242+ src_layout : TyLayout < ' tcx > ,
243+ dest_layout : TyLayout < ' tcx > ,
243244 ) -> InterpResult < ' tcx , Scalar < M :: PointerTag > > {
244245 use rustc:: ty:: TyKind :: * ;
245246
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 {
247256 // Casting to a reference or fn pointer is not permitted by rustc,
248257 // no need to support it here.
249- RawPtr ( _) => return Ok ( ptr. into ( ) ) ,
258+ RawPtr ( _) => Ok ( ptr. into ( ) ) ,
250259 Int ( IntTy :: Isize ) | Uint ( UintTy :: Usize ) => {
251260 let size = self . memory . pointer_size ( ) ;
261+
252262 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+ }
256267 }
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+ } ,
260277 // 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) ) ) ,
270279 }
271280 }
272281
0 commit comments