1
Fork 0

Rollup merge of #103546 - RalfJung:cast, r=oli-obk

interpret: a bit of cast cleanup

r? `@oli-obk`
This commit is contained in:
Dylan DPC 2022-10-26 17:32:55 +05:30 committed by GitHub
commit 709462bfe1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -138,21 +138,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(()) Ok(())
} }
/// Handles 'IntToInt' and 'IntToFloat' casts.
pub fn int_to_int_or_float( pub fn int_to_int_or_float(
&self, &self,
src: &ImmTy<'tcx, M::Provenance>, src: &ImmTy<'tcx, M::Provenance>,
cast_ty: Ty<'tcx>, cast_ty: Ty<'tcx>,
) -> InterpResult<'tcx, Immediate<M::Provenance>> { ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
if (src.layout.ty.is_integral() || src.layout.ty.is_char() || src.layout.ty.is_bool()) assert!(src.layout.ty.is_integral() || src.layout.ty.is_char() || src.layout.ty.is_bool());
&& (cast_ty.is_floating_point() || cast_ty.is_integral() || cast_ty.is_char()) assert!(cast_ty.is_floating_point() || cast_ty.is_integral() || cast_ty.is_char());
{
let scalar = src.to_scalar(); Ok(self.cast_from_int_like(src.to_scalar(), src.layout, cast_ty)?.into())
Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
} else {
bug!("Unexpected cast from type {:?}", src.layout.ty)
}
} }
/// Handles 'FloatToFloat' and 'FloatToInt' casts.
pub fn float_to_float_or_int( pub fn float_to_float_or_int(
&self, &self,
src: &ImmTy<'tcx, M::Provenance>, src: &ImmTy<'tcx, M::Provenance>,
@ -180,31 +178,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
src: &ImmTy<'tcx, M::Provenance>, src: &ImmTy<'tcx, M::Provenance>,
cast_ty: Ty<'tcx>, cast_ty: Ty<'tcx>,
) -> InterpResult<'tcx, Immediate<M::Provenance>> { ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
assert!(src.layout.ty.is_any_ptr());
assert!(cast_ty.is_unsafe_ptr());
// Handle casting any ptr to raw ptr (might be a fat ptr). // Handle casting any ptr to raw ptr (might be a fat ptr).
if src.layout.ty.is_any_ptr() && cast_ty.is_unsafe_ptr() { let dest_layout = self.layout_of(cast_ty)?;
let dest_layout = self.layout_of(cast_ty)?; if dest_layout.size == src.layout.size {
if dest_layout.size == src.layout.size { // Thin or fat pointer that just hast the ptr kind of target type changed.
// Thin or fat pointer that just hast the ptr kind of target type changed. return Ok(**src);
return Ok(**src);
} else {
// Casting the metadata away from a fat ptr.
assert_eq!(src.layout.size, 2 * self.pointer_size());
assert_eq!(dest_layout.size, self.pointer_size());
assert!(src.layout.ty.is_unsafe_ptr());
return match **src {
Immediate::ScalarPair(data, _) => Ok(data.into()),
Immediate::Scalar(..) => span_bug!(
self.cur_span(),
"{:?} input to a fat-to-thin cast ({:?} -> {:?})",
*src,
src.layout.ty,
cast_ty
),
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
};
}
} else { } else {
bug!("Can't cast 'Ptr' or 'FnPtr' into {:?}", cast_ty); // Casting the metadata away from a fat ptr.
assert_eq!(src.layout.size, 2 * self.pointer_size());
assert_eq!(dest_layout.size, self.pointer_size());
assert!(src.layout.ty.is_unsafe_ptr());
return match **src {
Immediate::ScalarPair(data, _) => Ok(data.into()),
Immediate::Scalar(..) => span_bug!(
self.cur_span(),
"{:?} input to a fat-to-thin cast ({:?} -> {:?})",
*src,
src.layout.ty,
cast_ty
),
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
};
} }
} }
@ -243,6 +239,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(Scalar::from_maybe_pointer(ptr, self).into()) Ok(Scalar::from_maybe_pointer(ptr, self).into())
} }
/// Low-level cast helper function. This works directly on scalars and can take 'int-like' input
/// type (basically everything with a scalar layout) to int/float/char types.
pub fn cast_from_int_like( pub fn cast_from_int_like(
&self, &self,
scalar: Scalar<M::Provenance>, // input value (there is no ScalarTy so we separate data+layout) 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> {
}) })
} }
/// Low-level cast helper function. Converts an apfloat `f` into int or float types.
fn cast_from_float<F>(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::Provenance> fn cast_from_float<F>(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::Provenance>
where where
F: Float + Into<Scalar<M::Provenance>> + FloatConvert<Single> + FloatConvert<Double>, F: Float + Into<Scalar<M::Provenance>> + FloatConvert<Single> + FloatConvert<Double>,