@@ -34,6 +34,7 @@ use rustc_mir_dataflow::points::DenseLocationMap;
34
34
use rustc_span:: def_id:: CRATE_DEF_ID ;
35
35
use rustc_span:: source_map:: Spanned ;
36
36
use rustc_span:: { Span , sym} ;
37
+ use rustc_trait_selection:: infer:: InferCtxtExt ;
37
38
use rustc_trait_selection:: traits:: query:: type_op:: custom:: scrape_region_constraints;
38
39
use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
39
40
use tracing:: { debug, instrument, trace} ;
@@ -1454,68 +1455,79 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1454
1455
}
1455
1456
CastKind :: PtrToPtr => {
1456
1457
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 ( ) ;
1519
1531
}
1520
1532
}
1521
1533
CastKind :: Transmute => {
0 commit comments