@@ -38,127 +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
7580 for krate in crate_graph. transitive_deps ( krate) {
76- res. merge ( & db. impls_in_crate ( krate) ) ;
81+ res. merge ( & db. trait_impls_in_crate ( krate) ) ;
7782 }
7883
7984 Arc :: new ( res)
8085 }
8186
82- fn fill ( & mut self , db : & dyn HirDatabase , krate : CrateId ) {
83- let crate_def_map = db. crate_def_map ( krate) ;
84- for ( _module_id, module_data) in crate_def_map. modules . iter ( ) {
85- for impl_id in module_data. scope . impls ( ) {
86- match db. impl_trait ( impl_id) {
87- Some ( tr) => {
88- let self_ty = db. impl_self_ty ( impl_id) ;
89- let self_ty_fp = TyFingerprint :: for_impl ( & self_ty. value ) ;
90- self . impls_by_trait
91- . entry ( tr. value . trait_ )
92- . or_default ( )
93- . entry ( self_ty_fp)
94- . or_default ( )
95- . push ( impl_id) ;
96- }
97- None => {
98- let self_ty = db. impl_self_ty ( impl_id) ;
99- if let Some ( self_ty_fp) = TyFingerprint :: for_impl ( & self_ty. value ) {
100- self . inherent_impls . entry ( self_ty_fp) . or_default ( ) . push ( impl_id) ;
101- }
102- }
103- }
104- }
105- }
106- }
107-
10887 fn merge ( & mut self , other : & Self ) {
109- for ( fp, impls) in & other. inherent_impls {
110- let vec = self . inherent_impls . entry ( * fp) . or_default ( ) ;
111- vec. extend ( impls) ;
112- }
113-
114- for ( trait_, other_map) in & other. impls_by_trait {
115- 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 ( ) ;
11690 for ( fp, impls) in other_map {
11791 let vec = map. entry ( * fp) . or_default ( ) ;
11892 vec. extend ( impls) ;
11993 }
12094 }
12195 }
12296
123- pub fn lookup_impl_defs ( & self , ty : & Ty ) -> impl Iterator < Item = ImplId > + ' _ {
124- let fingerprint = TyFingerprint :: for_impl ( ty) ;
125- fingerprint. and_then ( |f| self . inherent_impls . get ( & f) ) . into_iter ( ) . flatten ( ) . copied ( )
126- }
127-
128- pub fn lookup_impl_defs_for_trait ( & self , tr : TraitId ) -> impl Iterator < Item = ImplId > + ' _ {
129- self . impls_by_trait
130- . 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_)
131101 . into_iter ( )
132- . flat_map ( |m| m . values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) ) )
102+ . flat_map ( |map| map . values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) ) )
133103 }
134104
135- 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 (
136107 & self ,
137- tr : TraitId ,
138- fp : TyFingerprint ,
108+ trait_ : TraitId ,
109+ self_ty : TyFingerprint ,
139110 ) -> impl Iterator < Item = ImplId > + ' _ {
140- self . impls_by_trait
141- . get ( & tr)
142- . and_then ( |m| m. get ( & Some ( fp) ) )
111+ self . map
112+ . get ( & trait_)
143113 . into_iter ( )
144- . flatten ( )
145- . copied ( )
146- . chain (
147- self . impls_by_trait
148- . get ( & tr)
149- . and_then ( |m| m. get ( & None ) )
150- . into_iter ( )
151- . flatten ( )
152- . copied ( ) ,
153- )
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+ }
154162 }
155163
156- pub fn all_impls < ' a > ( & ' a self ) -> impl Iterator < Item = ImplId > + ' a {
157- self . inherent_impls
158- . values ( )
159- . chain ( self . impls_by_trait . values ( ) . flat_map ( |m| m. values ( ) ) )
160- . flatten ( )
161- . copied ( )
164+ pub fn all_impls ( & self ) -> impl Iterator < Item = ImplId > + ' _ {
165+ self . map . values ( ) . flat_map ( |v| v. iter ( ) . copied ( ) )
162166 }
163167}
164168
@@ -515,9 +519,9 @@ fn iterate_inherent_methods(
515519 None => return false ,
516520 } ;
517521 for krate in def_crates {
518- let impls = db. impls_in_crate ( krate) ;
522+ let impls = db. inherent_impls_in_crate ( krate) ;
519523
520- for impl_def in impls. lookup_impl_defs ( & self_ty. value ) {
524+ for & impl_def in impls. for_self_ty ( & self_ty. value ) {
521525 for & item in db. impl_data ( impl_def) . items . iter ( ) {
522526 if !is_valid_candidate ( db, name, receiver_ty, item, self_ty) {
523527 continue ;
0 commit comments