aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs101
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 {
224fn path_applicable_defs<'a>( 226fn 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
258fn resolve_qualifier_start( 250fn 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
340fn get_mod_path( 321fn get_mod_path(
@@ -350,14 +331,6 @@ fn get_mod_path(
350 } 331 }
351} 332}
352 333
353fn 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
361impl ImportCandidate { 334impl ImportCandidate {
362 fn for_method_call( 335 fn for_method_call(
363 sema: &Semantics<RootDatabase>, 336 sema: &Semantics<RootDatabase>,