@@ -3,8 +3,7 @@ use crate::{
33 insert_use_statement, AssistId ,
44} ;
55use hir:: {
6- db:: { DefDatabase , HirDatabase } ,
7- AsAssocItem , AssocItem , AssocItemContainer , Crate , ModPath , Module , ModuleDef , PathResolution ,
6+ db:: HirDatabase , AsAssocItem , AssocItemContainer , ModPath , Module , ModuleDef , PathResolution ,
87 SourceAnalyzer , Trait , Type ,
98} ;
109use ra_ide_db:: { imports_locator:: ImportsLocator , RootDatabase } ;
@@ -141,121 +140,73 @@ impl AutoImportAssets {
141140 ImportsLocator :: new ( db)
142141 . find_imports ( & self . get_search_query ( ) )
143142 . into_iter ( )
144- . map ( |module_def| match & self . import_candidate {
143+ . filter_map ( |module_def| match & self . import_candidate {
145144 ImportCandidate :: TraitAssocItem ( assoc_item_type, _) => {
146145 let located_assoc_item = match module_def {
147- ModuleDef :: Function ( located_function) => {
148- Some ( AssocItem :: Function ( located_function) )
149- }
150- ModuleDef :: Const ( located_const) => Some ( AssocItem :: Const ( located_const) ) ,
146+ ModuleDef :: Function ( located_function) => located_function
147+ . as_assoc_item ( db)
148+ . map ( |assoc| assoc. container ( db) )
149+ . and_then ( Self :: assoc_to_trait) ,
150+ ModuleDef :: Const ( located_const) => located_const
151+ . as_assoc_item ( db)
152+ . map ( |assoc| assoc. container ( db) )
153+ . and_then ( Self :: assoc_to_trait) ,
151154 _ => None ,
152- } ;
153-
154- let mut applicable_traits = Vec :: new ( ) ;
155- if let Some ( located_assoc_item) = located_assoc_item {
156- let trait_candidates: FxHashSet < _ > =
157- Self :: get_trait_candidates ( db, located_assoc_item, current_crate)
158- . into_iter ( )
159- . map ( |trait_candidate| trait_candidate. into ( ) )
160- . collect ( ) ;
161- if !trait_candidates. is_empty ( ) {
162- assoc_item_type. iterate_path_candidates (
163- db,
164- current_crate,
165- & trait_candidates,
166- None ,
167- |_, assoc| {
168- if let AssocItemContainer :: Trait ( appropriate_trait) =
169- assoc. container ( db)
170- {
171- applicable_traits. push (
172- self . module_with_name_to_import
173- . find_use_path ( db, appropriate_trait. into ( ) ) ,
174- ) ;
175- } ;
176- None :: < ( ) >
177- } ,
178- ) ;
179- } ;
180- }
181- applicable_traits
155+ } ?;
156+
157+ let mut trait_candidates = FxHashSet :: default ( ) ;
158+ trait_candidates. insert ( located_assoc_item. into ( ) ) ;
159+
160+ assoc_item_type
161+ . iterate_path_candidates (
162+ db,
163+ current_crate,
164+ & trait_candidates,
165+ None ,
166+ |_, assoc| Self :: assoc_to_trait ( assoc. container ( db) ) ,
167+ )
168+ . map ( ModuleDef :: from)
182169 }
183170 ImportCandidate :: TraitMethod ( function_callee, _) => {
184- let mut applicable_traits = Vec :: new ( ) ;
185- if let ModuleDef :: Function ( located_function) = module_def {
186- let trait_candidates: FxHashSet < _ > = Self :: get_trait_candidates (
171+ let located_assoc_item =
172+ if let ModuleDef :: Function ( located_function) = module_def {
173+ located_function
174+ . as_assoc_item ( db)
175+ . map ( |assoc| assoc. container ( db) )
176+ . and_then ( Self :: assoc_to_trait)
177+ } else {
178+ None
179+ } ?;
180+
181+ let mut trait_candidates = FxHashSet :: default ( ) ;
182+ trait_candidates. insert ( located_assoc_item. into ( ) ) ;
183+
184+ function_callee
185+ . iterate_method_candidates (
187186 db,
188- AssocItem :: Function ( located_function) ,
189187 current_crate,
188+ & trait_candidates,
189+ None ,
190+ |_, function| {
191+ Self :: assoc_to_trait ( function. as_assoc_item ( db) ?. container ( db) )
192+ } ,
190193 )
191- . into_iter ( )
192- . map ( |trait_candidate| trait_candidate. into ( ) )
193- . collect ( ) ;
194- if !trait_candidates. is_empty ( ) {
195- function_callee. iterate_method_candidates (
196- db,
197- current_crate,
198- & trait_candidates,
199- None ,
200- |_, function| {
201- if let AssocItemContainer :: Trait ( appropriate_trait) = function
202- . as_assoc_item ( db)
203- . expect ( "Function is an assoc item" )
204- . container ( db)
205- {
206- applicable_traits. push (
207- self . module_with_name_to_import
208- . find_use_path ( db, appropriate_trait. into ( ) ) ,
209- ) ;
210- } ;
211- None :: < ( ) >
212- } ,
213- ) ;
214- }
215- }
216- applicable_traits
194+ . map ( ModuleDef :: from)
217195 }
218- _ => vec ! [ self . module_with_name_to_import . find_use_path ( db , module_def) ] ,
196+ _ => Some ( module_def) ,
219197 } )
220- . flatten ( )
221- . filter_map ( std:: convert:: identity)
198+ . filter_map ( |module_def| self . module_with_name_to_import . find_use_path ( db, module_def) )
222199 . filter ( |use_path| !use_path. segments . is_empty ( ) )
223200 . take ( 20 )
224201 . collect :: < BTreeSet < _ > > ( )
225202 }
226203
227- fn get_trait_candidates (
228- db : & RootDatabase ,
229- called_assoc_item : AssocItem ,
230- root_crate : Crate ,
231- ) -> FxHashSet < Trait > {
232- let _p = profile ( "auto_import::get_trait_candidates" ) ;
233- root_crate
234- . dependencies ( db)
235- . into_iter ( )
236- . map ( |dependency| db. crate_def_map ( dependency. krate . into ( ) ) )
237- . chain ( std:: iter:: once ( db. crate_def_map ( root_crate. into ( ) ) ) )
238- . map ( |crate_def_map| {
239- crate_def_map
240- . modules
241- . iter ( )
242- . map ( |( _, module_data) | module_data. scope . declarations ( ) )
243- . flatten ( )
244- . filter_map ( |module_def_id| match module_def_id. into ( ) {
245- ModuleDef :: Trait ( trait_candidate)
246- if trait_candidate
247- . items ( db)
248- . into_iter ( )
249- . any ( |item| item == called_assoc_item) =>
250- {
251- Some ( trait_candidate)
252- }
253- _ => None ,
254- } )
255- . collect :: < FxHashSet < _ > > ( )
256- } )
257- . flatten ( )
258- . collect ( )
204+ fn assoc_to_trait ( assoc : AssocItemContainer ) -> Option < Trait > {
205+ if let AssocItemContainer :: Trait ( extracted_trait) = assoc {
206+ Some ( extracted_trait)
207+ } else {
208+ None
209+ }
259210 }
260211}
261212
0 commit comments