@@ -36,6 +36,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
3636use rustc:: traits:: query:: { Fallible , NoSolution } ;
3737use rustc:: traits:: { self , ObligationCause , PredicateObligations } ;
3838use rustc:: ty:: adjustment:: { PointerCast } ;
39+ use rustc:: ty:: cast:: CastTy ;
3940use rustc:: ty:: fold:: TypeFoldable ;
4041use rustc:: ty:: subst:: { Subst , SubstsRef , GenericArgKind , UserSubsts } ;
4142use rustc:: ty:: {
@@ -2177,72 +2178,125 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21772178 ty_from,
21782179 ty_to,
21792180 terr
2180- )
2181+ ) ;
21812182 }
21822183 }
21832184
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 => {
21922203 span_mirbug ! (
21932204 self ,
21942205 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 {:?}" ,
21972224 ty,
21982225 ) ;
21992226 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- }
22112227 }
2228+ } ;
22122229
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+ }
22442285 }
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+ _ => ( ) ,
22462300 }
22472301 }
22482302 }
0 commit comments