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