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