@@ -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:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitableExt , Variance } ;
12
13
use rustc_middle:: { bug, span_bug} ;
13
14
use rustc_target:: abi:: { Size , FIRST_VARIANT } ;
@@ -1132,9 +1133,74 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1132
1133
// FIXME(dyn-star): make sure nothing needs to be done here.
1133
1134
}
1134
1135
// 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
+ }
1138
1204
CastKind :: IntToInt | CastKind :: IntToFloat => {
1139
1205
let input_valid = op_ty. is_integral ( ) || op_ty. is_char ( ) || op_ty. is_bool ( ) ;
1140
1206
let target_valid = target_type. is_numeric ( ) || target_type. is_char ( ) ;
@@ -1145,10 +1211,29 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1145
1211
) ;
1146
1212
}
1147
1213
}
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
+ ) ;
1152
1237
}
1153
1238
CastKind :: FloatToFloat | CastKind :: FloatToInt => {
1154
1239
if !op_ty. is_floating_point ( ) || !target_type. is_numeric ( ) {
0 commit comments