@@ -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 > ,
@@ -474,11 +498,9 @@ fn implemented_method<'tcx>(
474498 trait_method = tcx. associated_item ( method_id) ;
475499 trait_id = trait_ref. skip_binder ( ) . def_id ;
476500 impl_id
477- } else if let InstanceKind :: Item ( def_id) = instance. def
478- && let Some ( trait_method_bound) = tcx. opt_associated_item ( def_id)
479- {
480- // Provided method in a `trait` block
481- trait_method = trait_method_bound;
501+ } else if let Some ( trait_method_def_id) = default_or_shim ( tcx, instance) {
502+ // Provided method in a `trait` block or a synthetic `shim`
503+ trait_method = tcx. associated_item ( trait_method_def_id) ;
482504 method_id = instance. def_id ( ) ;
483505 trait_id = tcx. trait_of_assoc ( method_id) ?;
484506 trait_ref = ty:: EarlyBinder :: bind ( TraitRef :: from_method ( tcx, trait_id, instance. args ) ) ;
0 commit comments