1
- use hir:: { Impl , Semantics } ;
1
+ use hir:: { AsAssocItem , Impl , Semantics } ;
2
2
use ide_db:: {
3
3
defs:: { Definition , NameClass , NameRefClass } ,
4
4
RootDatabase ,
@@ -36,6 +36,7 @@ pub(crate) fn goto_implementation(
36
36
}
37
37
ast:: NameLike :: Lifetime ( _) => None ,
38
38
} ?;
39
+
39
40
let def = match def {
40
41
Definition :: ModuleDef ( def) => def,
41
42
_ => return None ,
@@ -48,6 +49,12 @@ pub(crate) fn goto_implementation(
48
49
let module = sema. to_module_def ( position. file_id ) ?;
49
50
impls_for_ty ( & sema, builtin. ty ( sema. db , module) )
50
51
}
52
+ hir:: ModuleDef :: Function ( f) => {
53
+ let assoc = f. as_assoc_item ( sema. db ) ?;
54
+ let name = assoc. name ( sema. db ) ?;
55
+ let trait_ = assoc. containing_trait ( sema. db ) ?;
56
+ impls_for_trait_fn ( & sema, trait_, name)
57
+ }
51
58
_ => return None ,
52
59
} ;
53
60
Some ( RangeInfo { range : node. syntax ( ) . text_range ( ) , info : navs } )
@@ -64,6 +71,23 @@ fn impls_for_trait(sema: &Semantics<RootDatabase>, trait_: hir::Trait) -> Vec<Na
64
71
. collect ( )
65
72
}
66
73
74
+ fn impls_for_trait_fn (
75
+ sema : & Semantics < RootDatabase > ,
76
+ trait_ : hir:: Trait ,
77
+ fun_name : hir:: Name ,
78
+ ) -> Vec < NavigationTarget > {
79
+ Impl :: all_for_trait ( sema. db , trait_)
80
+ . into_iter ( )
81
+ . filter_map ( |imp| {
82
+ let item = imp. items ( sema. db ) . iter ( ) . find_map ( |itm| {
83
+ let itm_name = itm. name ( sema. db ) ?;
84
+ ( itm_name == fun_name) . then ( || itm. clone ( ) )
85
+ } ) ?;
86
+ item. try_to_nav ( sema. db )
87
+ } )
88
+ . collect ( )
89
+ }
90
+
67
91
#[ cfg( test) ]
68
92
mod tests {
69
93
use ide_db:: base_db:: FileRange ;
@@ -259,6 +283,26 @@ fn foo(_: bool$0) {{}}
259
283
#[lang = "bool"]
260
284
impl bool {}
261
285
//^^^^
286
+ "# ,
287
+ ) ;
288
+ }
289
+
290
+ #[ test]
291
+ fn goto_implementation_trait_functions ( ) {
292
+ check (
293
+ r#"
294
+ trait Tr {
295
+ fn f$0();
296
+ }
297
+
298
+ struct S;
299
+
300
+ impl Tr for S {
301
+ fn f() {
302
+ //^
303
+ println!("Hello, world!");
304
+ }
305
+ }
262
306
"# ,
263
307
) ;
264
308
}
0 commit comments