7912: Dedupe import map results r=matklad a=SomeoneToIgnore

While debugging https://github.com/rust-analyzer/rust-analyzer/issues/7902, I've found that there are some duplicates are produced during the external dependencies lookup.

I've spotted at least some of the `indexed_value.value` duplicated when typed `Arc` and requested the completions for that, so I've also deduped the `IndexedValue`'s to avoid unnecessary computations.

This helps to show `Arc` in the completion suggestions in a zero dependency project and in `hir` module, but we loose it again in the `ide` module.

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
bors[bot] 2021-03-08 11:15:17 +00:00 committed by GitHub
commit 6952a3b446
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -388,7 +388,7 @@ pub fn search_dependencies<'a>(
db: &'a dyn DefDatabase, db: &'a dyn DefDatabase,
krate: CrateId, krate: CrateId,
query: Query, query: Query,
) -> Vec<ItemInNs> { ) -> FxHashSet<ItemInNs> {
let _p = profile::span("search_dependencies").detail(|| format!("{:?}", query)); let _p = profile::span("search_dependencies").detail(|| format!("{:?}", query));
let graph = db.crate_graph(); let graph = db.crate_graph();
@ -403,9 +403,14 @@ pub fn search_dependencies<'a>(
} }
let mut stream = op.union(); let mut stream = op.union();
let mut res = Vec::new();
let mut all_indexed_values = FxHashSet::default();
while let Some((_, indexed_values)) = stream.next() { while let Some((_, indexed_values)) = stream.next() {
for indexed_value in indexed_values { all_indexed_values.extend(indexed_values.iter().copied());
}
let mut res = FxHashSet::default();
for indexed_value in all_indexed_values {
let import_map = &import_maps[indexed_value.index]; let import_map = &import_maps[indexed_value.index];
let importables = &import_map.importables[indexed_value.value as usize..]; let importables = &import_map.importables[indexed_value.value as usize..];
@ -421,9 +426,7 @@ pub fn search_dependencies<'a>(
let iter = importables let iter = importables
.iter() .iter()
.copied() .copied()
.take_while(|item| { .take_while(|item| common_importables_path_fst == fst_path(&import_map.map[item].path))
common_importables_path_fst == fst_path(&import_map.map[item].path)
})
.filter(|&item| match item_import_kind(item) { .filter(|&item| match item_import_kind(item) {
Some(import_kind) => !query.exclude_import_kinds.contains(&import_kind), Some(import_kind) => !query.exclude_import_kinds.contains(&import_kind),
None => true, None => true,
@ -435,11 +438,9 @@ pub fn search_dependencies<'a>(
res.extend(iter); res.extend(iter);
if res.len() >= query.limit { if res.len() >= query.limit {
res.truncate(query.limit);
return res; return res;
} }
} }
}
res res
} }
@ -821,10 +822,10 @@ mod tests {
Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy), Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::fmt::Display::format_method (a)
dep::fmt::Display (t) dep::fmt::Display (t)
dep::fmt::Display::FMT_CONST (a) dep::fmt::Display::FMT_CONST (a)
dep::fmt::Display::format_function (a) dep::fmt::Display::format_function (a)
dep::fmt::Display::format_method (a)
"#]], "#]],
); );
} }
@ -850,9 +851,9 @@ mod tests {
"main", "main",
Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy).assoc_items_only(), Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy).assoc_items_only(),
expect![[r#" expect![[r#"
dep::fmt::Display::format_method (a)
dep::fmt::Display::FMT_CONST (a) dep::fmt::Display::FMT_CONST (a)
dep::fmt::Display::format_function (a) dep::fmt::Display::format_function (a)
dep::fmt::Display::format_method (a)
"#]], "#]],
); );
@ -911,12 +912,12 @@ mod tests {
Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy), Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::Fmt (t)
dep::Fmt (v)
dep::Fmt (m)
dep::fmt::Display (t)
dep::fmt::Display::fmt (a)
dep::format (f) dep::format (f)
dep::Fmt (v)
dep::fmt::Display (t)
dep::Fmt (t)
dep::fmt::Display::fmt (a)
dep::Fmt (m)
"#]], "#]],
); );
@ -926,10 +927,10 @@ mod tests {
Query::new("fmt".to_string()).search_mode(SearchMode::Equals), Query::new("fmt".to_string()).search_mode(SearchMode::Equals),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::Fmt (t)
dep::Fmt (v) dep::Fmt (v)
dep::Fmt (m) dep::Fmt (t)
dep::fmt::Display::fmt (a) dep::fmt::Display::fmt (a)
dep::Fmt (m)
"#]], "#]],
); );
@ -939,11 +940,11 @@ mod tests {
Query::new("fmt".to_string()).search_mode(SearchMode::Contains), Query::new("fmt".to_string()).search_mode(SearchMode::Contains),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::Fmt (t)
dep::Fmt (v) dep::Fmt (v)
dep::Fmt (m)
dep::fmt::Display (t) dep::fmt::Display (t)
dep::Fmt (t)
dep::fmt::Display::fmt (a) dep::fmt::Display::fmt (a)
dep::Fmt (m)
"#]], "#]],
); );
} }
@ -980,11 +981,11 @@ mod tests {
Query::new("fmt".to_string()), Query::new("fmt".to_string()),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::Fmt (t)
dep::Fmt (v) dep::Fmt (v)
dep::Fmt (m)
dep::fmt::Display (t) dep::fmt::Display (t)
dep::Fmt (t)
dep::fmt::Display::fmt (a) dep::fmt::Display::fmt (a)
dep::Fmt (m)
"#]], "#]],
); );
@ -994,10 +995,10 @@ mod tests {
Query::new("fmt".to_string()).name_only(), Query::new("fmt".to_string()).name_only(),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::Fmt (t)
dep::Fmt (v) dep::Fmt (v)
dep::Fmt (m) dep::Fmt (t)
dep::fmt::Display::fmt (a) dep::fmt::Display::fmt (a)
dep::Fmt (m)
"#]], "#]],
); );
} }
@ -1018,9 +1019,9 @@ mod tests {
Query::new("FMT".to_string()), Query::new("FMT".to_string()),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::FMT (v)
dep::fmt (v) dep::fmt (v)
dep::FMT (t) dep::FMT (t)
dep::FMT (v)
"#]], "#]],
); );
@ -1060,6 +1061,8 @@ mod tests {
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::Fmt (t) dep::Fmt (t)
dep::Fmt (m)
dep::Fmt (v)
"#]], "#]],
); );
} }
@ -1080,9 +1083,9 @@ mod tests {
Query::new("FMT".to_string()), Query::new("FMT".to_string()),
expect![[r#" expect![[r#"
dep::fmt (t) dep::fmt (t)
dep::FMT (v)
dep::fmt (v) dep::fmt (v)
dep::FMT (t) dep::FMT (t)
dep::FMT (v)
"#]], "#]],
); );