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