@@ -21,8 +21,8 @@ use hir_def::{
21
21
path:: { ModPath , Path , PathKind } ,
22
22
resolver:: { resolver_for_scope, Resolver , TypeNs , ValueNs } ,
23
23
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 ,
26
26
} ;
27
27
use hir_expand:: {
28
28
builtin_fn_macro:: BuiltinFnLikeExpander , hygiene:: Hygiene , name:: AsName , HirFileId , InFile ,
@@ -245,55 +245,9 @@ impl SourceAnalyzer {
245
245
call : & ast:: MethodCallExpr ,
246
246
) -> Option < ( FunctionId , Substitution ) > {
247
247
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) )
297
251
}
298
252
299
253
pub ( crate ) fn resolve_field (
@@ -391,6 +345,25 @@ impl SourceAnalyzer {
391
345
let expr_id = self . expr_id ( db, & path_expr. into ( ) ) ?;
392
346
let infer = self . infer . as_ref ( ) ?;
393
347
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
+
394
367
return Some ( PathResolution :: Def ( AssocItem :: from ( assoc) . into ( ) ) ) ;
395
368
}
396
369
if let Some ( VariantId :: EnumVariantId ( variant) ) =
@@ -616,6 +589,30 @@ impl SourceAnalyzer {
616
589
}
617
590
false
618
591
}
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
+ }
619
616
}
620
617
621
618
fn scope_for (
0 commit comments