@@ -138,21 +138,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
138138 Ok ( ( ) )
139139 }
140140
141+ /// Handles 'IntToInt' and 'IntToFloat' casts.
141142 pub fn int_to_int_or_float (
142143 & self ,
143144 src : & ImmTy < ' tcx , M :: Provenance > ,
144145 cast_ty : Ty < ' tcx > ,
145146 ) -> 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 ( ) )
154151 }
155152
153+ /// Handles 'FloatToFloat' and 'FloatToInt' casts.
156154 pub fn float_to_float_or_int (
157155 & self ,
158156 src : & ImmTy < ' tcx , M :: Provenance > ,
@@ -180,31 +178,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
180178 src : & ImmTy < ' tcx , M :: Provenance > ,
181179 cast_ty : Ty < ' tcx > ,
182180 ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
181+ assert ! ( src. layout. ty. is_any_ptr( ) ) ;
182+ assert ! ( cast_ty. is_unsafe_ptr( ) ) ;
183183 // 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) ;
206188 } 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+ } ;
208204 }
209205 }
210206
@@ -243,6 +239,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
243239 Ok ( Scalar :: from_maybe_pointer ( ptr, self ) . into ( ) )
244240 }
245241
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.
246244 pub fn cast_from_int_like (
247245 & self ,
248246 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> {
282280 } )
283281 }
284282
283+ /// Low-level cast helper function. Converts an apfloat `f` into int or float types.
285284 fn cast_from_float < F > ( & self , f : F , dest_ty : Ty < ' tcx > ) -> Scalar < M :: Provenance >
286285 where
287286 F : Float + Into < Scalar < M :: Provenance > > + FloatConvert < Single > + FloatConvert < Double > ,
0 commit comments