@@ -36,6 +36,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
36
36
use rustc:: traits:: query:: { Fallible , NoSolution } ;
37
37
use rustc:: traits:: { self , ObligationCause , PredicateObligations } ;
38
38
use rustc:: ty:: adjustment:: { PointerCast } ;
39
+ use rustc:: ty:: cast:: CastTy ;
39
40
use rustc:: ty:: fold:: TypeFoldable ;
40
41
use rustc:: ty:: subst:: { Subst , SubstsRef , GenericArgKind , UserSubsts } ;
41
42
use rustc:: ty:: {
@@ -2177,72 +2178,125 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2177
2178
ty_from,
2178
2179
ty_to,
2179
2180
terr
2180
- )
2181
+ ) ;
2181
2182
}
2182
2183
}
2183
2184
2184
- CastKind :: Misc => {
2185
- if let ty:: Ref ( _, mut ty_from, _) = op. ty ( body, tcx) . kind {
2186
- let ( mut ty_to, mutability) = if let ty:: RawPtr ( ty:: TypeAndMut {
2187
- ty : ty_to,
2188
- mutbl,
2189
- } ) = ty. kind {
2190
- ( ty_to, mutbl)
2191
- } else {
2185
+ CastKind :: Pointer ( PointerCast :: ArrayToPointer ) => {
2186
+ let ty_from = op. ty ( body, tcx) ;
2187
+
2188
+ let opt_ty_elem = match ty_from. kind {
2189
+ ty:: RawPtr (
2190
+ ty:: TypeAndMut { mutbl : hir:: MutImmutable , ty : array_ty }
2191
+ ) => {
2192
+ match array_ty. kind {
2193
+ ty:: Array ( ty_elem, _) => Some ( ty_elem) ,
2194
+ _ => None ,
2195
+ }
2196
+ }
2197
+ _ => None ,
2198
+ } ;
2199
+
2200
+ let ty_elem = match opt_ty_elem {
2201
+ Some ( ty_elem) => ty_elem,
2202
+ None => {
2192
2203
span_mirbug ! (
2193
2204
self ,
2194
2205
rvalue,
2195
- "invalid cast types {:?} -> {:?}" ,
2196
- op. ty( body, tcx) ,
2206
+ "ArrayToPointer cast from unexpected type {:?}" ,
2207
+ ty_from,
2208
+ ) ;
2209
+ return ;
2210
+ }
2211
+ } ;
2212
+
2213
+ let ty_to = match ty. kind {
2214
+ ty:: RawPtr (
2215
+ ty:: TypeAndMut { mutbl : hir:: MutImmutable , ty : ty_to }
2216
+ ) => {
2217
+ ty_to
2218
+ }
2219
+ _ => {
2220
+ span_mirbug ! (
2221
+ self ,
2222
+ rvalue,
2223
+ "ArrayToPointer cast to unexpected type {:?}" ,
2197
2224
ty,
2198
2225
) ;
2199
2226
return ;
2200
- } ;
2201
-
2202
- // Handle the direct cast from `&[T; N]` to `*const T` by unwrapping
2203
- // any array we find.
2204
- while let ty:: Array ( ty_elem_from, _) = ty_from. kind {
2205
- ty_from = ty_elem_from;
2206
- if let ty:: Array ( ty_elem_to, _) = ty_to. kind {
2207
- ty_to = ty_elem_to;
2208
- } else {
2209
- break ;
2210
- }
2211
2227
}
2228
+ } ;
2212
2229
2213
- if let hir:: MutMutable = mutability {
2214
- if let Err ( terr) = self . eq_types (
2215
- ty_from,
2216
- ty_to,
2217
- location. to_locations ( ) ,
2218
- ConstraintCategory :: Cast ,
2219
- ) {
2220
- span_mirbug ! (
2221
- self ,
2222
- rvalue,
2223
- "equating {:?} with {:?} yields {:?}" ,
2224
- ty_from,
2225
- ty_to,
2226
- terr
2227
- )
2228
- }
2229
- } else {
2230
- if let Err ( terr) = self . sub_types (
2231
- ty_from,
2232
- ty_to,
2233
- location. to_locations ( ) ,
2234
- ConstraintCategory :: Cast ,
2235
- ) {
2236
- span_mirbug ! (
2237
- self ,
2238
- rvalue,
2239
- "relating {:?} with {:?} yields {:?}" ,
2240
- ty_from,
2241
- ty_to,
2242
- terr
2243
- )
2230
+ if let Err ( terr) = self . sub_types (
2231
+ ty_elem,
2232
+ ty_to,
2233
+ location. to_locations ( ) ,
2234
+ ConstraintCategory :: Cast ,
2235
+ ) {
2236
+ span_mirbug ! (
2237
+ self ,
2238
+ rvalue,
2239
+ "relating {:?} with {:?} yields {:?}" ,
2240
+ ty_elem,
2241
+ ty_to,
2242
+ terr
2243
+ )
2244
+ }
2245
+ }
2246
+
2247
+ CastKind :: Misc => {
2248
+ let ty_from = op. ty ( body, tcx) ;
2249
+ let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2250
+ let cast_ty_to = CastTy :: from_ty ( ty) ;
2251
+ match ( cast_ty_from, cast_ty_to) {
2252
+ ( Some ( CastTy :: RPtr ( ref_tm) ) , Some ( CastTy :: Ptr ( ptr_tm) ) ) => {
2253
+ if let hir:: MutMutable = ptr_tm. mutbl {
2254
+ if let Err ( terr) = self . eq_types (
2255
+ ref_tm. ty ,
2256
+ ptr_tm. ty ,
2257
+ location. to_locations ( ) ,
2258
+ ConstraintCategory :: Cast ,
2259
+ ) {
2260
+ span_mirbug ! (
2261
+ self ,
2262
+ rvalue,
2263
+ "equating {:?} with {:?} yields {:?}" ,
2264
+ ref_tm. ty,
2265
+ ptr_tm. ty,
2266
+ terr
2267
+ )
2268
+ }
2269
+ } else {
2270
+ if let Err ( terr) = self . sub_types (
2271
+ ref_tm. ty ,
2272
+ ptr_tm. ty ,
2273
+ location. to_locations ( ) ,
2274
+ ConstraintCategory :: Cast ,
2275
+ ) {
2276
+ span_mirbug ! (
2277
+ self ,
2278
+ rvalue,
2279
+ "relating {:?} with {:?} yields {:?}" ,
2280
+ ref_tm. ty,
2281
+ ptr_tm. ty,
2282
+ terr
2283
+ )
2284
+ }
2244
2285
}
2245
- }
2286
+ } ,
2287
+ ( None , _)
2288
+ | ( _, None )
2289
+ | ( _, Some ( CastTy :: FnPtr ) )
2290
+ | ( Some ( CastTy :: Float ) , Some ( CastTy :: Ptr ( _) ) )
2291
+ | ( Some ( CastTy :: Ptr ( _) ) , Some ( CastTy :: Float ) )
2292
+ | ( Some ( CastTy :: FnPtr ) , Some ( CastTy :: Float ) ) => span_mirbug ! (
2293
+ self ,
2294
+ rvalue,
2295
+ "Invalid cast {:?} -> {:?}" ,
2296
+ ty_from,
2297
+ ty,
2298
+ ) ,
2299
+ _ => ( ) ,
2246
2300
}
2247
2301
}
2248
2302
}
0 commit comments