@@ -605,48 +605,52 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
605605 // However, we don't want to bail early all the time, since the unholdable obligations
606606 // may be interesting for diagnostics (such as trying to coerce `&T` to `&dyn Id<This = U>`),
607607 // so we only bail if there (likely) is another way to convert the types.
608- if !self . infcx . predicate_may_hold ( & root_obligation) {
609- if let Some ( dyn_metadata_adt_def_id) = self . tcx . lang_items ( ) . get ( LangItem :: DynMetadata )
610- && let Some ( metadata_type_def_id) = self . tcx . lang_items ( ) . get ( LangItem :: Metadata )
611- {
612- self . probe ( |_| {
613- let ocx = ObligationCtxt :: new ( & self . infcx ) ;
614-
615- // returns `true` if `<ty as Pointee>::Metadata` is `DynMetadata<_>`
616- let has_dyn_trait_metadata = |ty| {
617- let metadata_ty: Result < _ , _ > = ocx. structurally_normalize_ty (
618- & ObligationCause :: dummy ( ) ,
619- self . fcx . param_env ,
620- Ty :: new_alias (
621- self . tcx ,
622- ty:: AliasTyKind :: Projection ,
623- AliasTy :: new ( self . tcx , metadata_type_def_id, [ ty] ) ,
624- ) ,
625- ) ;
608+ if let & ty:: RawPtr ( source_pointee, _) = coerce_source. kind ( )
609+ && let & ty:: RawPtr ( target_pointee, _) = target. kind ( )
610+ {
611+ if !self . infcx . predicate_may_hold ( & root_obligation) {
612+ if let Some ( dyn_metadata_adt_def_id) =
613+ self . tcx . lang_items ( ) . get ( LangItem :: DynMetadata )
614+ && let Some ( metadata_type_def_id) =
615+ self . tcx . lang_items ( ) . get ( LangItem :: Metadata )
616+ {
617+ self . probe ( |_| {
618+ let ocx = ObligationCtxt :: new ( & self . infcx ) ;
619+
620+ // returns `true` if `<ty as Pointee>::Metadata` is `DynMetadata<_>`
621+ let has_dyn_trait_metadata = |ty| {
622+ let metadata_ty: Result < _ , _ > = ocx. structurally_normalize_ty (
623+ & ObligationCause :: dummy ( ) ,
624+ self . fcx . param_env ,
625+ Ty :: new_alias (
626+ self . tcx ,
627+ ty:: AliasTyKind :: Projection ,
628+ AliasTy :: new ( self . tcx , metadata_type_def_id, [ ty] ) ,
629+ ) ,
630+ ) ;
626631
627- metadata_ty. is_ok_and ( |metadata_ty| {
628- metadata_ty
629- . ty_adt_def ( )
630- . is_some_and ( |d| d. did ( ) == dyn_metadata_adt_def_id)
631- } )
632- } ;
633-
634- // If both types are raw pointers to a (wrapper over a) trait object,
635- // this might be a cast like `*const W<dyn Trait> -> *const dyn Trait`.
636- // So it's better to bail and try that. (even if the cast is not possible, for
637- // example due to vtables not matching, cast diagnostic will likely still be better)
638- //
639- // N.B. use `target`, not `coerce_target` (the latter is a var)
640- if let & ty:: RawPtr ( source_pointee, _) = coerce_source. kind ( )
641- && let & ty:: RawPtr ( target_pointee, _) = target. kind ( )
642- && has_dyn_trait_metadata ( source_pointee)
643- && has_dyn_trait_metadata ( target_pointee)
644- {
645- return Err ( TypeError :: Mismatch ) ;
646- }
632+ metadata_ty. is_ok_and ( |metadata_ty| {
633+ metadata_ty
634+ . ty_adt_def ( )
635+ . is_some_and ( |d| d. did ( ) == dyn_metadata_adt_def_id)
636+ } )
637+ } ;
647638
648- Ok ( ( ) )
649- } ) ?;
639+ // If both types are raw pointers to a (wrapper over a) trait object,
640+ // this might be a cast like `*const W<dyn Trait> -> *const dyn Trait`.
641+ // So it's better to bail and try that. (even if the cast is not possible, for
642+ // example due to vtables not matching, cast diagnostic will likely still be better)
643+ //
644+ // N.B. use `target`, not `coerce_target` (the latter is a var)
645+ if has_dyn_trait_metadata ( source_pointee)
646+ && has_dyn_trait_metadata ( target_pointee)
647+ {
648+ return Err ( TypeError :: Mismatch ) ;
649+ }
650+
651+ Ok ( ( ) )
652+ } ) ?;
653+ }
650654 }
651655 }
652656
0 commit comments