Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/base-db/src/input.rs')
-rw-r--r--crates/base-db/src/input.rs19
1 files changed, 12 insertions, 7 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index e86944eeb3..a0fc8c31ea 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -490,21 +490,25 @@ impl CrateGraph {
}
}
- pub fn sort_deps(&mut self) {
- self.arena
- .iter_mut()
- .for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id));
- }
-
/// Extends this crate graph by adding a complete second crate
/// graph and adjust the ids in the [`ProcMacroPaths`] accordingly.
///
+ /// This will deduplicate the crates of the graph where possible.
+ /// Furthermore dependencies are sorted by crate id to make deduplication easier.
+ ///
/// Returns a map mapping `other`'s IDs to the new IDs in `self`.
pub fn extend(
&mut self,
mut other: CrateGraph,
proc_macros: &mut ProcMacroPaths,
) -> FxHashMap<CrateId, CrateId> {
+ // Sorting here is a bit pointless because the input is likely already sorted.
+ // However, the overhead is small and it makes the `extend` method harder to misuse.
+ self.arena
+ .iter_mut()
+ .for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id));
+
+ let m = self.len();
let topo = other.crates_in_topological_order();
let mut id_map: FxHashMap<CrateId, CrateId> = FxHashMap::default();
for topo in topo {
@@ -513,7 +517,8 @@ impl CrateGraph {
crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
crate_data.dependencies.sort_by_key(|dep| dep.crate_id);
- let new_id = self.arena.alloc(crate_data.clone());
+ let find = self.arena.iter().take(m).find_map(|(k, v)| (v == crate_data).then_some(k));
+ let new_id = find.unwrap_or_else(|| self.arena.alloc(crate_data.clone()));
id_map.insert(topo, new_id);
}