@@ -10,8 +10,8 @@ use rustc_hir as hir;
1010use rustc_hir:: LangItem ;
1111use rustc_middle:: bug;
1212use rustc_middle:: ty:: {
13- self , ExistentialPredicateStableCmpExt as _, Instance , InstanceKind , IntTy , List , TraitRef , Ty ,
14- TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt , UintTy ,
13+ self , ExistentialPredicateStableCmpExt as _, Instance , IntTy , List , TraitRef , Ty , TyCtxt ,
14+ TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt , UintTy ,
1515} ;
1616use rustc_span:: def_id:: DefId ;
1717use rustc_span:: { DUMMY_SP , sym} ;
@@ -458,6 +458,30 @@ pub(crate) fn transform_instance<'tcx>(
458458 instance
459459}
460460
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+ ///
461485fn implemented_method < ' tcx > (
462486 tcx : TyCtxt < ' tcx > ,
463487 instance : Instance < ' tcx > ,
@@ -473,11 +497,9 @@ fn implemented_method<'tcx>(
473497 trait_method = tcx. associated_item ( method_id) ;
474498 trait_id = trait_ref. skip_binder ( ) . def_id ;
475499 impl_id
476- } else if let InstanceKind :: Item ( def_id) = instance. def
477- && let Some ( trait_method_bound) = tcx. opt_associated_item ( def_id)
478- {
479- // Provided method in a `trait` block
480- trait_method = trait_method_bound;
500+ } else if let Some ( trait_method_def_id) = default_or_shim ( tcx, instance) {
501+ // Provided method in a `trait` block or a synthetic `shim`
502+ trait_method = tcx. associated_item ( trait_method_def_id) ;
481503 method_id = instance. def_id ( ) ;
482504 trait_id = tcx. trait_of_assoc ( method_id) ?;
483505 trait_ref = ty:: EarlyBinder :: bind ( TraitRef :: from_assoc ( tcx, trait_id, instance. args ) ) ;
0 commit comments