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.rs | 19 |
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); } |