@@ -42,10 +42,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
42
42
let res = self . pointer_from_exposed_address_cast ( & src, cast_ty) ?;
43
43
self . write_immediate ( res, dest) ?;
44
44
}
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 => {
47
47
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) ?;
49
61
self . write_immediate ( res, dest) ?;
50
62
}
51
63
@@ -126,13 +138,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
126
138
Ok ( ( ) )
127
139
}
128
140
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 (
130
157
& mut self ,
131
158
src : & ImmTy < ' tcx , M :: Provenance > ,
132
159
cast_ty : Ty < ' tcx > ,
133
160
) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
134
161
use rustc_type_ir:: sty:: TyKind :: * ;
135
- trace ! ( "Casting {:?}: {:?} to {:?}" , * src, src. layout. ty, cast_ty) ;
136
162
137
163
match src. layout . ty . kind ( ) {
138
164
// Floating point
@@ -142,19 +168,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
142
168
Float ( FloatTy :: F64 ) => {
143
169
return Ok ( self . cast_from_float ( src. to_scalar ( ) . to_f64 ( ) ?, cast_ty) . into ( ) ) ;
144
170
}
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
+ }
154
174
}
175
+ }
155
176
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 > > {
158
183
// Handle casting any ptr to raw ptr (might be a fat ptr).
159
184
if src. layout . ty . is_any_ptr ( ) && cast_ty. is_unsafe_ptr ( ) {
160
185
let dest_layout = self . layout_of ( cast_ty) ?;
@@ -178,11 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
178
203
Immediate :: Uninit => throw_ub ! ( InvalidUninitBytes ( None ) ) ,
179
204
} ;
180
205
}
206
+ } else {
207
+ bug ! ( "Can't cast 'Ptr' or 'FnPtr' into {:?}" , cast_ty) ;
181
208
}
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 ( ) )
186
209
}
187
210
188
211
pub fn pointer_expose_address_cast (
0 commit comments