7
7
use std:: { convert:: TryInto , mem, sync:: Arc } ;
8
8
9
9
use base_db:: { FileId , FileRange , SourceDatabase , SourceDatabaseExt } ;
10
- use hir:: {
11
- AsAssocItem , DefWithBody , HasAttrs , HasSource , InFile , ModuleSource , Semantics , Visibility ,
12
- } ;
10
+ use hir:: { DefWithBody , HasAttrs , HasSource , InFile , ModuleSource , Semantics , Visibility } ;
13
11
use once_cell:: unsync:: Lazy ;
14
12
use rustc_hash:: FxHashMap ;
15
13
use syntax:: { ast, match_ast, AstNode , TextRange , TextSize } ;
16
14
17
15
use crate :: {
18
16
defs:: { Definition , NameClass , NameRefClass } ,
19
- traits:: convert_to_def_in_trait,
17
+ traits:: { as_trait_assoc_def , convert_to_def_in_trait} ,
20
18
RootDatabase ,
21
19
} ;
22
20
@@ -314,6 +312,7 @@ impl Definition {
314
312
_ => None ,
315
313
} ,
316
314
def : self ,
315
+ trait_assoc_def : as_trait_assoc_def ( sema. db , self ) ,
317
316
sema,
318
317
scope : None ,
319
318
include_self_kw_refs : None ,
@@ -325,6 +324,8 @@ impl Definition {
325
324
#[ derive( Clone ) ]
326
325
pub struct FindUsages < ' a > {
327
326
def : Definition ,
327
+ /// If def is an assoc item from a trait or trait impl, this is the corresponding item of the trait definition
328
+ trait_assoc_def : Option < Definition > ,
328
329
sema : & ' a Semantics < ' a , RootDatabase > ,
329
330
scope : Option < SearchScope > ,
330
331
include_self_kw_refs : Option < hir:: Type > ,
@@ -375,7 +376,7 @@ impl<'a> FindUsages<'a> {
375
376
let sema = self . sema ;
376
377
377
378
let search_scope = {
378
- let base = self . def . search_scope ( sema. db ) ;
379
+ let base = self . trait_assoc_def . unwrap_or ( self . def ) . search_scope ( sema. db ) ;
379
380
match & self . scope {
380
381
None => base,
381
382
Some ( scope) => base. intersection ( scope) ,
@@ -621,7 +622,13 @@ impl<'a> FindUsages<'a> {
621
622
sink ( file_id, reference)
622
623
}
623
624
Some ( NameRefClass :: Definition ( def) )
624
- if convert_to_def_in_trait ( self . sema . db , def) == self . def =>
625
+ if match self . trait_assoc_def {
626
+ Some ( trait_assoc_def) => {
627
+ // we have a trait assoc item, so force resolve all assoc items to their trait version
628
+ convert_to_def_in_trait ( self . sema . db , def) == trait_assoc_def
629
+ }
630
+ None => self . def == def,
631
+ } =>
625
632
{
626
633
let FileRange { file_id, range } = self . sema . original_range ( name_ref. syntax ( ) ) ;
627
634
let reference = FileReference {
@@ -711,30 +718,22 @@ impl<'a> FindUsages<'a> {
711
718
}
712
719
false
713
720
}
714
- // Resolve trait impl function definitions to the trait definition's version if self.def is the trait definition's
715
721
Some ( NameClass :: Definition ( def) ) if def != self . def => {
716
- /* poor man's try block */
717
- ( || {
718
- let this_trait = self
719
- . def
720
- . as_assoc_item ( self . sema . db ) ?
721
- . containing_trait_or_trait_impl ( self . sema . db ) ?;
722
- let trait_ = def
723
- . as_assoc_item ( self . sema . db ) ?
724
- . containing_trait_or_trait_impl ( self . sema . db ) ?;
725
- ( trait_ == this_trait && self . def . name ( self . sema . db ) == def. name ( self . sema . db ) )
726
- . then ( || {
727
- let FileRange { file_id, range } =
728
- self . sema . original_range ( name. syntax ( ) ) ;
729
- let reference = FileReference {
730
- range,
731
- name : ast:: NameLike :: Name ( name. clone ( ) ) ,
732
- category : None ,
733
- } ;
734
- sink ( file_id, reference)
735
- } )
736
- } ) ( )
737
- . unwrap_or ( false )
722
+ // if the def we are looking for is a trait (impl) assoc item, we'll have to resolve the items to trait definition assoc item
723
+ if !matches ! (
724
+ self . trait_assoc_def,
725
+ Some ( trait_assoc_def)
726
+ if convert_to_def_in_trait( self . sema. db, def) == trait_assoc_def
727
+ ) {
728
+ return false ;
729
+ }
730
+ let FileRange { file_id, range } = self . sema . original_range ( name. syntax ( ) ) ;
731
+ let reference = FileReference {
732
+ range,
733
+ name : ast:: NameLike :: Name ( name. clone ( ) ) ,
734
+ category : None ,
735
+ } ;
736
+ sink ( file_id, reference)
738
737
}
739
738
_ => false ,
740
739
}
0 commit comments