@@ -605,48 +605,52 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
605
605
// However, we don't want to bail early all the time, since the unholdable obligations
606
606
// may be interesting for diagnostics (such as trying to coerce `&T` to `&dyn Id<This = U>`),
607
607
// 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
+ ) ;
626
631
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
+ } ;
647
638
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
+ }
650
654
}
651
655
}
652
656
0 commit comments