Skip to content

Commit 24d17ef

Browse files
authored
Rollup merge of rust-lang#103122 - ouz-a:mir-technical-debt, r=oli-obk
Remove misc_cast and validate types when casting Continuing our work in rust-lang#102675 r? `@oli-obk`
2 parents f7bf5cd + cc1407f commit 24d17ef

File tree

2 files changed

+63
-25
lines changed

2 files changed

+63
-25
lines changed

compiler/rustc_const_eval/src/interpret/cast.rs

+43-20
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
4242
let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?;
4343
self.write_immediate(res, dest)?;
4444
}
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 => {
4747
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)?;
4961
self.write_immediate(res, dest)?;
5062
}
5163

@@ -126,13 +138,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
126138
Ok(())
127139
}
128140

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(
130157
&mut self,
131158
src: &ImmTy<'tcx, M::Provenance>,
132159
cast_ty: Ty<'tcx>,
133160
) -> InterpResult<'tcx, Immediate<M::Provenance>> {
134161
use rustc_type_ir::sty::TyKind::*;
135-
trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, cast_ty);
136162

137163
match src.layout.ty.kind() {
138164
// Floating point
@@ -142,19 +168,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
142168
Float(FloatTy::F64) => {
143169
return Ok(self.cast_from_float(src.to_scalar().to_f64()?, cast_ty).into());
144170
}
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+
}
154174
}
175+
}
155176

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>> {
158183
// Handle casting any ptr to raw ptr (might be a fat ptr).
159184
if src.layout.ty.is_any_ptr() && cast_ty.is_unsafe_ptr() {
160185
let dest_layout = self.layout_of(cast_ty)?;
@@ -178,11 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
178203
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
179204
};
180205
}
206+
} else {
207+
bug!("Can't cast 'Ptr' or 'FnPtr' into {:?}", cast_ty);
181208
}
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())
186209
}
187210

188211
pub fn pointer_expose_address_cast(

compiler/rustc_const_eval/src/transform/validate.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -556,21 +556,36 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
556556
check_kinds!(a, "Cannot shallow init type {:?}", ty::RawPtr(..));
557557
}
558558
Rvalue::Cast(kind, operand, target_type) => {
559+
let op_ty = operand.ty(self.body, self.tcx);
559560
match kind {
560561
CastKind::DynStar => {
561562
// FIXME(dyn-star): make sure nothing needs to be done here.
562563
}
563-
// Nothing to check here
564+
// FIXME: Add Checks for these
564565
CastKind::PointerFromExposedAddress
565566
| CastKind::PointerExposeAddress
566567
| CastKind::Pointer(_) => {}
567-
_ => {
568-
let op_ty = operand.ty(self.body, self.tcx);
569-
if op_ty.is_enum() {
568+
CastKind::IntToInt | CastKind::IntToFloat => {
569+
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
570+
let target_valid = target_type.is_numeric() || target_type.is_char();
571+
if !input_valid || !target_valid {
572+
self.fail(
573+
location,
574+
format!("Wrong cast kind {kind:?} for the type {op_ty}",),
575+
);
576+
}
577+
}
578+
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
579+
if !(op_ty.is_any_ptr() && target_type.is_unsafe_ptr()) {
580+
self.fail(location, "Can't cast {op_ty} into 'Ptr'");
581+
}
582+
}
583+
CastKind::FloatToFloat | CastKind::FloatToInt => {
584+
if !op_ty.is_floating_point() || !target_type.is_numeric() {
570585
self.fail(
571586
location,
572587
format!(
573-
"enum -> int casts should go through `Rvalue::Discriminant`: {operand:?}:{op_ty} as {target_type}",
588+
"Trying to cast non 'Float' as {kind:?} into {target_type:?}"
574589
),
575590
);
576591
}

0 commit comments

Comments
 (0)