@@ -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