@@ -35,6 +35,7 @@ use rustc_mir_dataflow::points::DenseLocationMap;
3535use rustc_span:: def_id:: CRATE_DEF_ID ;
3636use rustc_span:: source_map:: Spanned ;
3737use rustc_span:: { Span , sym} ;
38+ use rustc_trait_selection:: infer:: InferCtxtExt ;
3839use rustc_trait_selection:: traits:: query:: type_op:: custom:: scrape_region_constraints;
3940use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
4041use tracing:: { debug, instrument, trace} ;
@@ -1473,22 +1474,32 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
14731474 let ty_from = op. ty ( self . body , tcx) ;
14741475 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
14751476 let cast_ty_to = CastTy :: from_ty ( * ty) ;
1477+
14761478 match ( cast_ty_from, cast_ty_to) {
14771479 ( Some ( CastTy :: Ptr ( src) ) , Some ( CastTy :: Ptr ( dst) ) ) => {
1478- let src_tail = self . struct_tail ( src. ty , location) ;
1479- let dst_tail = self . struct_tail ( dst. ty , location) ;
1480-
1481- // This checks (lifetime part of) vtable validity for pointer casts,
1482- // which is irrelevant when there are aren't principal traits on
1483- // both sides (aka only auto traits).
1484- //
1485- // Note that other checks (such as denying `dyn Send` -> `dyn
1486- // Debug`) are in `rustc_hir_typeck`.
1487- if let ty:: Dynamic ( src_tty, _src_lt, ty:: Dyn ) = * src_tail. kind ( )
1488- && let ty:: Dynamic ( dst_tty, dst_lt, ty:: Dyn ) = * dst_tail. kind ( )
1480+ if self
1481+ . infcx
1482+ . type_is_sized_modulo_regions ( self . infcx . param_env , dst. ty )
1483+ {
1484+ // Wide to thin ptr cast. This may even occur in an env with
1485+ // impossible predicates, such as `where dyn Trait: Sized`.
1486+ // In this case, we don't want to fall into the case below,
1487+ // since the types may not actually be equatable, but it's
1488+ // fine to perform this operation in an impossible env.
1489+ } else if let ty:: Dynamic ( src_tty, _src_lt, ty:: Dyn ) =
1490+ * self . struct_tail ( src. ty , location) . kind ( )
1491+ && let ty:: Dynamic ( dst_tty, dst_lt, ty:: Dyn ) =
1492+ * self . struct_tail ( dst. ty , location) . kind ( )
14891493 && src_tty. principal ( ) . is_some ( )
14901494 && dst_tty. principal ( ) . is_some ( )
14911495 {
1496+ // This checks (lifetime part of) vtable validity for pointer casts,
1497+ // which is irrelevant when there are aren't principal traits on
1498+ // both sides (aka only auto traits).
1499+ //
1500+ // Note that other checks (such as denying `dyn Send` -> `dyn
1501+ // Debug`) are in `rustc_hir_typeck`.
1502+
14921503 // Remove auto traits.
14931504 // Auto trait checks are handled in `rustc_hir_typeck` as FCW.
14941505 let src_obj = Ty :: new_dynamic (
0 commit comments