5
5
use std:: sync:: Arc ;
6
6
7
7
use arrayvec:: ArrayVec ;
8
- use hir_def:: { lang_item:: LangItemTarget , resolver:: Resolver , AstItemDef , HasModule } ;
8
+ use hir_def:: {
9
+ lang_item:: LangItemTarget , resolver:: HasResolver , resolver:: Resolver , AssocItemId , AstItemDef ,
10
+ HasModule , ImplId , TraitId ,
11
+ } ;
12
+ use ra_db:: CrateId ;
13
+ use ra_prof:: profile;
9
14
use rustc_hash:: FxHashMap ;
10
15
11
16
use crate :: {
12
17
db:: HirDatabase ,
13
18
ty:: primitive:: { FloatBitness , Uncertain } ,
14
19
ty:: { Ty , TypeCtor } ,
15
- AssocItem , Crate , Function , ImplBlock , Module , Mutability , Name , Trait ,
20
+ AssocItem , Crate , Function , Mutability , Name , Trait ,
16
21
} ;
17
22
18
23
use super :: { autoderef, Canonical , InEnvironment , TraitEnvironment , TraitRef } ;
@@ -37,54 +42,58 @@ impl TyFingerprint {
37
42
38
43
#[ derive( Debug , PartialEq , Eq ) ]
39
44
pub struct CrateImplBlocks {
40
- impls : FxHashMap < TyFingerprint , Vec < ImplBlock > > ,
41
- impls_by_trait : FxHashMap < Trait , Vec < ImplBlock > > ,
45
+ impls : FxHashMap < TyFingerprint , Vec < ImplId > > ,
46
+ impls_by_trait : FxHashMap < TraitId , Vec < ImplId > > ,
42
47
}
43
48
44
49
impl CrateImplBlocks {
45
50
pub ( crate ) fn impls_in_crate_query (
46
51
db : & impl HirDatabase ,
47
- krate : Crate ,
52
+ krate : CrateId ,
48
53
) -> Arc < CrateImplBlocks > {
49
- let mut crate_impl_blocks =
54
+ let _p = profile ( "impls_in_crate_query" ) ;
55
+ let mut res =
50
56
CrateImplBlocks { impls : FxHashMap :: default ( ) , impls_by_trait : FxHashMap :: default ( ) } ;
51
- if let Some ( module) = krate. root_module ( db) {
52
- crate_impl_blocks. collect_recursive ( db, module) ;
57
+
58
+ let crate_def_map = db. crate_def_map ( krate) ;
59
+ for ( _module_id, module_data) in crate_def_map. modules . iter ( ) {
60
+ for & impl_id in module_data. impls . iter ( ) {
61
+ let impl_data = db. impl_data ( impl_id) ;
62
+ let resolver = impl_id. resolver ( db) ;
63
+
64
+ let target_ty = { Ty :: from_hir ( db, & resolver, & impl_data. target_type ) } ;
65
+
66
+ match & impl_data. target_trait {
67
+ Some ( trait_ref) => {
68
+ if let Some ( tr) =
69
+ TraitRef :: from_hir ( db, & resolver, & trait_ref, Some ( target_ty) )
70
+ {
71
+ res. impls_by_trait . entry ( tr. trait_ . id ) . or_default ( ) . push ( impl_id) ;
72
+ }
73
+ }
74
+ None => {
75
+ if let Some ( target_ty_fp) = TyFingerprint :: for_impl ( & target_ty) {
76
+ res. impls . entry ( target_ty_fp) . or_default ( ) . push ( impl_id) ;
77
+ }
78
+ }
79
+ }
80
+ }
53
81
}
54
- Arc :: new ( crate_impl_blocks)
82
+
83
+ Arc :: new ( res)
55
84
}
56
- pub fn lookup_impl_blocks ( & self , ty : & Ty ) -> impl Iterator < Item = ImplBlock > + ' _ {
85
+ pub fn lookup_impl_blocks ( & self , ty : & Ty ) -> impl Iterator < Item = ImplId > + ' _ {
57
86
let fingerprint = TyFingerprint :: for_impl ( ty) ;
58
87
fingerprint. and_then ( |f| self . impls . get ( & f) ) . into_iter ( ) . flatten ( ) . copied ( )
59
88
}
60
89
61
- pub fn lookup_impl_blocks_for_trait ( & self , tr : Trait ) -> impl Iterator < Item = ImplBlock > + ' _ {
62
- self . impls_by_trait . get ( & tr) . into_iter ( ) . flatten ( ) . copied ( )
90
+ pub fn lookup_impl_blocks_for_trait ( & self , tr : Trait ) -> impl Iterator < Item = ImplId > + ' _ {
91
+ self . impls_by_trait . get ( & tr. id ) . into_iter ( ) . flatten ( ) . copied ( )
63
92
}
64
93
65
- pub fn all_impls < ' a > ( & ' a self ) -> impl Iterator < Item = ImplBlock > + ' a {
94
+ pub fn all_impls < ' a > ( & ' a self ) -> impl Iterator < Item = ImplId > + ' a {
66
95
self . impls . values ( ) . chain ( self . impls_by_trait . values ( ) ) . flatten ( ) . copied ( )
67
96
}
68
-
69
- fn collect_recursive ( & mut self , db : & impl HirDatabase , module : Module ) {
70
- for impl_block in module. impl_blocks ( db) {
71
- let target_ty = impl_block. target_ty ( db) ;
72
-
73
- if impl_block. target_trait ( db) . is_some ( ) {
74
- if let Some ( tr) = impl_block. target_trait_ref ( db) {
75
- self . impls_by_trait . entry ( tr. trait_ ) . or_default ( ) . push ( impl_block) ;
76
- }
77
- } else {
78
- if let Some ( target_ty_fp) = TyFingerprint :: for_impl ( & target_ty) {
79
- self . impls . entry ( target_ty_fp) . or_default ( ) . push ( impl_block) ;
80
- }
81
- }
82
- }
83
-
84
- for child in module. children ( db) {
85
- self . collect_recursive ( db, child) ;
86
- }
87
- }
88
97
}
89
98
90
99
fn def_crates ( db : & impl HirDatabase , cur_crate : Crate , ty : & Ty ) -> Option < ArrayVec < [ Crate ; 2 ] > > {
@@ -279,14 +288,14 @@ fn iterate_inherent_methods<T>(
279
288
mut callback : impl FnMut ( & Ty , AssocItem ) -> Option < T > ,
280
289
) -> Option < T > {
281
290
for krate in def_crates ( db, krate, & ty. value ) ? {
282
- let impls = db. impls_in_crate ( krate) ;
291
+ let impls = db. impls_in_crate ( krate. crate_id ) ;
283
292
284
293
for impl_block in impls. lookup_impl_blocks ( & ty. value ) {
285
- for item in impl_block. items ( db ) {
294
+ for & item in db . impl_data ( impl_block) . items . iter ( ) {
286
295
if !is_valid_candidate ( db, name, mode, item) {
287
296
continue ;
288
297
}
289
- if let Some ( result) = callback ( & ty. value , item) {
298
+ if let Some ( result) = callback ( & ty. value , item. into ( ) ) {
290
299
return Some ( result) ;
291
300
}
292
301
}
@@ -299,17 +308,17 @@ fn is_valid_candidate(
299
308
db : & impl HirDatabase ,
300
309
name : Option < & Name > ,
301
310
mode : LookupMode ,
302
- item : AssocItem ,
311
+ item : AssocItemId ,
303
312
) -> bool {
304
313
match item {
305
- AssocItem :: Function ( m) => {
306
- let data = db. function_data ( m. id ) ;
307
- name. map_or ( true , |name| data. name == * name)
314
+ AssocItemId :: FunctionId ( m) => {
315
+ let data = db. function_data ( m) ;
316
+ name. map_or ( true , |name| & data. name == name)
308
317
&& ( data. has_self_param || mode == LookupMode :: Path )
309
318
}
310
- AssocItem :: Const ( c) => {
311
- name . map_or ( true , |name| Some ( name ) == c . name ( db ) . as_ref ( ) )
312
- && ( mode == LookupMode :: Path )
319
+ AssocItemId :: ConstId ( c) => {
320
+ let data = db . const_data ( c ) ;
321
+ name . map_or ( true , |name| data . name . as_ref ( ) == Some ( name ) ) && ( mode == LookupMode :: Path )
313
322
}
314
323
_ => false ,
315
324
}
@@ -344,11 +353,11 @@ impl Ty {
344
353
mut callback : impl FnMut ( AssocItem ) -> Option < T > ,
345
354
) -> Option < T > {
346
355
for krate in def_crates ( db, krate, & self ) ? {
347
- let impls = db. impls_in_crate ( krate) ;
356
+ let impls = db. impls_in_crate ( krate. crate_id ) ;
348
357
349
358
for impl_block in impls. lookup_impl_blocks ( & self ) {
350
- for item in impl_block. items ( db ) {
351
- if let Some ( result) = callback ( item) {
359
+ for & item in db . impl_data ( impl_block) . items . iter ( ) {
360
+ if let Some ( result) = callback ( item. into ( ) ) {
352
361
return Some ( result) ;
353
362
}
354
363
}
0 commit comments