@@ -138,21 +138,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
138
138
Ok ( ( ) )
139
139
}
140
140
141
+ /// Handles 'IntToInt' and 'IntToFloat' casts.
141
142
pub fn int_to_int_or_float (
142
143
& self ,
143
144
src : & ImmTy < ' tcx , M :: Provenance > ,
144
145
cast_ty : Ty < ' tcx > ,
145
146
) -> 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
- }
147
+ assert ! ( src. layout. ty. is_integral( ) || src. layout. ty. is_char( ) || src. layout. ty. is_bool( ) ) ;
148
+ assert ! ( cast_ty. is_floating_point( ) || cast_ty. is_integral( ) || cast_ty. is_char( ) ) ;
149
+
150
+ Ok ( self . cast_from_int_like ( src. to_scalar ( ) , src. layout , cast_ty) ?. into ( ) )
154
151
}
155
152
153
+ /// Handles 'FloatToFloat' and 'FloatToInt' casts.
156
154
pub fn float_to_float_or_int (
157
155
& self ,
158
156
src : & ImmTy < ' tcx , M :: Provenance > ,
@@ -180,31 +178,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
180
178
src : & ImmTy < ' tcx , M :: Provenance > ,
181
179
cast_ty : Ty < ' tcx > ,
182
180
) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
181
+ assert ! ( src. layout. ty. is_any_ptr( ) ) ;
182
+ assert ! ( cast_ty. is_unsafe_ptr( ) ) ;
183
183
// Handle casting any ptr to raw ptr (might be a fat ptr).
184
- if src. layout . ty . is_any_ptr ( ) && cast_ty. is_unsafe_ptr ( ) {
185
- let dest_layout = self . layout_of ( cast_ty) ?;
186
- if dest_layout. size == src. layout . size {
187
- // Thin or fat pointer that just hast the ptr kind of target type changed.
188
- return Ok ( * * src) ;
189
- } else {
190
- // Casting the metadata away from a fat ptr.
191
- assert_eq ! ( src. layout. size, 2 * self . pointer_size( ) ) ;
192
- assert_eq ! ( dest_layout. size, self . pointer_size( ) ) ;
193
- assert ! ( src. layout. ty. is_unsafe_ptr( ) ) ;
194
- return match * * src {
195
- Immediate :: ScalarPair ( data, _) => Ok ( data. into ( ) ) ,
196
- Immediate :: Scalar ( ..) => span_bug ! (
197
- self . cur_span( ) ,
198
- "{:?} input to a fat-to-thin cast ({:?} -> {:?})" ,
199
- * src,
200
- src. layout. ty,
201
- cast_ty
202
- ) ,
203
- Immediate :: Uninit => throw_ub ! ( InvalidUninitBytes ( None ) ) ,
204
- } ;
205
- }
184
+ let dest_layout = self . layout_of ( cast_ty) ?;
185
+ if dest_layout. size == src. layout . size {
186
+ // Thin or fat pointer that just hast the ptr kind of target type changed.
187
+ return Ok ( * * src) ;
206
188
} else {
207
- bug ! ( "Can't cast 'Ptr' or 'FnPtr' into {:?}" , cast_ty) ;
189
+ // Casting the metadata away from a fat ptr.
190
+ assert_eq ! ( src. layout. size, 2 * self . pointer_size( ) ) ;
191
+ assert_eq ! ( dest_layout. size, self . pointer_size( ) ) ;
192
+ assert ! ( src. layout. ty. is_unsafe_ptr( ) ) ;
193
+ return match * * src {
194
+ Immediate :: ScalarPair ( data, _) => Ok ( data. into ( ) ) ,
195
+ Immediate :: Scalar ( ..) => span_bug ! (
196
+ self . cur_span( ) ,
197
+ "{:?} input to a fat-to-thin cast ({:?} -> {:?})" ,
198
+ * src,
199
+ src. layout. ty,
200
+ cast_ty
201
+ ) ,
202
+ Immediate :: Uninit => throw_ub ! ( InvalidUninitBytes ( None ) ) ,
203
+ } ;
208
204
}
209
205
}
210
206
@@ -243,6 +239,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
243
239
Ok ( Scalar :: from_maybe_pointer ( ptr, self ) . into ( ) )
244
240
}
245
241
242
+ /// Low-level cast helper function. This works directly on scalars and can take 'int-like' input
243
+ /// type (basically everything with a scalar layout) to int/float/char types.
246
244
pub fn cast_from_int_like (
247
245
& self ,
248
246
scalar : Scalar < M :: Provenance > , // input value (there is no ScalarTy so we separate data+layout)
@@ -282,6 +280,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
282
280
} )
283
281
}
284
282
283
+ /// Low-level cast helper function. Converts an apfloat `f` into int or float types.
285
284
fn cast_from_float < F > ( & self , f : F , dest_ty : Ty < ' tcx > ) -> Scalar < M :: Provenance >
286
285
where
287
286
F : Float + Into < Scalar < M :: Provenance > > + FloatConvert < Single > + FloatConvert < Double > ,
0 commit comments