diff options
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r-- | crates/ide_db/src/helpers/import_assets.rs | 101 |
1 files changed, 37 insertions, 64 deletions
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index 0da4bdd0e..66e60b698 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs | |||
@@ -183,39 +183,41 @@ impl ImportAssets { | |||
183 | } | 183 | } |
184 | 184 | ||
185 | fn applicable_defs<'a>( | 185 | fn applicable_defs<'a>( |
186 | &self, | 186 | &'a self, |
187 | sema: &'a Semantics<RootDatabase>, | 187 | sema: &'a Semantics<RootDatabase>, |
188 | prefixed: Option<hir::PrefixKind>, | 188 | prefixed: Option<hir::PrefixKind>, |
189 | unfiltered_imports: Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a>, | 189 | unfiltered_defs: impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a, |
190 | ) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> { | 190 | ) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> { |
191 | let current_crate = self.module_with_candidate.krate(); | 191 | let current_crate = self.module_with_candidate.krate(); |
192 | let db = sema.db; | 192 | let db = sema.db; |
193 | 193 | ||
194 | match &self.import_candidate { | 194 | match &self.import_candidate { |
195 | ImportCandidate::Path(path_candidate) => path_applicable_defs( | 195 | ImportCandidate::Path(path_candidate) => Box::new(path_applicable_defs( |
196 | sema, | 196 | sema, |
197 | path_candidate, | 197 | path_candidate, |
198 | unfiltered_imports, | 198 | unfiltered_defs |
199 | self.module_with_candidate, | 199 | .into_iter() |
200 | prefixed, | 200 | .map(|def| def.either(ItemInNs::from, ItemInNs::from)) |
201 | ), | 201 | .filter_map(move |item_to_search| { |
202 | ImportCandidate::TraitAssocItem(trait_candidate) => trait_applicable_defs( | 202 | get_mod_path(db, item_to_search, &self.module_with_candidate, prefixed) |
203 | db, | 203 | .zip(Some(item_to_search)) |
204 | current_crate, | 204 | }), |
205 | trait_candidate, | 205 | )), |
206 | true, | 206 | ImportCandidate::TraitAssocItem(trait_candidate) => Box::new( |
207 | unfiltered_imports, | 207 | trait_applicable_defs(db, current_crate, trait_candidate, true, unfiltered_defs) |
208 | self.module_with_candidate, | 208 | .into_iter() |
209 | prefixed, | 209 | .filter_map(move |item_to_search| { |
210 | get_mod_path(db, item_to_search, &self.module_with_candidate, prefixed) | ||
211 | .zip(Some(item_to_search)) | ||
212 | }), | ||
210 | ), | 213 | ), |
211 | ImportCandidate::TraitMethod(trait_candidate) => trait_applicable_defs( | 214 | ImportCandidate::TraitMethod(trait_candidate) => Box::new( |
212 | db, | 215 | trait_applicable_defs(db, current_crate, trait_candidate, false, unfiltered_defs) |
213 | current_crate, | 216 | .into_iter() |
214 | trait_candidate, | 217 | .filter_map(move |item_to_search| { |
215 | false, | 218 | get_mod_path(db, item_to_search, &self.module_with_candidate, prefixed) |
216 | unfiltered_imports, | 219 | .zip(Some(item_to_search)) |
217 | self.module_with_candidate, | 220 | }), |
218 | prefixed, | ||
219 | ), | 221 | ), |
220 | } | 222 | } |
221 | } | 223 | } |
@@ -224,22 +226,12 @@ impl ImportAssets { | |||
224 | fn path_applicable_defs<'a>( | 226 | fn path_applicable_defs<'a>( |
225 | sema: &'a Semantics<RootDatabase>, | 227 | sema: &'a Semantics<RootDatabase>, |
226 | path_candidate: &PathImportCandidate, | 228 | path_candidate: &PathImportCandidate, |
227 | unfiltered_defs: Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a>, | 229 | unfiltered_defs: impl Iterator<Item = (ModPath, ItemInNs)> + 'a, |
228 | module_with_candidate: Module, | 230 | ) -> impl Iterator<Item = (ModPath, ItemInNs)> + 'a { |
229 | prefixed: Option<hir::PrefixKind>, | ||
230 | ) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> { | ||
231 | let applicable_defs = unfiltered_defs | ||
232 | .map(|candidate| candidate.either(ItemInNs::from, ItemInNs::from)) | ||
233 | .filter_map(move |item_to_search| { | ||
234 | get_mod_path(sema.db, item_to_search, &module_with_candidate, prefixed) | ||
235 | .zip(Some(item_to_search)) | ||
236 | }); | ||
237 | |||
238 | let unresolved_qualifier = match &path_candidate.unresolved_qualifier { | 231 | let unresolved_qualifier = match &path_candidate.unresolved_qualifier { |
239 | Some(qualifier) => qualifier, | 232 | Some(qualifier) => qualifier, |
240 | None => { | 233 | None => { |
241 | // TODO kb too many boxes tossed around | 234 | return unfiltered_defs; |
242 | return Box::new(applicable_defs); | ||
243 | } | 235 | } |
244 | }; | 236 | }; |
245 | 237 | ||
@@ -252,7 +244,7 @@ fn path_applicable_defs<'a>( | |||
252 | // first segment is already unresolved, need to turn it into ModuleDef somehow | 244 | // first segment is already unresolved, need to turn it into ModuleDef somehow |
253 | } | 245 | } |
254 | 246 | ||
255 | return Box::new(applicable_defs); | 247 | return unfiltered_defs; |
256 | } | 248 | } |
257 | 249 | ||
258 | fn resolve_qualifier_start( | 250 | fn resolve_qualifier_start( |
@@ -269,10 +261,8 @@ fn trait_applicable_defs<'a>( | |||
269 | current_crate: Crate, | 261 | current_crate: Crate, |
270 | trait_candidate: &TraitImportCandidate, | 262 | trait_candidate: &TraitImportCandidate, |
271 | trait_assoc_item: bool, | 263 | trait_assoc_item: bool, |
272 | unfiltered_defs: Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a>, | 264 | unfiltered_defs: impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a, |
273 | module_with_candidate: Module, | 265 | ) -> FxHashSet<ItemInNs> { |
274 | prefixed: Option<hir::PrefixKind>, | ||
275 | ) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> { | ||
276 | let mut required_assoc_items = FxHashSet::default(); | 266 | let mut required_assoc_items = FxHashSet::default(); |
277 | 267 | ||
278 | let trait_candidates = unfiltered_defs | 268 | let trait_candidates = unfiltered_defs |
@@ -287,7 +277,7 @@ fn trait_applicable_defs<'a>( | |||
287 | }) | 277 | }) |
288 | .collect(); | 278 | .collect(); |
289 | 279 | ||
290 | let mut applicable_defs = FxHashSet::default(); | 280 | let mut applicable_traits = FxHashSet::default(); |
291 | 281 | ||
292 | if trait_assoc_item { | 282 | if trait_assoc_item { |
293 | trait_candidate.receiver_ty.iterate_path_candidates( | 283 | trait_candidate.receiver_ty.iterate_path_candidates( |
@@ -302,7 +292,8 @@ fn trait_applicable_defs<'a>( | |||
302 | return None; | 292 | return None; |
303 | } | 293 | } |
304 | } | 294 | } |
305 | applicable_defs.insert(assoc_to_module_def(assoc)); | 295 | applicable_traits |
296 | .insert(ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?))); | ||
306 | } | 297 | } |
307 | None::<()> | 298 | None::<()> |
308 | }, | 299 | }, |
@@ -316,25 +307,15 @@ fn trait_applicable_defs<'a>( | |||
316 | |_, function| { | 307 | |_, function| { |
317 | let assoc = function.as_assoc_item(db)?; | 308 | let assoc = function.as_assoc_item(db)?; |
318 | if required_assoc_items.contains(&assoc) { | 309 | if required_assoc_items.contains(&assoc) { |
319 | applicable_defs.insert(assoc_to_module_def(assoc)); | 310 | applicable_traits |
311 | .insert(ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?))); | ||
320 | } | 312 | } |
321 | None::<()> | 313 | None::<()> |
322 | }, | 314 | }, |
323 | ) | 315 | ) |
324 | }; | 316 | }; |
325 | 317 | ||
326 | Box::new( | 318 | applicable_traits |
327 | applicable_defs | ||
328 | .into_iter() | ||
329 | .filter_map(move |candidate| { | ||
330 | let canidate_trait = candidate.as_assoc_item(db)?.containing_trait(db)?; | ||
331 | Some(ItemInNs::from(ModuleDef::from(canidate_trait))) | ||
332 | }) | ||
333 | .filter_map(move |item_to_search| { | ||
334 | get_mod_path(db, item_to_search, &module_with_candidate, prefixed) | ||
335 | .zip(Some(item_to_search)) | ||
336 | }), | ||
337 | ) | ||
338 | } | 319 | } |
339 | 320 | ||
340 | fn get_mod_path( | 321 | fn get_mod_path( |
@@ -350,14 +331,6 @@ fn get_mod_path( | |||
350 | } | 331 | } |
351 | } | 332 | } |
352 | 333 | ||
353 | fn assoc_to_module_def(assoc: AssocItem) -> ModuleDef { | ||
354 | match assoc { | ||
355 | AssocItem::Function(f) => f.into(), | ||
356 | AssocItem::Const(c) => c.into(), | ||
357 | AssocItem::TypeAlias(t) => t.into(), | ||
358 | } | ||
359 | } | ||
360 | |||
361 | impl ImportCandidate { | 334 | impl ImportCandidate { |
362 | fn for_method_call( | 335 | fn for_method_call( |
363 | sema: &Semantics<RootDatabase>, | 336 | sema: &Semantics<RootDatabase>, |