Skip to content

Commit db6988d

Browse files
bors[bot]SomeoneToIgnorekjeremy
authored
Merge #6614 #6632
6614: Improve autoimports on completion speed r=matklad a=SomeoneToIgnore Presumably closes #6594 May help #6612 * Ignore modules eaferly * Do less completion string rendering 6632: Pin cargo_metadata r=matklad a=kjeremy See: oli-obk/cargo_metadata#142 (comment) Co-authored-by: Kirill Bulatov <[email protected]> Co-authored-by: kjeremy <[email protected]>
3 parents ed5c175 + 4baac23 + 9a31426 commit db6988d

File tree

7 files changed

+117
-35
lines changed

7 files changed

+117
-35
lines changed

crates/completion/src/completions/unqualified_path.rs

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,34 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
8181

8282
let potential_import_name = ctx.token.to_string();
8383

84-
let possible_imports =
85-
imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, 400)
86-
.filter_map(|import_candidate| match import_candidate {
87-
// when completing outside the use declaration, modules are pretty useless
88-
// and tend to bloat the completion suggestions a lot
89-
Either::Left(ModuleDef::Module(_)) => None,
90-
Either::Left(module_def) => Some((
91-
current_module.find_use_path(ctx.db, module_def)?,
92-
ScopeDef::ModuleDef(module_def),
93-
)),
94-
Either::Right(macro_def) => Some((
95-
current_module.find_use_path(ctx.db, macro_def)?,
96-
ScopeDef::MacroDef(macro_def),
97-
)),
98-
})
99-
.filter(|(mod_path, _)| mod_path.len() > 1)
100-
.filter_map(|(import_path, definition)| {
101-
render_resolution_with_import(
102-
RenderContext::new(ctx),
103-
import_path.clone(),
104-
import_scope.clone(),
105-
ctx.config.merge,
106-
&definition,
107-
)
108-
})
109-
.take(20);
84+
let possible_imports = imports_locator::find_similar_imports(
85+
&ctx.sema,
86+
ctx.krate?,
87+
&potential_import_name,
88+
50,
89+
true,
90+
)
91+
.filter_map(|import_candidate| {
92+
Some(match import_candidate {
93+
Either::Left(module_def) => {
94+
(current_module.find_use_path(ctx.db, module_def)?, ScopeDef::ModuleDef(module_def))
95+
}
96+
Either::Right(macro_def) => {
97+
(current_module.find_use_path(ctx.db, macro_def)?, ScopeDef::MacroDef(macro_def))
98+
}
99+
})
100+
})
101+
.filter(|(mod_path, _)| mod_path.len() > 1)
102+
.take(20)
103+
.filter_map(|(import_path, definition)| {
104+
render_resolution_with_import(
105+
RenderContext::new(ctx),
106+
import_path.clone(),
107+
import_scope.clone(),
108+
ctx.config.merge,
109+
&definition,
110+
)
111+
});
110112

111113
acc.add_all(possible_imports);
112114
Some(())

crates/completion/src/render.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ impl<'a> Render<'a> {
150150
import_data: Option<(ModPath, ImportScope, Option<MergeBehaviour>)>,
151151
resolution: &ScopeDef,
152152
) -> Option<CompletionItem> {
153+
let _p = profile::span("render_resolution");
153154
use hir::ModuleDef::*;
154155

155156
let completion_kind = match resolution {

crates/flycheck/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ doctest = false
1212
[dependencies]
1313
crossbeam-channel = "0.5.0"
1414
log = "0.4.8"
15-
cargo_metadata = "0.12.0"
15+
cargo_metadata = "=0.12.0"
1616
serde_json = "1.0.48"
1717
jod-thread = "0.1.1"
1818

crates/hir_def/src/import_map.rs

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use fst::{self, Streamer};
77
use hir_expand::name::Name;
88
use indexmap::{map::Entry, IndexMap};
99
use itertools::Itertools;
10-
use rustc_hash::{FxHashMap, FxHasher};
10+
use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
1111
use smallvec::SmallVec;
1212
use syntax::SmolStr;
1313

@@ -225,13 +225,27 @@ fn cmp((_, lhs): &(&ItemInNs, &ImportInfo), (_, rhs): &(&ItemInNs, &ImportInfo))
225225
lhs_str.cmp(&rhs_str)
226226
}
227227

228+
#[derive(Debug, Eq, PartialEq, Hash)]
229+
pub enum ImportKind {
230+
Module,
231+
Function,
232+
Adt,
233+
EnumVariant,
234+
Const,
235+
Static,
236+
Trait,
237+
TypeAlias,
238+
BuiltinType,
239+
}
240+
228241
#[derive(Debug)]
229242
pub struct Query {
230243
query: String,
231244
lowercased: String,
232245
anchor_end: bool,
233246
case_sensitive: bool,
234247
limit: usize,
248+
exclude_import_kinds: FxHashSet<ImportKind>,
235249
}
236250

237251
impl Query {
@@ -242,6 +256,7 @@ impl Query {
242256
anchor_end: false,
243257
case_sensitive: false,
244258
limit: usize::max_value(),
259+
exclude_import_kinds: FxHashSet::default(),
245260
}
246261
}
247262

@@ -260,6 +275,12 @@ impl Query {
260275
pub fn case_sensitive(self) -> Self {
261276
Self { case_sensitive: true, ..self }
262277
}
278+
279+
/// Do not include imports of the specified kind in the search results.
280+
pub fn exclude_import_kind(mut self, import_kind: ImportKind) -> Self {
281+
self.exclude_import_kinds.insert(import_kind);
282+
self
283+
}
263284
}
264285

265286
/// Searches dependencies of `krate` for an importable path matching `query`.
@@ -303,10 +324,17 @@ pub fn search_dependencies<'a>(
303324

304325
// Add the items from this `ModPath` group. Those are all subsequent items in
305326
// `importables` whose paths match `path`.
306-
let iter = importables.iter().copied().take_while(|item| {
307-
let item_path = &import_map.map[item].path;
308-
fst_path(item_path) == fst_path(path)
309-
});
327+
let iter = importables
328+
.iter()
329+
.copied()
330+
.take_while(|item| {
331+
let item_path = &import_map.map[item].path;
332+
fst_path(item_path) == fst_path(path)
333+
})
334+
.filter(|&item| match item_import_kind(item) {
335+
Some(import_kind) => !query.exclude_import_kinds.contains(&import_kind),
336+
None => true,
337+
});
310338

311339
if query.case_sensitive {
312340
// FIXME: This does not do a subsequence match.
@@ -341,6 +369,20 @@ pub fn search_dependencies<'a>(
341369
res
342370
}
343371

372+
fn item_import_kind(item: ItemInNs) -> Option<ImportKind> {
373+
Some(match item.as_module_def_id()? {
374+
ModuleDefId::ModuleId(_) => ImportKind::Module,
375+
ModuleDefId::FunctionId(_) => ImportKind::Function,
376+
ModuleDefId::AdtId(_) => ImportKind::Adt,
377+
ModuleDefId::EnumVariantId(_) => ImportKind::EnumVariant,
378+
ModuleDefId::ConstId(_) => ImportKind::Const,
379+
ModuleDefId::StaticId(_) => ImportKind::Static,
380+
ModuleDefId::TraitId(_) => ImportKind::Trait,
381+
ModuleDefId::TypeAliasId(_) => ImportKind::TypeAlias,
382+
ModuleDefId::BuiltinType(_) => ImportKind::BuiltinType,
383+
})
384+
}
385+
344386
#[cfg(test)]
345387
mod tests {
346388
use base_db::{fixture::WithFixture, SourceDatabase, Upcast};
@@ -758,4 +800,34 @@ mod tests {
758800
"#]],
759801
);
760802
}
803+
804+
#[test]
805+
fn search_exclusions() {
806+
let ra_fixture = r#"
807+
//- /main.rs crate:main deps:dep
808+
//- /dep.rs crate:dep
809+
810+
pub struct fmt;
811+
pub struct FMT;
812+
"#;
813+
814+
check_search(
815+
ra_fixture,
816+
"main",
817+
Query::new("FMT"),
818+
expect![[r#"
819+
dep::fmt (t)
820+
dep::fmt (v)
821+
dep::FMT (t)
822+
dep::FMT (v)
823+
"#]],
824+
);
825+
826+
check_search(
827+
ra_fixture,
828+
"main",
829+
Query::new("FMT").exclude_import_kind(ImportKind::Adt),
830+
expect![[r#""#]],
831+
);
832+
}
761833
}

crates/ide_db/src/imports_locator.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,15 @@ pub fn find_similar_imports<'a>(
3636
krate: Crate,
3737
name_to_import: &str,
3838
limit: usize,
39+
ignore_modules: bool,
3940
) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> {
4041
let _p = profile::span("find_similar_imports");
42+
43+
let mut external_query = import_map::Query::new(name_to_import).limit(limit);
44+
if ignore_modules {
45+
external_query = external_query.exclude_import_kind(import_map::ImportKind::Module);
46+
}
47+
4148
find_imports(
4249
sema,
4350
krate,
@@ -46,7 +53,7 @@ pub fn find_similar_imports<'a>(
4653
local_query.limit(limit);
4754
local_query
4855
},
49-
import_map::Query::new(name_to_import).limit(limit),
56+
external_query,
5057
)
5158
}
5259

crates/proc_macro_srv/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" }
2020
test_utils = { path = "../test_utils", version = "0.0.0" }
2121

2222
[dev-dependencies]
23-
cargo_metadata = "0.12.0"
23+
cargo_metadata = "=0.12.0"
2424
difference = "2.0.0"
2525

2626
# used as proc macro test targets

crates/project_model/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ doctest = false
1212
[dependencies]
1313
log = "0.4.8"
1414
rustc-hash = "1.1.0"
15-
cargo_metadata = "0.12.0"
15+
cargo_metadata = "=0.12.0"
1616
serde = { version = "1.0.106", features = ["derive"] }
1717
serde_json = "1.0.48"
1818
anyhow = "1.0.26"

0 commit comments

Comments
 (0)