@@ -35,6 +35,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
3535use rustc:: traits:: query:: { Fallible , NoSolution } ;
3636use rustc:: traits:: { self , ObligationCause , PredicateObligations } ;
3737use rustc:: ty:: adjustment:: { PointerCast } ;
38+ use rustc:: ty:: cast:: CastTy ;
3839use rustc:: ty:: fold:: TypeFoldable ;
3940use rustc:: ty:: subst:: { Subst , SubstsRef , GenericArgKind , UserSubsts } ;
4041use rustc:: ty:: {
@@ -2169,72 +2170,125 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21692170 ty_from,
21702171 ty_to,
21712172 terr
2172- )
2173+ ) ;
21732174 }
21742175 }
21752176
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 => {
21842195 span_mirbug ! (
21852196 self ,
21862197 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 {:?}" ,
21892216 ty,
21902217 ) ;
21912218 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- }
22032219 }
2220+ } ;
22042221
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+ }
22362277 }
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+ _ => ( ) ,
22382292 }
22392293 }
22402294 }
0 commit comments