Skip to content

Commit 74e5444

Browse files
committed
Fix some FIXMEs
1 parent ba61766 commit 74e5444

File tree

2 files changed

+58
-45
lines changed

2 files changed

+58
-45
lines changed

crates/hir-def/src/import_map.rs

+57-44
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
2323

2424
/// Item import details stored in the `ImportMap`.
25-
#[derive(Debug, Clone, Eq, PartialEq)]
25+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
2626
pub struct ImportInfo {
2727
/// A name that can be used to import the item, relative to the crate's root.
2828
pub name: Name,
@@ -78,7 +78,8 @@ impl ImportMap {
7878

7979
// Build the FST, taking care not to insert duplicate values.
8080
let mut builder = fst::MapBuilder::memory();
81-
let iter = importables.iter().enumerate().dedup_by(|lhs, rhs| lhs.1 .1 == rhs.1 .1);
81+
let iter =
82+
importables.iter().enumerate().dedup_by(|(_, (_, lhs)), (_, (_, rhs))| lhs == rhs);
8283
for (start_idx, (_, name)) in iter {
8384
let _ = builder.insert(name, start_idx as u64);
8485
}
@@ -128,7 +129,6 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMapIndex {
128129
}
129130
});
130131

131-
// FIXME: This loop might add the same entry up to 3 times per item! dedup
132132
for (name, per_ns) in visible_items {
133133
for (item, import) in per_ns.iter_items() {
134134
let attr_id = if let Some(import) = import {
@@ -164,10 +164,10 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMapIndex {
164164
);
165165
}
166166

167-
map.entry(item)
168-
.or_insert_with(|| (SmallVec::new(), IsTraitAssocItem::No))
169-
.0
170-
.push(import_info);
167+
let (infos, _) =
168+
map.entry(item).or_insert_with(|| (SmallVec::new(), IsTraitAssocItem::No));
169+
infos.reserve_exact(1);
170+
infos.push(import_info);
171171

172172
// If we've just added a module, descend into it.
173173
if let Some(ModuleDefId::ModuleId(mod_id)) = item.as_module_def_id() {
@@ -213,10 +213,10 @@ fn collect_trait_assoc_items(
213213
is_unstable: attrs.is_unstable(),
214214
};
215215

216-
map.entry(assoc_item)
217-
.or_insert_with(|| (SmallVec::new(), IsTraitAssocItem::Yes))
218-
.0
219-
.push(assoc_item_info);
216+
let (infos, _) =
217+
map.entry(assoc_item).or_insert_with(|| (SmallVec::new(), IsTraitAssocItem::Yes));
218+
infos.reserve_exact(1);
219+
infos.push(assoc_item_info);
220220
}
221221
}
222222

@@ -234,10 +234,13 @@ impl fmt::Debug for ImportMap {
234234
let mut importable_names: Vec<_> = self
235235
.map
236236
.iter()
237-
.map(|(item, _)| match item {
238-
ItemInNs::Types(it) => format!("- {it:?} (t)",),
239-
ItemInNs::Values(it) => format!("- {it:?} (v)",),
240-
ItemInNs::Macros(it) => format!("- {it:?} (m)",),
237+
.map(|(item, (infos, _))| {
238+
let l = infos.len();
239+
match item {
240+
ItemInNs::Types(it) => format!("- {it:?} (t) [{l}]",),
241+
ItemInNs::Values(it) => format!("- {it:?} (v) [{l}]",),
242+
ItemInNs::Macros(it) => format!("- {it:?} (m) [{l}]",),
243+
}
241244
})
242245
.collect();
243246

@@ -368,7 +371,7 @@ impl Query {
368371
pub fn search_dependencies(
369372
db: &dyn DefDatabase,
370373
krate: CrateId,
371-
query: Query,
374+
ref query: Query,
372375
) -> FxHashSet<ItemInNs> {
373376
let _p = profile::span("search_dependencies").detail(|| format!("{query:?}"));
374377

@@ -386,6 +389,7 @@ pub fn search_dependencies(
386389
let mut stream = op.union();
387390

388391
let mut res = FxHashSet::default();
392+
let mut common_importable_data_scratch = vec![];
389393
while let Some((_, indexed_values)) = stream.next() {
390394
for &IndexedValue { index, value } in indexed_values {
391395
let import_map = &import_maps[index];
@@ -398,36 +402,45 @@ pub fn search_dependencies(
398402
continue;
399403
}
400404

401-
// FIXME: We probably need to account for other possible matches in this alias group?
402-
let Some(common_importable_data) =
403-
importable_data.iter().find(|&info| query.import_matches(db, info, true))
404-
else {
405+
common_importable_data_scratch.extend(
406+
importable_data
407+
.iter()
408+
.filter(|&info| query.import_matches(db, info, true))
409+
// Name shared by the importable items in this group.
410+
.map(|info| info.name.to_smol_str()),
411+
);
412+
if common_importable_data_scratch.is_empty() {
405413
continue;
406-
};
407-
408-
// FIXME: so many allocs...
409-
// Name shared by the importable items in this group.
410-
let common_importable_name =
411-
common_importable_data.name.to_smol_str().to_ascii_lowercase();
412-
// Add the items from this name group. Those are all subsequent items in
413-
// `importables` whose name match `common_importable_name`.
414-
let iter = importables
415-
.iter()
416-
.copied()
417-
.take_while(|item| {
418-
let &(ref import_infos, assoc_mode) = &import_map.map[item];
419-
query.matches_assoc_mode(assoc_mode)
420-
&& import_infos.iter().any(|info| {
421-
info.name.to_smol_str().to_ascii_lowercase() == common_importable_name
414+
}
415+
common_importable_data_scratch.sort();
416+
common_importable_data_scratch.dedup();
417+
418+
let iter =
419+
common_importable_data_scratch.drain(..).flat_map(|common_importable_name| {
420+
// Add the items from this name group. Those are all subsequent items in
421+
// `importables` whose name match `common_importable_name`.
422+
importables
423+
.iter()
424+
.copied()
425+
.take_while(move |item| {
426+
let &(ref import_infos, assoc_mode) = &import_map.map[item];
427+
query.matches_assoc_mode(assoc_mode)
428+
&& import_infos.iter().any(|info| {
429+
info.name
430+
.to_smol_str()
431+
.eq_ignore_ascii_case(&common_importable_name)
432+
})
433+
})
434+
.filter(move |item| {
435+
!query.case_sensitive || {
436+
// we've already checked the common importables name case-insensitively
437+
let &(ref import_infos, assoc_mode) = &import_map.map[item];
438+
query.matches_assoc_mode(assoc_mode)
439+
&& import_infos
440+
.iter()
441+
.any(|info| query.import_matches(db, info, false))
442+
}
422443
})
423-
})
424-
.filter(|item| {
425-
!query.case_sensitive || {
426-
// we've already checked the common importables name case-insensitively
427-
let &(ref import_infos, assoc_mode) = &import_map.map[item];
428-
query.matches_assoc_mode(assoc_mode)
429-
&& import_infos.iter().any(|info| query.import_matches(db, info, false))
430-
}
431444
});
432445
res.extend(iter);
433446

crates/hir-def/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl TryFrom<ModuleId> for CrateRootModuleId {
152152
}
153153
}
154154

155-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
156156
pub struct ModuleId {
157157
krate: CrateId,
158158
/// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the

0 commit comments

Comments
 (0)