@@ -1587,23 +1587,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15871587 self . ty_to_value_string ( rcvr_ty. peel_refs ( ) )
15881588 } ;
15891589 if let SelfSource :: MethodCall ( _) = source {
1590- let first_arg = if let Some ( CandidateSource :: Impl ( impl_did) ) = static_candidates. get ( 0 )
1591- && let Some ( assoc) = self . associated_value ( * impl_did, item_name)
1592- && assoc. kind == ty:: AssocKind :: Fn
1593- {
1590+ let first_arg = static_candidates. get ( 0 ) . and_then ( |candidate_source| {
1591+ let ( assoc_did, impl_ty) = match candidate_source {
1592+ CandidateSource :: Impl ( impl_did) => {
1593+ ( * impl_did, self . tcx . type_of ( * impl_did) . instantiate_identity ( ) )
1594+ }
1595+ CandidateSource :: Trait ( trait_did) => ( * trait_did, rcvr_ty) ,
1596+ } ;
1597+
1598+ let assoc = self . associated_value ( assoc_did, item_name) ?;
1599+ if assoc. kind != ty:: AssocKind :: Fn {
1600+ return None ;
1601+ }
1602+
1603+ // for CandidateSource::Impl, `Self` will be instantiated to a concrete type
1604+ // but for CandidateSource::Trait, `Self` is still `Self`
15941605 let sig = self . tcx . fn_sig ( assoc. def_id ) . instantiate_identity ( ) ;
15951606 sig. inputs ( ) . skip_binder ( ) . get ( 0 ) . and_then ( |first| {
1596- let impl_ty = self . tcx . type_of ( * impl_did) . instantiate_identity ( ) ;
15971607 // if the type of first arg is the same as the current impl type, we should take the first arg into assoc function
1598- if first. peel_refs ( ) == impl_ty {
1608+ let first_ty = first. peel_refs ( ) ;
1609+ if first_ty == impl_ty || first_ty == self . tcx . types . self_param {
15991610 Some ( first. ref_mutability ( ) . map_or ( "" , |mutbl| mutbl. ref_prefix_str ( ) ) )
16001611 } else {
16011612 None
16021613 }
16031614 } )
1604- } else {
1605- None
1606- } ;
1615+ } ) ;
1616+
16071617 let mut applicability = Applicability :: MachineApplicable ;
16081618 let args = if let SelfSource :: MethodCall ( receiver) = source
16091619 && let Some ( args) = args
0 commit comments