aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2021-03-02 23:26:53 +0000
committerKirill Bulatov <[email protected]>2021-03-08 21:59:20 +0000
commit33c83e72b9b48177a6171fd06a26676679963a4d (patch)
treeb787206319b2cf0050e4ce7c89ad4365b9a43c11 /crates/ide_db
parent4d4ac1d4fa0aba107a27d3fd2d209304dfe69b9f (diff)
Work towards better import labels
Diffstat (limited to 'crates/ide_db')
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs155
-rw-r--r--crates/ide_db/src/items_locator.rs (renamed from crates/ide_db/src/imports_locator.rs)75
-rw-r--r--crates/ide_db/src/lib.rs2
3 files changed, 101 insertions, 131 deletions
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs
index a30a4dd9d..8d16c011e 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/helpers/import_assets.rs
@@ -1,14 +1,13 @@
1//! Look up accessible paths for items. 1//! Look up accessible paths for items.
2use either::Either;
3use hir::{ 2use hir::{
4 AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module, 3 AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module,
5 ModuleDef, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type, 4 ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type,
6}; 5};
7use rustc_hash::FxHashSet; 6use rustc_hash::FxHashSet;
8use syntax::{ast, AstNode}; 7use syntax::{ast, AstNode};
9 8
10use crate::{ 9use crate::{
11 imports_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT}, 10 items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT},
12 RootDatabase, 11 RootDatabase,
13}; 12};
14 13
@@ -130,34 +129,23 @@ impl<'a> ImportAssets<'a> {
130 129
131#[derive(Debug, Clone, PartialEq, Eq, Hash)] 130#[derive(Debug, Clone, PartialEq, Eq, Hash)]
132pub struct LocatedImport { 131pub struct LocatedImport {
133 import_path: ModPath, 132 pub import_path: ModPath,
134 item_to_import: ItemInNs, 133 pub item_to_import: ItemInNs,
135 data_to_display: Option<(ModPath, ItemInNs)>, 134 pub original_item: ItemInNs,
136} 135}
137 136
138impl LocatedImport { 137impl LocatedImport {
139 pub fn new( 138 pub fn new(import_path: ModPath, item_to_import: ItemInNs, original_item: ItemInNs) -> Self {
140 import_path: ModPath, 139 Self { import_path, item_to_import, original_item }
141 item_to_import: ItemInNs,
142 data_to_display: Option<(ModPath, ItemInNs)>,
143 ) -> Self {
144 Self { import_path, item_to_import, data_to_display }
145 } 140 }
146 141
147 pub fn display_path(&self) -> &ModPath { 142 pub fn original_item_name(&self, db: &RootDatabase) -> Option<Name> {
148 self.data_to_display.as_ref().map(|(mod_path, _)| mod_path).unwrap_or(&self.import_path) 143 match self.original_item {
149 } 144 ItemInNs::Types(module_def_id) | ItemInNs::Values(module_def_id) => {
150 145 ModuleDef::from(module_def_id).name(db)
151 pub fn import_path(&self) -> &ModPath { 146 }
152 &self.import_path 147 ItemInNs::Macros(macro_def_id) => MacroDef::from(macro_def_id).name(db),
153 } 148 }
154
155 pub fn item_to_display(&self) -> ItemInNs {
156 self.data_to_display.as_ref().map(|&(_, item)| item).unwrap_or(self.item_to_import)
157 }
158
159 pub fn item_to_import(&self) -> ItemInNs {
160 self.item_to_import
161 } 149 }
162} 150}
163 151
@@ -166,25 +154,20 @@ impl<'a> ImportAssets<'a> {
166 &self.import_candidate 154 &self.import_candidate
167 } 155 }
168 156
169 fn name_to_import(&self) -> &NameToImport {
170 match &self.import_candidate {
171 ImportCandidate::Path(candidate) => &candidate.name,
172 ImportCandidate::TraitAssocItem(candidate)
173 | ImportCandidate::TraitMethod(candidate) => &candidate.name,
174 }
175 }
176
177 pub fn search_for_imports( 157 pub fn search_for_imports(
178 &self, 158 &self,
179 sema: &Semantics<RootDatabase>, 159 sema: &Semantics<RootDatabase>,
180 prefix_kind: PrefixKind, 160 prefix_kind: PrefixKind,
181 ) -> Vec<LocatedImport> { 161 ) -> FxHashSet<LocatedImport> {
182 let _p = profile::span("import_assets::search_for_imports"); 162 let _p = profile::span("import_assets::search_for_imports");
183 self.search_for(sema, Some(prefix_kind)) 163 self.search_for(sema, Some(prefix_kind))
184 } 164 }
185 165
186 /// This may return non-absolute paths if a part of the returned path is already imported into scope. 166 /// This may return non-absolute paths if a part of the returned path is already imported into scope.
187 pub fn search_for_relative_paths(&self, sema: &Semantics<RootDatabase>) -> Vec<LocatedImport> { 167 pub fn search_for_relative_paths(
168 &self,
169 sema: &Semantics<RootDatabase>,
170 ) -> FxHashSet<LocatedImport> {
188 let _p = profile::span("import_assets::search_for_relative_paths"); 171 let _p = profile::span("import_assets::search_for_relative_paths");
189 self.search_for(sema, None) 172 self.search_for(sema, None)
190 } 173 }
@@ -193,14 +176,13 @@ impl<'a> ImportAssets<'a> {
193 &self, 176 &self,
194 sema: &Semantics<RootDatabase>, 177 sema: &Semantics<RootDatabase>,
195 prefixed: Option<PrefixKind>, 178 prefixed: Option<PrefixKind>,
196 ) -> Vec<LocatedImport> { 179 ) -> FxHashSet<LocatedImport> {
197 let current_crate = self.module_with_candidate.krate(); 180 let items_with_candidate_name = match self.name_to_import() {
198 let scope_definitions = self.scope_definitions(); 181 NameToImport::Exact(exact_name) => items_locator::with_for_exact_name(
199 182 sema,
200 let defs_for_candidate_name = match self.name_to_import() { 183 self.module_with_candidate.krate(),
201 NameToImport::Exact(exact_name) => { 184 exact_name.clone(),
202 imports_locator::find_exact_imports(sema, current_crate, exact_name.clone()) 185 ),
203 }
204 // FIXME: ideally, we should avoid using `fst` for seacrhing trait imports for assoc items: 186 // FIXME: ideally, we should avoid using `fst` for seacrhing trait imports for assoc items:
205 // instead, we need to look up all trait impls for a certain struct and search through them only 187 // instead, we need to look up all trait impls for a certain struct and search through them only
206 // see https://github.com/rust-analyzer/rust-analyzer/pull/7293#issuecomment-761585032 188 // see https://github.com/rust-analyzer/rust-analyzer/pull/7293#issuecomment-761585032
@@ -213,9 +195,9 @@ impl<'a> ImportAssets<'a> {
213 (AssocItemSearch::Include, Some(DEFAULT_QUERY_SEARCH_LIMIT)) 195 (AssocItemSearch::Include, Some(DEFAULT_QUERY_SEARCH_LIMIT))
214 }; 196 };
215 197
216 imports_locator::find_similar_imports( 198 items_locator::with_similar_name(
217 sema, 199 sema,
218 current_crate, 200 self.module_with_candidate.krate(),
219 fuzzy_name.clone(), 201 fuzzy_name.clone(),
220 assoc_item_search, 202 assoc_item_search,
221 limit, 203 limit,
@@ -223,10 +205,11 @@ impl<'a> ImportAssets<'a> {
223 } 205 }
224 }; 206 };
225 207
226 self.applicable_defs(sema.db, prefixed, defs_for_candidate_name) 208 let scope_definitions = self.scope_definitions();
209 self.applicable_defs(sema.db, prefixed, items_with_candidate_name)
227 .into_iter() 210 .into_iter()
228 .filter(|import| import.import_path().len() > 1) 211 .filter(|import| import.import_path.len() > 1)
229 .filter(|import| !scope_definitions.contains(&ScopeDef::from(import.item_to_import()))) 212 .filter(|import| !scope_definitions.contains(&ScopeDef::from(import.item_to_import)))
230 .collect() 213 .collect()
231 } 214 }
232 215
@@ -238,11 +221,19 @@ impl<'a> ImportAssets<'a> {
238 scope_definitions 221 scope_definitions
239 } 222 }
240 223
224 fn name_to_import(&self) -> &NameToImport {
225 match &self.import_candidate {
226 ImportCandidate::Path(candidate) => &candidate.name,
227 ImportCandidate::TraitAssocItem(candidate)
228 | ImportCandidate::TraitMethod(candidate) => &candidate.name,
229 }
230 }
231
241 fn applicable_defs( 232 fn applicable_defs(
242 &self, 233 &self,
243 db: &RootDatabase, 234 db: &RootDatabase,
244 prefixed: Option<PrefixKind>, 235 prefixed: Option<PrefixKind>,
245 defs_for_candidate_name: impl Iterator<Item = Either<ModuleDef, MacroDef>>, 236 items_with_candidate_name: FxHashSet<ItemInNs>,
246 ) -> FxHashSet<LocatedImport> { 237 ) -> FxHashSet<LocatedImport> {
247 let _p = profile::span("import_assets::applicable_defs"); 238 let _p = profile::span("import_assets::applicable_defs");
248 let current_crate = self.module_with_candidate.krate(); 239 let current_crate = self.module_with_candidate.krate();
@@ -251,7 +242,7 @@ impl<'a> ImportAssets<'a> {
251 242
252 match &self.import_candidate { 243 match &self.import_candidate {
253 ImportCandidate::Path(path_candidate) => { 244 ImportCandidate::Path(path_candidate) => {
254 path_applicable_imports(db, path_candidate, mod_path, defs_for_candidate_name) 245 path_applicable_imports(db, path_candidate, mod_path, items_with_candidate_name)
255 } 246 }
256 ImportCandidate::TraitAssocItem(trait_candidate) => trait_applicable_items( 247 ImportCandidate::TraitAssocItem(trait_candidate) => trait_applicable_items(
257 db, 248 db,
@@ -259,7 +250,7 @@ impl<'a> ImportAssets<'a> {
259 trait_candidate, 250 trait_candidate,
260 true, 251 true,
261 mod_path, 252 mod_path,
262 defs_for_candidate_name, 253 items_with_candidate_name,
263 ), 254 ),
264 ImportCandidate::TraitMethod(trait_candidate) => trait_applicable_items( 255 ImportCandidate::TraitMethod(trait_candidate) => trait_applicable_items(
265 db, 256 db,
@@ -267,7 +258,7 @@ impl<'a> ImportAssets<'a> {
267 trait_candidate, 258 trait_candidate,
268 false, 259 false,
269 mod_path, 260 mod_path,
270 defs_for_candidate_name, 261 items_with_candidate_name,
271 ), 262 ),
272 } 263 }
273 } 264 }
@@ -277,17 +268,15 @@ fn path_applicable_imports(
277 db: &RootDatabase, 268 db: &RootDatabase,
278 path_candidate: &PathImportCandidate, 269 path_candidate: &PathImportCandidate,
279 mod_path: impl Fn(ItemInNs) -> Option<ModPath> + Copy, 270 mod_path: impl Fn(ItemInNs) -> Option<ModPath> + Copy,
280 defs_for_candidate_name: impl Iterator<Item = Either<ModuleDef, MacroDef>>, 271 items_with_candidate_name: FxHashSet<ItemInNs>,
281) -> FxHashSet<LocatedImport> { 272) -> FxHashSet<LocatedImport> {
282 let _p = profile::span("import_assets::path_applicable_imports"); 273 let _p = profile::span("import_assets::path_applicable_imports");
283 274
284 let items_for_candidate_name =
285 defs_for_candidate_name.map(|def| def.either(ItemInNs::from, ItemInNs::from));
286
287 let (unresolved_first_segment, unresolved_qualifier) = match &path_candidate.qualifier { 275 let (unresolved_first_segment, unresolved_qualifier) = match &path_candidate.qualifier {
288 Qualifier::Absent => { 276 Qualifier::Absent => {
289 return items_for_candidate_name 277 return items_with_candidate_name
290 .filter_map(|item| Some(LocatedImport::new(mod_path(item)?, item, None))) 278 .into_iter()
279 .filter_map(|item| Some(LocatedImport::new(mod_path(item)?, item, item)))
291 .collect(); 280 .collect();
292 } 281 }
293 Qualifier::FirstSegmentUnresolved(first_segment, qualifier) => { 282 Qualifier::FirstSegmentUnresolved(first_segment, qualifier) => {
@@ -295,7 +284,8 @@ fn path_applicable_imports(
295 } 284 }
296 }; 285 };
297 286
298 items_for_candidate_name 287 items_with_candidate_name
288 .into_iter()
299 .filter_map(|item| { 289 .filter_map(|item| {
300 import_for_item(db, mod_path, &unresolved_first_segment, &unresolved_qualifier, item) 290 import_for_item(db, mod_path, &unresolved_first_segment, &unresolved_qualifier, item)
301 }) 291 })
@@ -336,7 +326,6 @@ fn import_for_item(
336 } 326 }
337 327
338 let segment_import = find_import_for_segment(db, item_candidate, &unresolved_first_segment)?; 328 let segment_import = find_import_for_segment(db, item_candidate, &unresolved_first_segment)?;
339 let data_to_display = Some((import_path_candidate.clone(), original_item));
340 Some(match (segment_import == item_candidate, trait_to_import) { 329 Some(match (segment_import == item_candidate, trait_to_import) {
341 (true, Some(_)) => { 330 (true, Some(_)) => {
342 // FIXME we should be able to import both the trait and the segment, 331 // FIXME we should be able to import both the trait and the segment,
@@ -345,11 +334,11 @@ fn import_for_item(
345 return None; 334 return None;
346 } 335 }
347 (false, Some(trait_to_import)) => { 336 (false, Some(trait_to_import)) => {
348 LocatedImport::new(mod_path(trait_to_import)?, trait_to_import, data_to_display) 337 LocatedImport::new(mod_path(trait_to_import)?, trait_to_import, original_item)
349 } 338 }
350 (true, None) => LocatedImport::new(import_path_candidate, item_candidate, data_to_display), 339 (true, None) => LocatedImport::new(import_path_candidate, item_candidate, original_item),
351 (false, None) => { 340 (false, None) => {
352 LocatedImport::new(mod_path(segment_import)?, segment_import, data_to_display) 341 LocatedImport::new(mod_path(segment_import)?, segment_import, original_item)
353 } 342 }
354 }) 343 })
355} 344}
@@ -399,16 +388,14 @@ fn trait_applicable_items(
399 trait_candidate: &TraitImportCandidate, 388 trait_candidate: &TraitImportCandidate,
400 trait_assoc_item: bool, 389 trait_assoc_item: bool,
401 mod_path: impl Fn(ItemInNs) -> Option<ModPath>, 390 mod_path: impl Fn(ItemInNs) -> Option<ModPath>,
402 defs_for_candidate_name: impl Iterator<Item = Either<ModuleDef, MacroDef>>, 391 items_with_candidate_name: FxHashSet<ItemInNs>,
403) -> FxHashSet<LocatedImport> { 392) -> FxHashSet<LocatedImport> {
404 let _p = profile::span("import_assets::trait_applicable_items"); 393 let _p = profile::span("import_assets::trait_applicable_items");
405 let mut required_assoc_items = FxHashSet::default(); 394 let mut required_assoc_items = FxHashSet::default();
406 395
407 let trait_candidates = defs_for_candidate_name 396 let trait_candidates = items_with_candidate_name
408 .filter_map(|input| match input { 397 .into_iter()
409 Either::Left(module_def) => module_def.as_assoc_item(db), 398 .filter_map(|input| ModuleDef::from(input.as_module_def_id()?).as_assoc_item(db))
410 _ => None,
411 })
412 .filter_map(|assoc| { 399 .filter_map(|assoc| {
413 let assoc_item_trait = assoc.containing_trait(db)?; 400 let assoc_item_trait = assoc.containing_trait(db)?;
414 required_assoc_items.insert(assoc); 401 required_assoc_items.insert(assoc);
@@ -433,20 +420,10 @@ fn trait_applicable_items(
433 } 420 }
434 421
435 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); 422 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
436 let item_path = mod_path(item)?;
437
438 let assoc_item = assoc_to_item(assoc);
439 let assoc_item_path = match assoc.container(db) {
440 AssocItemContainer::Trait(_) => item_path.clone(),
441 AssocItemContainer::Impl(impl_) => mod_path(ItemInNs::from(
442 ModuleDef::from(impl_.target_ty(db).as_adt()?),
443 ))?,
444 };
445
446 located_imports.insert(LocatedImport::new( 423 located_imports.insert(LocatedImport::new(
447 item_path, 424 mod_path(item)?,
448 item, 425 item,
449 Some((assoc_item_path, assoc_item)), 426 assoc_to_item(assoc),
450 )); 427 ));
451 } 428 }
452 None::<()> 429 None::<()>
@@ -462,20 +439,10 @@ fn trait_applicable_items(
462 let assoc = function.as_assoc_item(db)?; 439 let assoc = function.as_assoc_item(db)?;
463 if required_assoc_items.contains(&assoc) { 440 if required_assoc_items.contains(&assoc) {
464 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)); 441 let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
465 let item_path = mod_path(item)?;
466
467 let assoc_item = assoc_to_item(assoc);
468 let assoc_item_path = match assoc.container(db) {
469 AssocItemContainer::Trait(_) => item_path.clone(),
470 AssocItemContainer::Impl(impl_) => mod_path(ItemInNs::from(
471 ModuleDef::from(impl_.target_ty(db).as_adt()?),
472 ))?,
473 };
474
475 located_imports.insert(LocatedImport::new( 442 located_imports.insert(LocatedImport::new(
476 item_path, 443 mod_path(item)?,
477 item, 444 item,
478 Some((assoc_item_path, assoc_item)), 445 assoc_to_item(assoc),
479 )); 446 ));
480 } 447 }
481 None::<()> 448 None::<()>
diff --git a/crates/ide_db/src/imports_locator.rs b/crates/ide_db/src/items_locator.rs
index fd700e04f..b81c14618 100644
--- a/crates/ide_db/src/imports_locator.rs
+++ b/crates/ide_db/src/items_locator.rs
@@ -1,9 +1,10 @@
1//! This module contains an import search functionality that is provided to the assists module. 1//! This module contains an import search functionality that is provided to the assists module.
2//! Later, this should be moved away to a separate crate that is accessible from the assists module. 2//! Later, this should be moved away to a separate crate that is accessible from the assists module.
3 3
4use either::Either;
4use hir::{ 5use hir::{
5 import_map::{self, ImportKind}, 6 import_map::{self, ImportKind},
6 AsAssocItem, Crate, MacroDef, ModuleDef, Semantics, 7 AsAssocItem, Crate, ItemInNs, ModuleDef, Semantics,
7}; 8};
8use syntax::{ast, AstNode, SyntaxKind::NAME}; 9use syntax::{ast, AstNode, SyntaxKind::NAME};
9 10
@@ -12,32 +13,31 @@ use crate::{
12 symbol_index::{self, FileSymbol}, 13 symbol_index::{self, FileSymbol},
13 RootDatabase, 14 RootDatabase,
14}; 15};
15use either::Either;
16use rustc_hash::FxHashSet; 16use rustc_hash::FxHashSet;
17 17
18pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40; 18pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40;
19 19
20pub fn find_exact_imports( 20pub fn with_for_exact_name(
21 sema: &Semantics<'_, RootDatabase>, 21 sema: &Semantics<'_, RootDatabase>,
22 krate: Crate, 22 krate: Crate,
23 name_to_import: String, 23 exact_name: String,
24) -> Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>>> { 24) -> FxHashSet<ItemInNs> {
25 let _p = profile::span("find_exact_imports"); 25 let _p = profile::span("find_exact_imports");
26 Box::new(find_imports( 26 find_items(
27 sema, 27 sema,
28 krate, 28 krate,
29 { 29 {
30 let mut local_query = symbol_index::Query::new(name_to_import.clone()); 30 let mut local_query = symbol_index::Query::new(exact_name.clone());
31 local_query.exact(); 31 local_query.exact();
32 local_query.limit(DEFAULT_QUERY_SEARCH_LIMIT); 32 local_query.limit(DEFAULT_QUERY_SEARCH_LIMIT);
33 local_query 33 local_query
34 }, 34 },
35 import_map::Query::new(name_to_import) 35 import_map::Query::new(exact_name)
36 .limit(DEFAULT_QUERY_SEARCH_LIMIT) 36 .limit(DEFAULT_QUERY_SEARCH_LIMIT)
37 .name_only() 37 .name_only()
38 .search_mode(import_map::SearchMode::Equals) 38 .search_mode(import_map::SearchMode::Equals)
39 .case_sensitive(), 39 .case_sensitive(),
40 )) 40 )
41} 41}
42 42
43#[derive(Debug)] 43#[derive(Debug)]
@@ -47,13 +47,13 @@ pub enum AssocItemSearch {
47 AssocItemsOnly, 47 AssocItemsOnly,
48} 48}
49 49
50pub fn find_similar_imports<'a>( 50pub fn with_similar_name(
51 sema: &'a Semantics<'a, RootDatabase>, 51 sema: &Semantics<'_, RootDatabase>,
52 krate: Crate, 52 krate: Crate,
53 fuzzy_search_string: String, 53 fuzzy_search_string: String,
54 assoc_item_search: AssocItemSearch, 54 assoc_item_search: AssocItemSearch,
55 limit: Option<usize>, 55 limit: Option<usize>,
56) -> Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a> { 56) -> FxHashSet<ItemInNs> {
57 let _p = profile::span("find_similar_imports"); 57 let _p = profile::span("find_similar_imports");
58 58
59 let mut external_query = import_map::Query::new(fuzzy_search_string.clone()) 59 let mut external_query = import_map::Query::new(fuzzy_search_string.clone())
@@ -77,36 +77,39 @@ pub fn find_similar_imports<'a>(
77 local_query.limit(limit); 77 local_query.limit(limit);
78 } 78 }
79 79
80 Box::new(find_imports(sema, krate, local_query, external_query).filter( 80 find_items(sema, krate, local_query, external_query)
81 move |import_candidate| match assoc_item_search { 81 .into_iter()
82 .filter(move |&item| match assoc_item_search {
82 AssocItemSearch::Include => true, 83 AssocItemSearch::Include => true,
83 AssocItemSearch::Exclude => !is_assoc_item(import_candidate, sema.db), 84 AssocItemSearch::Exclude => !is_assoc_item(item, sema.db),
84 AssocItemSearch::AssocItemsOnly => is_assoc_item(import_candidate, sema.db), 85 AssocItemSearch::AssocItemsOnly => is_assoc_item(item, sema.db),
85 }, 86 })
86 )) 87 .collect()
87} 88}
88 89
89fn is_assoc_item(import_candidate: &Either<ModuleDef, MacroDef>, db: &RootDatabase) -> bool { 90fn is_assoc_item(item: ItemInNs, db: &RootDatabase) -> bool {
90 match import_candidate { 91 item.as_module_def_id()
91 Either::Left(ModuleDef::Function(function)) => function.as_assoc_item(db).is_some(), 92 .and_then(|module_def_id| ModuleDef::from(module_def_id).as_assoc_item(db))
92 Either::Left(ModuleDef::Const(const_)) => const_.as_assoc_item(db).is_some(), 93 .is_some()
93 Either::Left(ModuleDef::TypeAlias(type_alias)) => type_alias.as_assoc_item(db).is_some(),
94 _ => false,
95 }
96} 94}
97 95
98fn find_imports<'a>( 96fn find_items(
99 sema: &Semantics<'a, RootDatabase>, 97 sema: &Semantics<'_, RootDatabase>,
100 krate: Crate, 98 krate: Crate,
101 local_query: symbol_index::Query, 99 local_query: symbol_index::Query,
102 external_query: import_map::Query, 100 external_query: import_map::Query,
103) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> { 101) -> FxHashSet<ItemInNs> {
104 let _p = profile::span("find_similar_imports"); 102 let _p = profile::span("find_similar_imports");
105 let db = sema.db; 103 let db = sema.db;
106 104
107 // Query dependencies first. 105 // Query dependencies first.
108 let mut candidates: FxHashSet<_> = 106 let mut candidates = krate
109 krate.query_external_importables(db, external_query).collect(); 107 .query_external_importables(db, external_query)
108 .map(|external_importable| match external_importable {
109 Either::Left(module_def) => ItemInNs::from(module_def),
110 Either::Right(macro_def) => ItemInNs::from(macro_def),
111 })
112 .collect::<FxHashSet<_>>();
110 113
111 // Query the local crate using the symbol index. 114 // Query the local crate using the symbol index.
112 let local_results = symbol_index::crate_symbols(db, krate.into(), local_query); 115 let local_results = symbol_index::crate_symbols(db, krate.into(), local_query);
@@ -114,19 +117,19 @@ fn find_imports<'a>(
114 candidates.extend( 117 candidates.extend(
115 local_results 118 local_results
116 .into_iter() 119 .into_iter()
117 .filter_map(|import_candidate| get_name_definition(sema, &import_candidate)) 120 .filter_map(|local_candidate| get_name_definition(sema, &local_candidate))
118 .filter_map(|name_definition_to_import| match name_definition_to_import { 121 .filter_map(|name_definition_to_import| match name_definition_to_import {
119 Definition::ModuleDef(module_def) => Some(Either::Left(module_def)), 122 Definition::ModuleDef(module_def) => Some(ItemInNs::from(module_def)),
120 Definition::Macro(macro_def) => Some(Either::Right(macro_def)), 123 Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)),
121 _ => None, 124 _ => None,
122 }), 125 }),
123 ); 126 );
124 127
125 candidates.into_iter() 128 candidates
126} 129}
127 130
128fn get_name_definition<'a>( 131fn get_name_definition(
129 sema: &Semantics<'a, RootDatabase>, 132 sema: &Semantics<'_, RootDatabase>,
130 import_candidate: &FileSymbol, 133 import_candidate: &FileSymbol,
131) -> Option<Definition> { 134) -> Option<Definition> {
132 let _p = profile::span("get_name_definition"); 135 let _p = profile::span("get_name_definition");
diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs
index 6eb34b06b..88ee4a87d 100644
--- a/crates/ide_db/src/lib.rs
+++ b/crates/ide_db/src/lib.rs
@@ -8,7 +8,7 @@ pub mod line_index;
8pub mod symbol_index; 8pub mod symbol_index;
9pub mod defs; 9pub mod defs;
10pub mod search; 10pub mod search;
11pub mod imports_locator; 11pub mod items_locator;
12pub mod source_change; 12pub mod source_change;
13pub mod ty_filter; 13pub mod ty_filter;
14pub mod traits; 14pub mod traits;