Skip to content

Commit 30dc2ba

Browse files
Rollup merge of #125851 - scottmcm:moar-validate, r=compiler-errors
Add some more specific checks to the MIR validator None of the `PointerCoercion`s had any checks, so while there's probably more that could be done here, hopefully these are better than the previous nothing. r? mir
2 parents 0722c94 + 11d6f18 commit 30dc2ba

File tree

1 file changed

+94
-7
lines changed

1 file changed

+94
-7
lines changed

compiler/rustc_mir_transform/src/validate.rs

+94-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::{
1213
self, CoroutineArgsExt, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance,
1314
};
@@ -1134,9 +1135,76 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11341135
// FIXME(dyn-star): make sure nothing needs to be done here.
11351136
}
11361137
// FIXME: Add Checks for these
1137-
CastKind::PointerWithExposedProvenance
1138-
| CastKind::PointerExposeProvenance
1139-
| CastKind::PointerCoercion(_) => {}
1138+
CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {}
1139+
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
1140+
// FIXME: check signature compatibility.
1141+
check_kinds!(
1142+
op_ty,
1143+
"CastKind::{kind:?} input must be a fn item, not {:?}",
1144+
ty::FnDef(..)
1145+
);
1146+
check_kinds!(
1147+
target_type,
1148+
"CastKind::{kind:?} output must be a fn pointer, not {:?}",
1149+
ty::FnPtr(..)
1150+
);
1151+
}
1152+
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
1153+
// FIXME: check safety and signature compatibility.
1154+
check_kinds!(
1155+
op_ty,
1156+
"CastKind::{kind:?} input must be a fn pointer, not {:?}",
1157+
ty::FnPtr(..)
1158+
);
1159+
check_kinds!(
1160+
target_type,
1161+
"CastKind::{kind:?} output must be a fn pointer, not {:?}",
1162+
ty::FnPtr(..)
1163+
);
1164+
}
1165+
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => {
1166+
// FIXME: check safety, captures, and signature compatibility.
1167+
check_kinds!(
1168+
op_ty,
1169+
"CastKind::{kind:?} input must be a closure, not {:?}",
1170+
ty::Closure(..)
1171+
);
1172+
check_kinds!(
1173+
target_type,
1174+
"CastKind::{kind:?} output must be a fn pointer, not {:?}",
1175+
ty::FnPtr(..)
1176+
);
1177+
}
1178+
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
1179+
// FIXME: check same pointee?
1180+
check_kinds!(
1181+
op_ty,
1182+
"CastKind::{kind:?} input must be a raw mut pointer, not {:?}",
1183+
ty::RawPtr(_, Mutability::Mut)
1184+
);
1185+
check_kinds!(
1186+
target_type,
1187+
"CastKind::{kind:?} output must be a raw const pointer, not {:?}",
1188+
ty::RawPtr(_, Mutability::Not)
1189+
);
1190+
}
1191+
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
1192+
// FIXME: Check pointee types
1193+
check_kinds!(
1194+
op_ty,
1195+
"CastKind::{kind:?} input must be a raw pointer, not {:?}",
1196+
ty::RawPtr(..)
1197+
);
1198+
check_kinds!(
1199+
target_type,
1200+
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
1201+
ty::RawPtr(..)
1202+
);
1203+
}
1204+
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
1205+
// This is used for all `CoerceUnsized` types,
1206+
// not just pointers/references, so is hard to check.
1207+
}
11401208
CastKind::IntToInt | CastKind::IntToFloat => {
11411209
let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
11421210
let target_valid = target_type.is_numeric() || target_type.is_char();
@@ -1147,10 +1215,29 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11471215
);
11481216
}
11491217
}
1150-
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
1151-
if !(op_ty.is_any_ptr() && target_type.is_unsafe_ptr()) {
1152-
self.fail(location, "Can't cast {op_ty} into 'Ptr'");
1153-
}
1218+
CastKind::FnPtrToPtr => {
1219+
check_kinds!(
1220+
op_ty,
1221+
"CastKind::{kind:?} input must be a fn pointer, not {:?}",
1222+
ty::FnPtr(..)
1223+
);
1224+
check_kinds!(
1225+
target_type,
1226+
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
1227+
ty::RawPtr(..)
1228+
);
1229+
}
1230+
CastKind::PtrToPtr => {
1231+
check_kinds!(
1232+
op_ty,
1233+
"CastKind::{kind:?} input must be a raw pointer, not {:?}",
1234+
ty::RawPtr(..)
1235+
);
1236+
check_kinds!(
1237+
target_type,
1238+
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
1239+
ty::RawPtr(..)
1240+
);
11541241
}
11551242
CastKind::FloatToFloat | CastKind::FloatToInt => {
11561243
if !op_ty.is_floating_point() || !target_type.is_numeric() {

0 commit comments

Comments
 (0)