@@ -8,6 +8,7 @@ use rustc_middle::mir::coverage::CoverageKind;
88use rustc_middle:: mir:: interpret:: Scalar ;
99use rustc_middle:: mir:: visit:: { NonUseContext , PlaceContext , Visitor } ;
1010use rustc_middle:: mir:: * ;
11+ use rustc_middle:: ty:: adjustment:: PointerCoercion ;
1112use 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