@@ -10,9 +10,8 @@ use rustc_hir as hir;
1010use rustc_hir:: LangItem ;
1111use rustc_middle:: bug;
1212use rustc_middle:: ty:: {
13- self , AssocContainer , ExistentialPredicateStableCmpExt as _, Instance , InstanceKind , IntTy ,
14- List , TraitRef , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
15- UintTy ,
13+ self , AssocContainer , ExistentialPredicateStableCmpExt as _, Instance , IntTy , List , TraitRef ,
14+ Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt , UintTy ,
1615} ;
1716use rustc_span:: def_id:: DefId ;
1817use rustc_span:: { DUMMY_SP , sym} ;
@@ -459,6 +458,30 @@ pub(crate) fn transform_instance<'tcx>(
459458 instance
460459}
461460
461+ fn default_or_shim < ' tcx > ( tcx : TyCtxt < ' tcx > , instance : Instance < ' tcx > ) -> Option < DefId > {
462+ match instance. def {
463+ ty:: InstanceKind :: Item ( def_id) | ty:: InstanceKind :: FnPtrShim ( def_id, _) => {
464+ tcx. opt_associated_item ( def_id) . map ( |item| item. def_id )
465+ }
466+ _ => None ,
467+ }
468+ }
469+
470+ /// Determines if an instance represents a trait method implementation and returns the necessary
471+ /// information for type erasure.
472+ ///
473+ /// This function handles two main cases:
474+ ///
475+ /// * **Implementation in an `impl` block**: When the instance represents a concrete implementation
476+ /// of a trait method in an `impl` block, it extracts the trait reference, method ID, and trait
477+ /// ID from the implementation. The method ID is obtained from the `trait_item_def_id` field of
478+ /// the associated item, which points to the original trait method definition.
479+ ///
480+ /// * **Provided method in a `trait` block or synthetic `shim`**: When the instance represents a
481+ /// default implementation provided in the trait definition itself or a synthetic shim, it uses
482+ /// the instance's own `def_id` as the method ID and determines the trait ID from the associated
483+ /// item.
484+ ///
462485fn implemented_method < ' tcx > (
463486 tcx : TyCtxt < ' tcx > ,
464487 instance : Instance < ' tcx > ,
@@ -476,10 +499,11 @@ fn implemented_method<'tcx>(
476499 trait_id = trait_ref. skip_binder ( ) . def_id ;
477500 impl_id
478501 } else if let AssocContainer :: Trait = assoc. container
479- && let InstanceKind :: Item ( def_id ) = instance. def
502+ && let Some ( trait_method_def_id ) = default_or_shim ( tcx , instance)
480503 {
504+ // Provided method in a `trait` block or a synthetic `shim`
481505 trait_method = assoc;
482- method_id = def_id ;
506+ method_id = trait_method_def_id ;
483507 trait_id = tcx. parent ( method_id) ;
484508 trait_ref = ty:: EarlyBinder :: bind ( TraitRef :: from_assoc ( tcx, trait_id, instance. args ) ) ;
485509 trait_id
0 commit comments