Skip to content

Commit 7ddeaba

Browse files
committed
Less allocs
1 parent dbf7ccc commit 7ddeaba

File tree

3 files changed

+30
-19
lines changed

3 files changed

+30
-19
lines changed

src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Look up accessible paths for items.
22
3+
use std::ops::ControlFlow;
4+
35
use hir::{
46
db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig,
57
ItemInNs, ModPath, Module, ModuleDef, PathResolution, PrefixKind, ScopeDef, Semantics,
@@ -353,6 +355,7 @@ fn path_applicable_imports(
353355
// we have some unresolved qualifier that we search an import for
354356
// The key here is that whatever we import must form a resolved path for the remainder of
355357
// what follows
358+
// FIXME: This doesn't handle visibility
356359
[first_qsegment, qualifier_rest @ ..] => items_locator::items_with_name(
357360
sema,
358361
current_crate,
@@ -417,8 +420,11 @@ fn validate_resolvable(
417420
module,
418421
candidate.clone(),
419422
AssocSearchMode::Exclude,
423+
|it| match scope_filter(it) {
424+
true => ControlFlow::Break(it),
425+
false => ControlFlow::Continue(()),
426+
},
420427
)
421-
.find(|&it| scope_filter(it))
422428
.map(|item| LocatedImport::new(import_path_candidate, resolved_qualifier, item))
423429
}
424430
// FIXME

src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//! by its name and a few criteria.
33
//! The main reason for this module to exist is the fact that project's items and dependencies' items
44
//! are located in different caches, with different APIs.
5+
use std::ops::ControlFlow;
6+
57
use either::Either;
68
use hir::{import_map, Crate, ItemInNs, Module, Semantics};
79
use limit::Limit;
@@ -17,6 +19,7 @@ pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(100);
1719

1820
pub use import_map::AssocSearchMode;
1921

22+
// FIXME: Do callbacks instead to avoid allocations.
2023
/// Searches for importable items with the given name in the crate and its dependencies.
2124
pub fn items_with_name<'a>(
2225
sema: &'a Semantics<'_, RootDatabase>,
@@ -70,12 +73,13 @@ pub fn items_with_name<'a>(
7073
}
7174

7275
/// Searches for importable items with the given name in the crate and its dependencies.
73-
pub fn items_with_name_in_module<'a>(
74-
sema: &'a Semantics<'_, RootDatabase>,
76+
pub fn items_with_name_in_module<T>(
77+
sema: &Semantics<'_, RootDatabase>,
7578
module: Module,
7679
name: NameToImport,
7780
assoc_item_search: AssocSearchMode,
78-
) -> impl Iterator<Item = ItemInNs> + 'a {
81+
mut cb: impl FnMut(ItemInNs) -> ControlFlow<T>,
82+
) -> Option<T> {
7983
let _p = tracing::info_span!("items_with_name_in", name = name.text(), assoc_item_search = ?assoc_item_search, ?module)
8084
.entered();
8185

@@ -107,15 +111,12 @@ pub fn items_with_name_in_module<'a>(
107111
local_query
108112
}
109113
};
110-
let mut local_results = Vec::new();
111-
// FIXME: This using module_symbols is likely wrong?
112114
local_query.search(&[sema.db.module_symbols(module)], |local_candidate| {
113-
local_results.push(match local_candidate.def {
115+
cb(match local_candidate.def {
114116
hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
115117
def => ItemInNs::from(def),
116118
})
117-
});
118-
local_results.into_iter()
119+
})
119120
}
120121

121122
fn find_items<'a>(
@@ -140,10 +141,10 @@ fn find_items<'a>(
140141
// Query the local crate using the symbol index.
141142
let mut local_results = Vec::new();
142143
local_query.search(&symbol_index::crate_symbols(db, krate), |local_candidate| {
143-
local_results.push(match local_candidate.def {
144+
ControlFlow::<()>::Continue(local_results.push(match local_candidate.def {
144145
hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
145146
def => ItemInNs::from(def),
146-
})
147+
}))
147148
});
148149
local_results.into_iter().chain(external_importables)
149150
}

src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::{
2525
fmt,
2626
hash::{Hash, Hasher},
2727
mem,
28+
ops::ControlFlow,
2829
};
2930

3031
use base_db::{
@@ -219,7 +220,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
219220
};
220221

221222
let mut res = vec![];
222-
query.search(&indices, |f| res.push(f.clone()));
223+
query.search::<()>(&indices, |f| ControlFlow::Continue(res.push(f.clone())));
223224
res
224225
}
225226

@@ -313,11 +314,11 @@ impl SymbolIndex {
313314
}
314315

315316
impl Query {
316-
pub(crate) fn search<'sym>(
317+
pub(crate) fn search<'sym, T>(
317318
self,
318319
indices: &'sym [Arc<SymbolIndex>],
319-
cb: impl FnMut(&'sym FileSymbol),
320-
) {
320+
cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
321+
) -> Option<T> {
321322
let _p = tracing::info_span!("symbol_index::Query::search").entered();
322323
let mut op = fst::map::OpBuilder::new();
323324
match self.mode {
@@ -348,12 +349,12 @@ impl Query {
348349
}
349350
}
350351

351-
fn search_maps<'sym>(
352+
fn search_maps<'sym, T>(
352353
&self,
353354
indices: &'sym [Arc<SymbolIndex>],
354355
mut stream: fst::map::Union<'_>,
355-
mut cb: impl FnMut(&'sym FileSymbol),
356-
) {
356+
mut cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
357+
) -> Option<T> {
357358
let ignore_underscore_prefixed = !self.query.starts_with("__");
358359
while let Some((_, indexed_values)) = stream.next() {
359360
for &IndexedValue { index, value } in indexed_values {
@@ -379,11 +380,14 @@ impl Query {
379380
continue;
380381
}
381382
if self.mode.check(&self.query, self.case_sensitive, symbol_name) {
382-
cb(symbol);
383+
if let Some(b) = cb(symbol).break_value() {
384+
return Some(b);
385+
}
383386
}
384387
}
385388
}
386389
}
390+
None
387391
}
388392

389393
fn matches_assoc_mode(&self, is_trait_assoc_item: bool) -> bool {

0 commit comments

Comments
 (0)