@@ -1456,78 +1456,79 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1456
1456
}
1457
1457
CastKind :: PtrToPtr => {
1458
1458
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
+ } ;
1461
1465
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 ( ) ;
1531
1532
}
1532
1533
}
1533
1534
CastKind :: Transmute => {
0 commit comments