@@ -8,6 +8,7 @@ use rustc_middle::mir::coverage::CoverageKind;
8
8
use rustc_middle:: mir:: interpret:: Scalar ;
9
9
use rustc_middle:: mir:: visit:: { NonUseContext , PlaceContext , Visitor } ;
10
10
use rustc_middle:: mir:: * ;
11
+ use rustc_middle:: ty:: adjustment:: PointerCoercion ;
11
12
use rustc_middle:: ty:: {
12
13
self , CoroutineArgsExt , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitableExt , Variance ,
13
14
} ;
@@ -1134,9 +1135,76 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1134
1135
// FIXME(dyn-star): make sure nothing needs to be done here.
1135
1136
}
1136
1137
// 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
+ }
1140
1208
CastKind :: IntToInt | CastKind :: IntToFloat => {
1141
1209
let input_valid = op_ty. is_integral ( ) || op_ty. is_char ( ) || op_ty. is_bool ( ) ;
1142
1210
let target_valid = target_type. is_numeric ( ) || target_type. is_char ( ) ;
@@ -1147,10 +1215,29 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1147
1215
) ;
1148
1216
}
1149
1217
}
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
+ ) ;
1154
1241
}
1155
1242
CastKind :: FloatToFloat | CastKind :: FloatToInt => {
1156
1243
if !op_ty. is_floating_point ( ) || !target_type. is_numeric ( ) {
0 commit comments