@@ -1456,78 +1456,79 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
14561456                    } 
14571457                    CastKind :: PtrToPtr  => { 
14581458                        let  ty_from = op. ty ( self . body ,  tcx) ; 
1459-                         let  cast_ty_from = CastTy :: from_ty ( ty_from) ; 
1460-                         let  cast_ty_to = CastTy :: from_ty ( * ty) ; 
1459+                         let  Some ( CastTy :: Ptr ( src) )  = CastTy :: from_ty ( ty_from)  else  { 
1460+                             unreachable ! ( ) ; 
1461+                         } ; 
1462+                         let  Some ( CastTy :: Ptr ( dst) )  = CastTy :: from_ty ( * ty)  else  { 
1463+                             unreachable ! ( ) ; 
1464+                         } ; 
14611465
1462-                         match  ( cast_ty_from,  cast_ty_to)  { 
1463-                             ( Some ( CastTy :: Ptr ( src) ) ,  Some ( CastTy :: Ptr ( dst) ) )  => { 
1464-                                 if  self 
1465-                                     . infcx 
1466-                                     . type_is_sized_modulo_regions ( self . infcx . param_env ,  dst. ty ) 
1467-                                 { 
1468-                                     // Wide to thin ptr cast. This may even occur in an env with 
1469-                                     // impossible predicates, such as `where dyn Trait: Sized`. 
1470-                                     // In this case, we don't want to fall into the case below, 
1471-                                     // since the types may not actually be equatable, but it's 
1472-                                     // fine to perform this operation in an impossible env. 
1473-                                 }  else  if  let  ty:: Dynamic ( src_tty,  _src_lt,  ty:: Dyn )  =
1474-                                     * self . struct_tail ( src. ty ,  location) . kind ( ) 
1475-                                     && let  ty:: Dynamic ( dst_tty,  dst_lt,  ty:: Dyn )  =
1476-                                         * self . struct_tail ( dst. ty ,  location) . kind ( ) 
1477-                                     && src_tty. principal ( ) . is_some ( ) 
1478-                                     && dst_tty. principal ( ) . is_some ( ) 
1479-                                 { 
1480-                                     // This checks (lifetime part of) vtable validity for pointer casts, 
1481-                                     // which is irrelevant when there are aren't principal traits on 
1482-                                     // both sides (aka only auto traits). 
1483-                                     // 
1484-                                     // Note that other checks (such as denying `dyn Send` -> `dyn 
1485-                                     // Debug`) are in `rustc_hir_typeck`. 
1486- 
1487-                                     // Remove auto traits. 
1488-                                     // Auto trait checks are handled in `rustc_hir_typeck` as FCW. 
1489-                                     let  src_obj = Ty :: new_dynamic ( 
1490-                                         tcx, 
1491-                                         tcx. mk_poly_existential_predicates ( 
1492-                                             & src_tty. without_auto_traits ( ) . collect :: < Vec < _ > > ( ) , 
1493-                                         ) , 
1494-                                         // FIXME: Once we disallow casting `*const dyn Trait + 'short` 
1495-                                         // to `*const dyn Trait + 'long`, then this can just be `src_lt`. 
1496-                                         dst_lt, 
1497-                                         ty:: Dyn , 
1498-                                     ) ; 
1499-                                     let  dst_obj = Ty :: new_dynamic ( 
1500-                                         tcx, 
1501-                                         tcx. mk_poly_existential_predicates ( 
1502-                                             & dst_tty. without_auto_traits ( ) . collect :: < Vec < _ > > ( ) , 
1503-                                         ) , 
1504-                                         dst_lt, 
1505-                                         ty:: Dyn , 
1506-                                     ) ; 
1507- 
1508-                                     debug ! ( ?src_tty,  ?dst_tty,  ?src_obj,  ?dst_obj) ; 
1509- 
1510-                                     self . sub_types ( 
1511-                                         src_obj, 
1512-                                         dst_obj, 
1513-                                         location. to_locations ( ) , 
1514-                                         ConstraintCategory :: Cast  { 
1515-                                             is_implicit_coercion :  false , 
1516-                                             unsize_to :  None , 
1517-                                         } , 
1518-                                     ) 
1519-                                     . unwrap ( ) ; 
1520-                                 } 
1521-                             } 
1522-                             _ => { 
1523-                                 span_mirbug ! ( 
1524-                                     self , 
1525-                                     rvalue, 
1526-                                     "Invalid PtrToPtr cast {:?} -> {:?}" , 
1527-                                     ty_from, 
1528-                                     ty
1529-                                 ) 
1530-                             } 
1466+                         if  self . infcx . type_is_sized_modulo_regions ( self . infcx . param_env ,  dst. ty )  { 
1467+                             // Wide to thin ptr cast. This may even occur in an env with 
1468+                             // impossible predicates, such as `where dyn Trait: Sized`. 
1469+                             // In this case, we don't want to fall into the case below, 
1470+                             // since the types may not actually be equatable, but it's 
1471+                             // fine to perform this operation in an impossible env. 
1472+                             let  trait_ref = ty:: TraitRef :: new ( 
1473+                                 tcx, 
1474+                                 tcx. require_lang_item ( LangItem :: Sized ,  self . last_span ) , 
1475+                                 [ dst. ty ] , 
1476+                             ) ; 
1477+                             self . prove_trait_ref ( 
1478+                                 trait_ref, 
1479+                                 location. to_locations ( ) , 
1480+                                 ConstraintCategory :: Cast  { 
1481+                                     is_implicit_coercion :  true , 
1482+                                     unsize_to :  None , 
1483+                                 } , 
1484+                             ) ; 
1485+                         }  else  if  let  ty:: Dynamic ( src_tty,  _src_lt,  ty:: Dyn )  =
1486+                             * self . struct_tail ( src. ty ,  location) . kind ( ) 
1487+                             && let  ty:: Dynamic ( dst_tty,  dst_lt,  ty:: Dyn )  =
1488+                                 * self . struct_tail ( dst. ty ,  location) . kind ( ) 
1489+                             && src_tty. principal ( ) . is_some ( ) 
1490+                             && dst_tty. principal ( ) . is_some ( ) 
1491+                         { 
1492+                             // This checks (lifetime part of) vtable validity for pointer casts, 
1493+                             // which is irrelevant when there are aren't principal traits on 
1494+                             // both sides (aka only auto traits). 
1495+                             // 
1496+                             // Note that other checks (such as denying `dyn Send` -> `dyn 
1497+                             // Debug`) are in `rustc_hir_typeck`. 
1498+ 
1499+                             // Remove auto traits. 
1500+                             // Auto trait checks are handled in `rustc_hir_typeck` as FCW. 
1501+                             let  src_obj = Ty :: new_dynamic ( 
1502+                                 tcx, 
1503+                                 tcx. mk_poly_existential_predicates ( 
1504+                                     & src_tty. without_auto_traits ( ) . collect :: < Vec < _ > > ( ) , 
1505+                                 ) , 
1506+                                 // FIXME: Once we disallow casting `*const dyn Trait + 'short` 
1507+                                 // to `*const dyn Trait + 'long`, then this can just be `src_lt`. 
1508+                                 dst_lt, 
1509+                                 ty:: Dyn , 
1510+                             ) ; 
1511+                             let  dst_obj = Ty :: new_dynamic ( 
1512+                                 tcx, 
1513+                                 tcx. mk_poly_existential_predicates ( 
1514+                                     & dst_tty. without_auto_traits ( ) . collect :: < Vec < _ > > ( ) , 
1515+                                 ) , 
1516+                                 dst_lt, 
1517+                                 ty:: Dyn , 
1518+                             ) ; 
1519+ 
1520+                             debug ! ( ?src_tty,  ?dst_tty,  ?src_obj,  ?dst_obj) ; 
1521+ 
1522+                             self . sub_types ( 
1523+                                 src_obj, 
1524+                                 dst_obj, 
1525+                                 location. to_locations ( ) , 
1526+                                 ConstraintCategory :: Cast  { 
1527+                                     is_implicit_coercion :  false , 
1528+                                     unsize_to :  None , 
1529+                                 } , 
1530+                             ) 
1531+                             . unwrap ( ) ; 
15311532                        } 
15321533                    } 
15331534                    CastKind :: Transmute  => { 
0 commit comments