@@ -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