@@ -38,136 +38,131 @@ impl TyFingerprint {
3838 }
3939}
4040
41- /// A queryable and mergeable collection of impls .
42- #[ derive( Debug , PartialEq , Eq ) ]
43- pub struct CrateImplDefs {
44- inherent_impls : FxHashMap < TyFingerprint , Vec < ImplId > > ,
45- impls_by_trait : FxHashMap < TraitId , FxHashMap < Option < TyFingerprint > , Vec < ImplId > > > ,
41+ /// Trait impls defined or available in some crate .
42+ #[ derive( Debug , Eq , PartialEq ) ]
43+ pub struct TraitImpls {
44+ // If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type.
45+ map : FxHashMap < TraitId , FxHashMap < Option < TyFingerprint > , Vec < ImplId > > > ,
4646}
4747
48- impl CrateImplDefs {
49- pub ( crate ) fn impls_in_crate_query ( db : & dyn HirDatabase , krate : CrateId ) -> Arc < CrateImplDefs > {
50- let _p = profile ( "impls_in_crate_query" ) ;
51- let mut res = CrateImplDefs {
52- inherent_impls : FxHashMap :: default ( ) ,
53- impls_by_trait : FxHashMap :: default ( ) ,
54- } ;
55- res. fill ( db, krate) ;
48+ impl TraitImpls {
49+ pub ( crate ) fn trait_impls_in_crate_query ( db : & dyn HirDatabase , krate : CrateId ) -> Arc < Self > {
50+ let _p = profile ( "trait_impls_in_crate_query" ) ;
51+ let mut impls = Self { map : FxHashMap :: default ( ) } ;
5652
57- Arc :: new ( res)
53+ let crate_def_map = db. crate_def_map ( krate) ;
54+ for ( _module_id, module_data) in crate_def_map. modules . iter ( ) {
55+ for impl_id in module_data. scope . impls ( ) {
56+ let target_trait = match db. impl_trait ( impl_id) {
57+ Some ( tr) => tr. value . trait_ ,
58+ None => continue ,
59+ } ;
60+ let self_ty = db. impl_self_ty ( impl_id) ;
61+ let self_ty_fp = TyFingerprint :: for_impl ( & self_ty. value ) ;
62+ impls
63+ . map
64+ . entry ( target_trait)
65+ . or_default ( )
66+ . entry ( self_ty_fp)
67+ . or_default ( )
68+ . push ( impl_id) ;
69+ }
70+ }
71+
72+ Arc :: new ( impls)
5873 }
5974
60- /// Collects all impls from transitive dependencies of `krate` that may be used by `krate`.
61- ///
62- /// The full set of impls that can be used by `krate` is the returned map plus all the impls
63- /// from `krate` itself.
64- pub ( crate ) fn impls_from_deps_query (
65- db : & dyn HirDatabase ,
66- krate : CrateId ,
67- ) -> Arc < CrateImplDefs > {
68- let _p = profile ( "impls_from_deps_query" ) ;
75+ pub ( crate ) fn trait_impls_in_deps_query ( db : & dyn HirDatabase , krate : CrateId ) -> Arc < Self > {
76+ let _p = profile ( "trait_impls_in_deps_query" ) ;
6977 let crate_graph = db. crate_graph ( ) ;
70- let mut res = CrateImplDefs {
71- inherent_impls : FxHashMap :: default ( ) ,
72- impls_by_trait : FxHashMap :: default ( ) ,
73- } ;
78+ let mut res = Self { map : FxHashMap :: default ( ) } ;
7479
75- // For each dependency, calculate `impls_from_deps` recursively, then add its own
76- // `impls_in_crate`.
77- // As we might visit crates multiple times, `merge` has to deduplicate impls to avoid
78- // wasting memory.
79- for dep in & crate_graph[ krate] . dependencies {
80- res. merge ( & db. impls_from_deps ( dep. crate_id ) ) ;
81- res. merge ( & db. impls_in_crate ( dep. crate_id ) ) ;
80+ for krate in crate_graph. transitive_deps ( krate) {
81+ res. merge ( & db. trait_impls_in_crate ( krate) ) ;
8282 }
8383
8484 Arc :: new ( res)
8585 }
8686
87- fn fill ( & mut self , db : & dyn HirDatabase , krate : CrateId ) {
88- let crate_def_map = db. crate_def_map ( krate) ;
89- for ( _module_id, module_data) in crate_def_map. modules . iter ( ) {
90- for impl_id in module_data. scope . impls ( ) {
91- match db. impl_trait ( impl_id) {
92- Some ( tr) => {
93- let self_ty = db. impl_self_ty ( impl_id) ;
94- let self_ty_fp = TyFingerprint :: for_impl ( & self_ty. value ) ;
95- self . impls_by_trait
96- . entry ( tr. value . trait_ )
97- . or_default ( )
98- . entry ( self_ty_fp)
99- . or_default ( )
100- . push ( impl_id) ;
101- }
102- None => {
103- let self_ty = db. impl_self_ty ( impl_id) ;
104- if let Some ( self_ty_fp) = TyFingerprint :: for_impl ( & self_ty. value ) {
105- self . inherent_impls . entry ( self_ty_fp) . or_default ( ) . push ( impl_id) ;
106- }
107- }
108- }
109- }
110- }
111- }
112-
11387 fn merge ( & mut self , other : & Self ) {
114- for ( fp, impls) in & other. inherent_impls {
115- let vec = self . inherent_impls . entry ( * fp) . or_default ( ) ;
116- vec. extend ( impls) ;
117- vec. sort ( ) ;
118- vec. dedup ( ) ;
119- }
120-
121- for ( trait_, other_map) in & other. impls_by_trait {
122- let map = self . impls_by_trait . entry ( * trait_) . or_default ( ) ;
88+ for ( trait_, other_map) in & other. map {
89+ let map = self . map . entry ( * trait_) . or_default ( ) ;
12390 for ( fp, impls) in other_map {
12491 let vec = map. entry ( * fp) . or_default ( ) ;
12592 vec. extend ( impls) ;
126- vec. sort ( ) ;
127- vec. dedup ( ) ;
12893 }
12994 }
13095 }
13196
132- pub fn lookup_impl_defs ( & self , ty : & Ty ) -> impl Iterator < Item = ImplId > + ' _ {
133- let fingerprint = TyFingerprint :: for_impl ( ty) ;
134- fingerprint. and_then ( |f| self . inherent_impls . get ( & f) ) . into_iter ( ) . flatten ( ) . copied ( )
135- }
136-
137- pub fn lookup_impl_defs_for_trait ( & self , tr : TraitId ) -> impl Iterator < Item = ImplId > + ' _ {
138- self . impls_by_trait
139- . get ( & tr)
97+ /// Queries all impls of the given trait.
98+ pub fn for_trait ( & self , trait_ : TraitId ) -> impl Iterator < Item = ImplId > + ' _ {
99+ self . map
100+ . get ( & trait_)
140101 . into_iter ( )
141- . flat_map ( |m| m . values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) ) )
102+ . flat_map ( |map| map . values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) ) )
142103 }
143104
144- pub fn lookup_impl_defs_for_trait_and_ty (
105+ /// Queries all impls of `trait_` that may apply to `self_ty`.
106+ pub fn for_trait_and_self_ty (
145107 & self ,
146- tr : TraitId ,
147- fp : TyFingerprint ,
108+ trait_ : TraitId ,
109+ self_ty : TyFingerprint ,
148110 ) -> impl Iterator < Item = ImplId > + ' _ {
149- self . impls_by_trait
150- . get ( & tr)
151- . and_then ( |m| m. get ( & Some ( fp) ) )
111+ self . map
112+ . get ( & trait_)
152113 . into_iter ( )
153- . flatten ( )
154- . copied ( )
155- . chain (
156- self . impls_by_trait
157- . get ( & tr)
158- . and_then ( |m| m. get ( & None ) )
159- . into_iter ( )
160- . flatten ( )
161- . copied ( ) ,
162- )
114+ . flat_map ( move |map| map. get ( & None ) . into_iter ( ) . chain ( map. get ( & Some ( self_ty) ) ) )
115+ . flat_map ( |v| v. iter ( ) . copied ( ) )
116+ }
117+
118+ pub fn all_impls ( & self ) -> impl Iterator < Item = ImplId > + ' _ {
119+ self . map . values ( ) . flat_map ( |map| map. values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) ) )
120+ }
121+ }
122+
123+ /// Inherent impls defined in some crate.
124+ ///
125+ /// Inherent impls can only be defined in the crate that also defines the self type of the impl
126+ /// (note that some primitives are considered to be defined by both libcore and liballoc).
127+ ///
128+ /// This makes inherent impl lookup easier than trait impl lookup since we only have to consider a
129+ /// single crate.
130+ #[ derive( Debug , Eq , PartialEq ) ]
131+ pub struct InherentImpls {
132+ map : FxHashMap < TyFingerprint , Vec < ImplId > > ,
133+ }
134+
135+ impl InherentImpls {
136+ pub ( crate ) fn inherent_impls_in_crate_query ( db : & dyn HirDatabase , krate : CrateId ) -> Arc < Self > {
137+ let mut map: FxHashMap < _ , Vec < _ > > = FxHashMap :: default ( ) ;
138+
139+ let crate_def_map = db. crate_def_map ( krate) ;
140+ for ( _module_id, module_data) in crate_def_map. modules . iter ( ) {
141+ for impl_id in module_data. scope . impls ( ) {
142+ let data = db. impl_data ( impl_id) ;
143+ if data. target_trait . is_some ( ) {
144+ continue ;
145+ }
146+
147+ let self_ty = db. impl_self_ty ( impl_id) ;
148+ if let Some ( fp) = TyFingerprint :: for_impl ( & self_ty. value ) {
149+ map. entry ( fp) . or_default ( ) . push ( impl_id) ;
150+ }
151+ }
152+ }
153+
154+ Arc :: new ( Self { map } )
155+ }
156+
157+ pub fn for_self_ty ( & self , self_ty : & Ty ) -> & [ ImplId ] {
158+ match TyFingerprint :: for_impl ( self_ty) {
159+ Some ( fp) => self . map . get ( & fp) . map ( |vec| vec. as_ref ( ) ) . unwrap_or ( & [ ] ) ,
160+ None => & [ ] ,
161+ }
163162 }
164163
165- pub fn all_impls < ' a > ( & ' a self ) -> impl Iterator < Item = ImplId > + ' a {
166- self . inherent_impls
167- . values ( )
168- . chain ( self . impls_by_trait . values ( ) . flat_map ( |m| m. values ( ) ) )
169- . flatten ( )
170- . copied ( )
164+ pub fn all_impls ( & self ) -> impl Iterator < Item = ImplId > + ' _ {
165+ self . map . values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) )
171166 }
172167}
173168
@@ -524,9 +519,9 @@ fn iterate_inherent_methods(
524519 None => return false ,
525520 } ;
526521 for krate in def_crates {
527- let impls = db. impls_in_crate ( krate) ;
522+ let impls = db. inherent_impls_in_crate ( krate) ;
528523
529- for impl_def in impls. lookup_impl_defs ( & self_ty. value ) {
524+ for & impl_def in impls. for_self_ty ( & self_ty. value ) {
530525 for & item in db. impl_data ( impl_def) . items . iter ( ) {
531526 if !is_valid_candidate ( db, name, receiver_ty, item, self_ty) {
532527 continue ;
0 commit comments