Skip to content

Commit c84352a

Browse files
committed
Auto merge of rust-lang#16261 - Veykril:import-map-fix, r=Veykril
internal: Move query limits to the caller Prior we calculated up to `limit` entries from a query, then filtered from that leaving us with less entries than the limit in some cases (which might give odd completion behavior due to items disappearing). This changes it so we filter before checking the limit.
2 parents a795f48 + 2666349 commit c84352a

File tree

10 files changed

+146
-124
lines changed

10 files changed

+146
-124
lines changed

crates/hir-def/src/import_map.rs

+23-42
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ pub struct Query {
295295
search_mode: SearchMode,
296296
assoc_mode: AssocSearchMode,
297297
case_sensitive: bool,
298-
limit: usize,
299298
}
300299

301300
impl Query {
@@ -307,7 +306,6 @@ impl Query {
307306
search_mode: SearchMode::Exact,
308307
assoc_mode: AssocSearchMode::Include,
309308
case_sensitive: false,
310-
limit: usize::MAX,
311309
}
312310
}
313311

@@ -329,11 +327,6 @@ impl Query {
329327
Self { assoc_mode, ..self }
330328
}
331329

332-
/// Limits the returned number of items to `limit`.
333-
pub fn limit(self, limit: usize) -> Self {
334-
Self { limit, ..self }
335-
}
336-
337330
/// Respect casing of the query string when matching.
338331
pub fn case_sensitive(self) -> Self {
339332
Self { case_sensitive: true, ..self }
@@ -413,6 +406,7 @@ fn search_maps(
413406
})
414407
// we put all entries with the same lowercased name in a row, so stop once we find a
415408
// different name in the importables
409+
// FIXME: Consider putting a range into the value: u64 as (u32, u32)?
416410
.take_while(|&(_, info, _)| {
417411
info.name.to_smol_str().as_bytes().eq_ignore_ascii_case(&key)
418412
})
@@ -424,13 +418,32 @@ fn search_maps(
424418
return true;
425419
}
426420
let name = info.name.to_smol_str();
421+
// FIXME: Deduplicate this from ide-db
427422
match query.search_mode {
428-
SearchMode::Exact => name == query.query,
429-
SearchMode::Prefix => name.starts_with(&query.query),
423+
SearchMode::Exact => !query.case_sensitive || name == query.query,
424+
SearchMode::Prefix => {
425+
query.query.len() <= name.len() && {
426+
let prefix = &name[..query.query.len() as usize];
427+
if query.case_sensitive {
428+
prefix == query.query
429+
} else {
430+
prefix.eq_ignore_ascii_case(&query.query)
431+
}
432+
}
433+
}
430434
SearchMode::Fuzzy => {
431435
let mut name = &*name;
432436
query.query.chars().all(|query_char| {
433-
match name.match_indices(query_char).next() {
437+
let m = if query.case_sensitive {
438+
name.match_indices(query_char).next()
439+
} else {
440+
name.match_indices([
441+
query_char,
442+
query_char.to_ascii_uppercase(),
443+
])
444+
.next()
445+
};
446+
match m {
434447
Some((index, _)) => {
435448
name = &name[index + 1..];
436449
true
@@ -442,10 +455,6 @@ fn search_maps(
442455
}
443456
});
444457
res.extend(iter.map(TupleExt::head));
445-
446-
if res.len() >= query.limit {
447-
return res;
448-
}
449458
}
450459
}
451460

@@ -1015,32 +1024,4 @@ pub mod fmt {
10151024
"#]],
10161025
);
10171026
}
1018-
1019-
#[test]
1020-
fn search_limit() {
1021-
check_search(
1022-
r#"
1023-
//- /main.rs crate:main deps:dep
1024-
//- /dep.rs crate:dep
1025-
pub mod fmt {
1026-
pub trait Display {
1027-
fn fmt();
1028-
}
1029-
}
1030-
#[macro_export]
1031-
macro_rules! Fmt {
1032-
() => {};
1033-
}
1034-
pub struct Fmt;
1035-
1036-
pub fn format() {}
1037-
pub fn no() {}
1038-
"#,
1039-
"main",
1040-
Query::new("".to_string()).fuzzy().limit(1),
1041-
expect![[r#"
1042-
dep::fmt::Display (t)
1043-
"#]],
1044-
);
1045-
}
10461027
}

crates/hir/src/symbols.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<'a> SymbolCollector<'a> {
163163
}
164164

165165
// Record renamed imports.
166-
// In case it imports multiple items under different namespaces we just pick one arbitrarily
166+
// FIXME: In case it imports multiple items under different namespaces we just pick one arbitrarily
167167
// for now.
168168
for id in scope.imports() {
169169
let loc = id.import.lookup(self.db.upcast());

crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ pub(crate) fn replace_derive_with_manual_impl(
7474
current_crate,
7575
NameToImport::exact_case_sensitive(path.segments().last()?.to_string()),
7676
items_locator::AssocSearchMode::Exclude,
77-
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
7877
)
7978
.filter_map(|item| match item.as_module_def()? {
8079
ModuleDef::Trait(trait_) => Some(trait_),

crates/ide-completion/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ pub fn resolve_completion_edits(
256256
current_crate,
257257
NameToImport::exact_case_sensitive(imported_name),
258258
items_locator::AssocSearchMode::Include,
259-
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
260259
);
261260
let import = items_with_name
262261
.filter_map(|candidate| {

crates/ide-db/src/imports/import_assets.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -333,22 +333,22 @@ fn path_applicable_imports(
333333
//
334334
// see also an ignored test under FIXME comment in the qualify_path.rs module
335335
AssocSearchMode::Exclude,
336-
Some(DEFAULT_QUERY_SEARCH_LIMIT.inner()),
337336
)
338337
.filter_map(|item| {
339338
let mod_path = mod_path(item)?;
340339
Some(LocatedImport::new(mod_path, item, item))
341340
})
341+
.take(DEFAULT_QUERY_SEARCH_LIMIT.inner())
342342
.collect()
343343
}
344344
Some(qualifier) => items_locator::items_with_name(
345345
sema,
346346
current_crate,
347347
path_candidate.name.clone(),
348348
AssocSearchMode::Include,
349-
Some(DEFAULT_QUERY_SEARCH_LIMIT.inner()),
350349
)
351350
.filter_map(|item| import_for_item(sema.db, mod_path, &qualifier, item))
351+
.take(DEFAULT_QUERY_SEARCH_LIMIT.inner())
352352
.collect(),
353353
}
354354
}
@@ -505,7 +505,6 @@ fn trait_applicable_items(
505505
current_crate,
506506
trait_candidate.assoc_item_name.clone(),
507507
AssocSearchMode::AssocItemsOnly,
508-
Some(DEFAULT_QUERY_SEARCH_LIMIT.inner()),
509508
)
510509
.filter_map(|input| item_as_assoc(db, input))
511510
.filter_map(|assoc| {
@@ -517,6 +516,7 @@ fn trait_applicable_items(
517516
Some(assoc_item_trait.into())
518517
}
519518
})
519+
.take(DEFAULT_QUERY_SEARCH_LIMIT.inner())
520520
.collect();
521521

522522
let mut located_imports = FxHashSet::default();

crates/ide-db/src/items_locator.rs

+12-25
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,24 @@ pub fn items_with_name<'a>(
1919
krate: Crate,
2020
name: NameToImport,
2121
assoc_item_search: AssocSearchMode,
22-
limit: Option<usize>,
2322
) -> impl Iterator<Item = ItemInNs> + 'a {
2423
let _p = profile::span("items_with_name").detail(|| {
2524
format!(
26-
"Name: {}, crate: {:?}, assoc items: {:?}, limit: {:?}",
25+
"Name: {}, crate: {:?}, assoc items: {:?}",
2726
name.text(),
2827
assoc_item_search,
2928
krate.display_name(sema.db).map(|name| name.to_string()),
30-
limit,
3129
)
3230
});
3331

3432
let prefix = matches!(name, NameToImport::Prefix(..));
35-
let (mut local_query, mut external_query) = match name {
33+
let (local_query, external_query) = match name {
3634
NameToImport::Prefix(exact_name, case_sensitive)
3735
| NameToImport::Exact(exact_name, case_sensitive) => {
3836
let mut local_query = symbol_index::Query::new(exact_name.clone());
37+
local_query.assoc_search_mode(assoc_item_search);
3938
let mut external_query =
40-
// import_map::Query::new(exact_name).assoc_search_mode(assoc_item_search);
41-
import_map::Query::new(exact_name);
39+
import_map::Query::new(exact_name).assoc_search_mode(assoc_item_search);
4240
if prefix {
4341
local_query.prefix();
4442
external_query = external_query.prefix();
@@ -55,6 +53,7 @@ pub fn items_with_name<'a>(
5553
NameToImport::Fuzzy(fuzzy_search_string, case_sensitive) => {
5654
let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());
5755
local_query.fuzzy();
56+
local_query.assoc_search_mode(assoc_item_search);
5857

5958
let mut external_query = import_map::Query::new(fuzzy_search_string.clone())
6059
.fuzzy()
@@ -69,18 +68,12 @@ pub fn items_with_name<'a>(
6968
}
7069
};
7170

72-
if let Some(limit) = limit {
73-
external_query = external_query.limit(limit);
74-
local_query.limit(limit);
75-
}
76-
77-
find_items(sema, krate, assoc_item_search, local_query, external_query)
71+
find_items(sema, krate, local_query, external_query)
7872
}
7973

8074
fn find_items<'a>(
8175
sema: &'a Semantics<'_, RootDatabase>,
8276
krate: Crate,
83-
assoc_item_search: AssocSearchMode,
8477
local_query: symbol_index::Query,
8578
external_query: import_map::Query,
8679
) -> impl Iterator<Item = ItemInNs> + 'a {
@@ -98,18 +91,12 @@ fn find_items<'a>(
9891
});
9992

10093
// Query the local crate using the symbol index.
101-
let local_results = local_query
102-
.search(&symbol_index::crate_symbols(db, krate))
103-
.into_iter()
104-
.filter(move |candidate| match assoc_item_search {
105-
AssocSearchMode::Include => true,
106-
AssocSearchMode::Exclude => !candidate.is_assoc,
107-
AssocSearchMode::AssocItemsOnly => candidate.is_assoc,
108-
})
109-
.map(|local_candidate| match local_candidate.def {
94+
let mut local_results = Vec::new();
95+
local_query.search(&symbol_index::crate_symbols(db, krate), |local_candidate| {
96+
local_results.push(match local_candidate.def {
11097
hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
11198
def => ItemInNs::from(def),
112-
});
113-
114-
external_importables.chain(local_results)
99+
})
100+
});
101+
local_results.into_iter().chain(external_importables)
115102
}

0 commit comments

Comments
 (0)