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