@@ -42,10 +42,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
4242                let  res = self . pointer_from_exposed_address_cast ( & src,  cast_ty) ?; 
4343                self . write_immediate ( res,  dest) ?; 
4444            } 
45-              // FIXME: We shouldn't use `misc_cast` for these but handle them separately. 
46-             IntToInt  | FloatToInt  |  FloatToFloat  |  IntToFloat  |  FnPtrToPtr  |  PtrToPtr  => { 
45+ 
46+             IntToInt  | IntToFloat  => { 
4747                let  src = self . read_immediate ( src) ?; 
48-                 let  res = self . misc_cast ( & src,  cast_ty) ?; 
48+                 let  res = self . int_to_int_or_float ( & src,  cast_ty) ?; 
49+                 self . write_immediate ( res,  dest) ?; 
50+             } 
51+ 
52+             FloatToFloat  | FloatToInt  => { 
53+                 let  src = self . read_immediate ( src) ?; 
54+                 let  res = self . float_to_float_or_int ( & src,  cast_ty) ?; 
55+                 self . write_immediate ( res,  dest) ?; 
56+             } 
57+ 
58+             FnPtrToPtr  | PtrToPtr  => { 
59+                 let  src = self . read_immediate ( & src) ?; 
60+                 let  res = self . ptr_to_ptr ( & src,  cast_ty) ?; 
4961                self . write_immediate ( res,  dest) ?; 
5062            } 
5163
@@ -126,13 +138,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
126138        Ok ( ( ) ) 
127139    } 
128140
129-     pub  fn  misc_cast ( 
141+     pub  fn  int_to_int_or_float ( 
142+         & mut  self , 
143+         src :  & ImmTy < ' tcx ,  M :: Provenance > , 
144+         cast_ty :  Ty < ' tcx > , 
145+     )  -> InterpResult < ' tcx ,  Immediate < M :: Provenance > >  { 
146+         if  ( src. layout . ty . is_integral ( )  || src. layout . ty . is_char ( )  || src. layout . ty . is_bool ( ) ) 
147+             && ( cast_ty. is_floating_point ( )  || cast_ty. is_integral ( )  || cast_ty. is_char ( ) ) 
148+         { 
149+             let  scalar = src. to_scalar ( ) ; 
150+             Ok ( self . cast_from_int_like ( scalar,  src. layout ,  cast_ty) ?. into ( ) ) 
151+         }  else  { 
152+             bug ! ( "Unexpected cast from type {:?}" ,  src. layout. ty) 
153+         } 
154+     } 
155+ 
156+     pub  fn  float_to_float_or_int ( 
130157        & mut  self , 
131158        src :  & ImmTy < ' tcx ,  M :: Provenance > , 
132159        cast_ty :  Ty < ' tcx > , 
133160    )  -> InterpResult < ' tcx ,  Immediate < M :: Provenance > >  { 
134161        use  rustc_type_ir:: sty:: TyKind :: * ; 
135-         trace ! ( "Casting {:?}: {:?} to {:?}" ,  * src,  src. layout. ty,  cast_ty) ; 
136162
137163        match  src. layout . ty . kind ( )  { 
138164            // Floating point 
@@ -142,19 +168,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
142168            Float ( FloatTy :: F64 )  => { 
143169                return  Ok ( self . cast_from_float ( src. to_scalar ( ) . to_f64 ( ) ?,  cast_ty) . into ( ) ) ; 
144170            } 
145-             // The rest is integer/pointer-"like", including fn ptr casts 
146-             _ => assert ! ( 
147-                 src. layout. ty. is_bool( ) 
148-                     || src. layout. ty. is_char( ) 
149-                     || src. layout. ty. is_integral( ) 
150-                     || src. layout. ty. is_any_ptr( ) , 
151-                 "Unexpected cast from type {:?}" , 
152-                 src. layout. ty
153-             ) , 
171+             _ => { 
172+                 bug ! ( "Can't cast 'Float' type into {:?}" ,  cast_ty) ; 
173+             } 
154174        } 
175+     } 
155176
156-         // # First handle non-scalar source values. 
157- 
177+     /// Handles 'FnPtrToPtr' and 'PtrToPtr' casts. 
178+      pub  fn  ptr_to_ptr ( 
179+         & mut  self , 
180+         src :  & ImmTy < ' tcx ,  M :: Provenance > , 
181+         cast_ty :  Ty < ' tcx > , 
182+     )  -> InterpResult < ' tcx ,  Immediate < M :: Provenance > >  { 
158183        // Handle casting any ptr to raw ptr (might be a fat ptr). 
159184        if  src. layout . ty . is_any_ptr ( )  && cast_ty. is_unsafe_ptr ( )  { 
160185            let  dest_layout = self . layout_of ( cast_ty) ?; 
@@ -178,11 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
178203                    Immediate :: Uninit  => throw_ub ! ( InvalidUninitBytes ( None ) ) , 
179204                } ; 
180205            } 
206+         }  else  { 
207+             bug ! ( "Can't cast 'Ptr' or 'FnPtr' into {:?}" ,  cast_ty) ; 
181208        } 
182- 
183-         // # The remaining source values are scalar and "int-like". 
184-         let  scalar = src. to_scalar ( ) ; 
185-         Ok ( self . cast_from_int_like ( scalar,  src. layout ,  cast_ty) ?. into ( ) ) 
186209    } 
187210
188211    pub  fn  pointer_expose_address_cast ( 
0 commit comments