1
- use hir:: { db:: HirDatabase , source_binder} ;
1
+ use hir:: { db:: HirDatabase , source_binder, ApplicationTy , Ty , TypeCtor } ;
2
2
use ra_db:: SourceDatabase ;
3
3
use ra_syntax:: { algo:: find_node_at_offset, ast, AstNode } ;
4
4
@@ -47,7 +47,8 @@ fn impls_for_def(
47
47
48
48
Some (
49
49
impls
50
- . lookup_impl_blocks ( & ty)
50
+ . all_impls ( )
51
+ . filter ( |impl_block| is_equal_for_find_impls ( & ty, & impl_block. target_ty ( db) ) )
51
52
. map ( |imp| NavigationTarget :: from_impl_block ( db, imp) )
52
53
. collect ( ) ,
53
54
)
@@ -71,6 +72,19 @@ fn impls_for_trait(
71
72
)
72
73
}
73
74
75
+ fn is_equal_for_find_impls ( original_ty : & Ty , impl_ty : & Ty ) -> bool {
76
+ match ( original_ty, impl_ty) {
77
+ ( Ty :: Apply ( a_original_ty) , Ty :: Apply ( ApplicationTy { ctor, parameters } ) ) => match ctor {
78
+ TypeCtor :: Ref ( ..) => match parameters. as_single ( ) {
79
+ Ty :: Apply ( a_ty) => a_original_ty. ctor == a_ty. ctor ,
80
+ _ => false ,
81
+ } ,
82
+ _ => a_original_ty. ctor == * ctor,
83
+ } ,
84
+ _ => false ,
85
+ }
86
+ }
87
+
74
88
#[ cfg( test) ]
75
89
mod tests {
76
90
use crate :: mock_analysis:: analysis_and_position;
@@ -173,4 +187,23 @@ mod tests {
173
187
& [ "impl IMPL_BLOCK FileId(2) [0; 31)" , "impl IMPL_BLOCK FileId(3) [0; 31)" ] ,
174
188
) ;
175
189
}
190
+
191
+ #[ test]
192
+ fn goto_implementation_all_impls ( ) {
193
+ check_goto (
194
+ "
195
+ //- /lib.rs
196
+ trait T {}
197
+ struct Foo<|>;
198
+ impl Foo {}
199
+ impl T for Foo {}
200
+ impl T for &Foo {}
201
+ " ,
202
+ & [
203
+ "impl IMPL_BLOCK FileId(1) [23; 34)" ,
204
+ "impl IMPL_BLOCK FileId(1) [35; 52)" ,
205
+ "impl IMPL_BLOCK FileId(1) [53; 71)" ,
206
+ ] ,
207
+ ) ;
208
+ }
176
209
}
0 commit comments