@@ -41,8 +41,8 @@ use rustc_abi::ExternAbi;
4141use  rustc_attr_parsing:: InlineAttr ; 
4242use  rustc_errors:: codes:: * ; 
4343use  rustc_errors:: { Applicability ,  Diag ,  struct_span_code_err} ; 
44+ use  rustc_hir as  hir; 
4445use  rustc_hir:: def_id:: { DefId ,  LocalDefId } ; 
45- use  rustc_hir:: { self  as  hir,  LangItem } ; 
4646use  rustc_hir_analysis:: hir_ty_lowering:: HirTyLowerer ; 
4747use  rustc_infer:: infer:: relate:: RelateResult ; 
4848use  rustc_infer:: infer:: { Coercion ,  DefineOpaqueTypes ,  InferOk ,  InferResult } ; 
@@ -55,7 +55,7 @@ use rustc_middle::ty::adjustment::{
5555    Adjust ,  Adjustment ,  AllowTwoPhase ,  AutoBorrow ,  AutoBorrowMutability ,  PointerCoercion , 
5656} ; 
5757use  rustc_middle:: ty:: error:: TypeError ; 
58- use  rustc_middle:: ty:: { self ,  AliasTy ,   GenericArgsRef ,  Ty ,  TyCtxt ,  TypeVisitableExt } ; 
58+ use  rustc_middle:: ty:: { self ,  GenericArgsRef ,  Ty ,  TyCtxt ,  TypeVisitableExt } ; 
5959use  rustc_span:: { BytePos ,  DUMMY_SP ,  DesugaringKind ,  Span } ; 
6060use  rustc_trait_selection:: infer:: InferCtxtExt  as  _; 
6161use  rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ; 
@@ -592,63 +592,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
592592
593593        // Create an obligation for `Source: CoerceUnsized<Target>`. 
594594        let  cause = self . cause ( self . cause . span ,  ObligationCauseCode :: Coercion  {  source,  target } ) ; 
595-         let  root_obligation = Obligation :: new ( 
596-             self . tcx , 
597-             cause. clone ( ) , 
598-             self . fcx . param_env , 
599-             ty:: TraitRef :: new ( self . tcx ,  coerce_unsized_did,  [ coerce_source,  coerce_target] ) , 
600-         ) ; 
601- 
602-         // If the root `Source: CoerceUnsized<Target>` obligation can't possibly hold, 
603-         // we don't have to assume that this is unsizing coercion (it will always lead to an error) 
604-         // 
605-         // However, we don't want to bail early all the time, since the unholdable obligations 
606-         // may be interesting for diagnostics (such as trying to coerce `&T` to `&dyn Id<This = U>`), 
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-                         ) ; 
626- 
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-                     } 
647- 
648-                     Ok ( ( ) ) 
649-                 } ) ?; 
650-             } 
651-         } 
652595
653596        // Use a FIFO queue for this custom fulfillment procedure. 
654597        // 
@@ -657,7 +600,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
657600        // and almost never more than 3. By using a SmallVec we avoid an 
658601        // allocation, at the (very small) cost of (occasionally) having to 
659602        // shift subsequent elements down when removing the front element. 
660-         let  mut  queue:  SmallVec < [ PredicateObligation < ' tcx > ;  4 ] >  = smallvec ! [ root_obligation] ; 
603+         let  mut  queue:  SmallVec < [ PredicateObligation < ' tcx > ;  4 ] >  = smallvec ! [ Obligation :: new( 
604+             self . tcx, 
605+             cause, 
606+             self . fcx. param_env, 
607+             ty:: TraitRef :: new( self . tcx,  coerce_unsized_did,  [ coerce_source,  coerce_target] ) 
608+         ) ] ; 
661609
662610        // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid 
663611        // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where 
0 commit comments