@@ -21,8 +21,8 @@ use hir_def::{
2121 path:: { ModPath , Path , PathKind } ,
2222 resolver:: { resolver_for_scope, Resolver , TypeNs , ValueNs } ,
2323 type_ref:: Mutability ,
24- AsMacroCall , DefWithBodyId , FieldId , FunctionId , ItemContainerId , LocalFieldId , Lookup ,
25- ModuleDefId , VariantId ,
24+ AsMacroCall , AssocItemId , DefWithBodyId , FieldId , FunctionId , ItemContainerId , LocalFieldId ,
25+ Lookup , ModuleDefId , VariantId ,
2626} ;
2727use hir_expand:: {
2828 builtin_fn_macro:: BuiltinFnLikeExpander , hygiene:: Hygiene , name:: AsName , HirFileId , InFile ,
@@ -245,55 +245,9 @@ impl SourceAnalyzer {
245245 call : & ast:: MethodCallExpr ,
246246 ) -> Option < ( FunctionId , Substitution ) > {
247247 let expr_id = self . expr_id ( db, & call. clone ( ) . into ( ) ) ?;
248- self . infer . as_ref ( ) ?. method_resolution ( expr_id)
249- }
250-
251- pub ( crate ) fn resolve_impl_method (
252- & self ,
253- db : & dyn HirDatabase ,
254- call : & ast:: Expr ,
255- ) -> Option < FunctionId > {
256- let infered = self . infer . as_ref ( ) ?;
257- let expr_id = self . expr_id ( db, call) ?;
258-
259- let mut fun_info = None ;
260- match call {
261- & ast:: Expr :: MethodCallExpr ( ..) => {
262- let ( func, subs) = infered. method_resolution ( expr_id) ?;
263- if subs. is_empty ( Interner ) {
264- return None ;
265- }
266- fun_info. replace ( ( func, subs. at ( Interner , 0 ) . ty ( Interner ) ?. clone ( ) ) ) ;
267- }
268- & ast:: Expr :: PathExpr ( ..) => {
269- let func_ty = infered. type_of_expr . get ( expr_id) ?;
270- if let TyKind :: FnDef ( fn_def, subs) = func_ty. kind ( Interner ) {
271- if subs. is_empty ( Interner ) {
272- return None ;
273- }
274- if let hir_ty:: CallableDefId :: FunctionId ( f_id) =
275- db. lookup_intern_callable_def ( fn_def. clone ( ) . into ( ) )
276- {
277- fun_info. replace ( ( f_id, subs. at ( Interner , 0 ) . ty ( Interner ) ?. clone ( ) ) ) ;
278- }
279- }
280- }
281- _ => ( ) ,
282- } ;
283- let ( func, self_ty) = fun_info?;
284- let impled_trait = match func. lookup ( db. upcast ( ) ) . container {
285- ItemContainerId :: TraitId ( trait_id) => trait_id,
286- _ => return None ,
287- } ;
288-
289- let krate = self . resolver . krate ( ) ;
290- let trait_env = self . resolver . body_owner ( ) ?. as_generic_def_id ( ) . map_or_else (
291- || Arc :: new ( hir_ty:: TraitEnvironment :: empty ( krate) ) ,
292- |d| db. trait_environment ( d) ,
293- ) ;
294-
295- let fun_data = db. function_data ( func) ;
296- method_resolution:: lookup_impl_method ( & self_ty, db, trait_env, impled_trait, & fun_data. name )
248+ let ( f_in_trait, substs) = self . infer . as_ref ( ) ?. method_resolution ( expr_id) ?;
249+ let f_in_impl = self . resolve_impl_method ( db, f_in_trait, & substs) ;
250+ Some ( ( f_in_impl. unwrap_or ( f_in_trait) , substs) )
297251 }
298252
299253 pub ( crate ) fn resolve_field (
@@ -391,6 +345,25 @@ impl SourceAnalyzer {
391345 let expr_id = self . expr_id ( db, & path_expr. into ( ) ) ?;
392346 let infer = self . infer . as_ref ( ) ?;
393347 if let Some ( assoc) = infer. assoc_resolutions_for_expr ( expr_id) {
348+ let assoc = match assoc {
349+ AssocItemId :: FunctionId ( f_in_trait) => {
350+ match infer. type_of_expr . get ( expr_id) {
351+ None => assoc,
352+ Some ( func_ty) => {
353+ if let TyKind :: FnDef ( _fn_def, subs) = func_ty. kind ( Interner ) {
354+ self . resolve_impl_method ( db, f_in_trait, subs)
355+ . map ( AssocItemId :: FunctionId )
356+ . unwrap_or ( assoc)
357+ } else {
358+ assoc
359+ }
360+ }
361+ }
362+ }
363+
364+ _ => assoc,
365+ } ;
366+
394367 return Some ( PathResolution :: Def ( AssocItem :: from ( assoc) . into ( ) ) ) ;
395368 }
396369 if let Some ( VariantId :: EnumVariantId ( variant) ) =
@@ -616,6 +589,30 @@ impl SourceAnalyzer {
616589 }
617590 false
618591 }
592+
593+ fn resolve_impl_method (
594+ & self ,
595+ db : & dyn HirDatabase ,
596+ func : FunctionId ,
597+ substs : & Substitution ,
598+ ) -> Option < FunctionId > {
599+ let impled_trait = match func. lookup ( db. upcast ( ) ) . container {
600+ ItemContainerId :: TraitId ( trait_id) => trait_id,
601+ _ => return None ,
602+ } ;
603+ if substs. is_empty ( Interner ) {
604+ return None ;
605+ }
606+ let self_ty = substs. at ( Interner , 0 ) . ty ( Interner ) ?;
607+ let krate = self . resolver . krate ( ) ;
608+ let trait_env = self . resolver . body_owner ( ) ?. as_generic_def_id ( ) . map_or_else (
609+ || Arc :: new ( hir_ty:: TraitEnvironment :: empty ( krate) ) ,
610+ |d| db. trait_environment ( d) ,
611+ ) ;
612+
613+ let fun_data = db. function_data ( func) ;
614+ method_resolution:: lookup_impl_method ( self_ty, db, trait_env, impled_trait, & fun_data. name )
615+ }
619616}
620617
621618fn scope_for (
0 commit comments