@@ -34,6 +34,7 @@ use rustc_mir_dataflow::points::DenseLocationMap;
3434use rustc_span:: def_id:: CRATE_DEF_ID ;
3535use rustc_span:: source_map:: Spanned ;
3636use rustc_span:: { Span , sym} ;
37+ use rustc_trait_selection:: infer:: InferCtxtExt ;
3738use rustc_trait_selection:: traits:: query:: type_op:: custom:: scrape_region_constraints;
3839use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
3940use tracing:: { debug, instrument, trace} ;
@@ -1457,22 +1458,32 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
14571458 let ty_from = op. ty ( self . body , tcx) ;
14581459 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
14591460 let cast_ty_to = CastTy :: from_ty ( * ty) ;
1461+
14601462 match ( cast_ty_from, cast_ty_to) {
14611463 ( Some ( CastTy :: Ptr ( src) ) , Some ( CastTy :: Ptr ( dst) ) ) => {
1462- let src_tail = self . struct_tail ( src. ty , location) ;
1463- let dst_tail = self . struct_tail ( dst. ty , location) ;
1464-
1465- // This checks (lifetime part of) vtable validity for pointer casts,
1466- // which is irrelevant when there are aren't principal traits on
1467- // both sides (aka only auto traits).
1468- //
1469- // Note that other checks (such as denying `dyn Send` -> `dyn
1470- // Debug`) are in `rustc_hir_typeck`.
1471- if let ty:: Dynamic ( src_tty, _src_lt, ty:: Dyn ) = * src_tail. kind ( )
1472- && let ty:: Dynamic ( dst_tty, dst_lt, ty:: Dyn ) = * dst_tail. kind ( )
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 ( )
14731477 && src_tty. principal ( ) . is_some ( )
14741478 && dst_tty. principal ( ) . is_some ( )
14751479 {
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+
14761487 // Remove auto traits.
14771488 // Auto trait checks are handled in `rustc_hir_typeck` as FCW.
14781489 let src_obj = Ty :: new_dynamic (
0 commit comments