Skip to content

Commit cb8705a

Browse files
committed
Add some more specific checks to the MIR validator
None of the `PointerCoercion`s had any, so while there's probably more that could be done here, hopefully these are better than the previous nothing.
1 parent 20be84a commit cb8705a

File tree

1 file changed

+92
-7
lines changed

1 file changed

+92
-7
lines changed

compiler/rustc_mir_transform/src/validate.rs

+92-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_middle::mir::coverage::CoverageKind;
88
use rustc_middle::mir::interpret::Scalar;
99
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
1010
use rustc_middle::mir::*;
11+
use rustc_middle::ty::adjustment::PointerCoercion;
1112
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance};
1213
use rustc_middle::{bug, span_bug};
1314
use rustc_target::abi::{Size, FIRST_VARIANT};
@@ -1132,9 +1133,74 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11321133
// FIXME(dyn-star): make sure nothing needs to be done here.
11331134
}
11341135
// FIXME: Add Checks for these
1135-
CastKind::PointerWithExposedProvenance
1136-
| CastKind::PointerExposeProvenance
1137-
| CastKind::PointerCoercion(_) => {}
1136+
CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {}
1137+
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
1138+
check_kinds!(
1139+
op_ty,
1140+
"CastKind::{kind:?} input must be a fn item, not {:?}",
1141+
ty::FnDef(..)
1142+
);
1143+
check_kinds!(
1144+
target_type,
1145+
"CastKind::{kind:?} output must be a fn pointer, not {:?}",
1146+
ty::FnPtr(..)
1147+
);
1148+
}
1149+
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
1150+
// FIXME: check safety
1151+
check_kinds!(
1152+
op_ty,
1153+
"CastKind::{kind:?} input must be a fn pointer, not {:?}",
1154+
ty::FnPtr(..)
1155+
);
1156+
check_kinds!(
1157+
target_type,
1158+
"CastKind::{kind:?} output must be a fn pointer, not {:?}",
1159+
ty::FnPtr(..)
1160+
);
1161+
}
1162+
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => {
1163+
// FIXME: check safety & captures
1164+
check_kinds!(
1165+
op_ty,
1166+
"CastKind::{kind:?} input must be a closure, not {:?}",
1167+
ty::Closure(..)
1168+
);
1169+
check_kinds!(
1170+
target_type,
1171+
"CastKind::{kind:?} output must be a fn pointer, not {:?}",
1172+
ty::FnPtr(..)
1173+
);
1174+
}
1175+
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
1176+
// FIXME: check same pointee?
1177+
check_kinds!(
1178+
op_ty,
1179+
"CastKind::{kind:?} input must be a raw mut pointer, not {:?}",
1180+
ty::RawPtr(_, Mutability::Mut)
1181+
);
1182+
check_kinds!(
1183+
target_type,
1184+
"CastKind::{kind:?} output must be a raw const pointer, not {:?}",
1185+
ty::RawPtr(_, Mutability::Not)
1186+
);
1187+
}
1188+
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
1189+
// FIXME: Check pointee types
1190+
check_kinds!(
1191+
op_ty,
1192+
"CastKind::{kind:?} input must be a raw pointer, not {:?}",
1193+
ty::RawPtr(..)
1194+
);
1195+
check_kinds!(
1196+
target_type,
1197+
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
1198+
ty::RawPtr(..)
1199+
);
1200+
}
1201+
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
1202+
// FIXME: Add Checks for this
1203+
}
11381204
CastKind::IntToInt | CastKind::IntToFloat => {
11391205
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
11401206
let target_valid = target_type.is_numeric() || target_type.is_char();
@@ -1145,10 +1211,29 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11451211
);
11461212
}
11471213
}
1148-
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
1149-
if !(op_ty.is_any_ptr() && target_type.is_unsafe_ptr()) {
1150-
self.fail(location, "Can't cast {op_ty} into 'Ptr'");
1151-
}
1214+
CastKind::FnPtrToPtr => {
1215+
check_kinds!(
1216+
op_ty,
1217+
"CastKind::{kind:?} input must be a fn pointer, not {:?}",
1218+
ty::FnPtr(..)
1219+
);
1220+
check_kinds!(
1221+
target_type,
1222+
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
1223+
ty::RawPtr(..)
1224+
);
1225+
}
1226+
CastKind::PtrToPtr => {
1227+
check_kinds!(
1228+
op_ty,
1229+
"CastKind::{kind:?} input must be a raw pointer, not {:?}",
1230+
ty::RawPtr(..)
1231+
);
1232+
check_kinds!(
1233+
target_type,
1234+
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
1235+
ty::RawPtr(..)
1236+
);
11521237
}
11531238
CastKind::FloatToFloat | CastKind::FloatToInt => {
11541239
if !op_ty.is_floating_point() || !target_type.is_numeric() {

0 commit comments

Comments
 (0)