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 | 55 |
1 files changed, 11 insertions, 44 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index 3a3effae03..f0a4b9bf85 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -295,7 +295,7 @@ pub struct CrateData { impl CrateData { /// Check if [`other`] is almost equal to [`self`] ignoring `CrateOrigin` value. - fn eq_ignoring_origin_and_deps(&self, other: &CrateData, ignore_dev_deps: bool) -> bool { + pub fn eq_ignoring_origin_and_deps(&self, other: &CrateData, ignore_dev_deps: bool) -> bool { // This method has some obscure bits. These are mostly there to be compliant with // some patches. References to the patches are given. if self.root_file_id != other.root_file_id { @@ -622,8 +622,9 @@ impl CrateGraph { &mut self, mut other: CrateGraph, proc_macros: &mut ProcMacroPaths, - may_merge: impl Fn((CrateId, &CrateData), (CrateId, &CrateData)) -> bool, + merge: impl Fn((CrateId, &mut CrateData), (CrateId, &CrateData)) -> bool, ) -> FxHashMap<CrateId, CrateId> { + let m = self.len(); let topo = other.crates_in_topological_order(); let mut id_map: FxHashMap<CrateId, CrateId> = FxHashMap::default(); for topo in topo { @@ -631,48 +632,14 @@ 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 res = self.arena.iter().find_map(|(id, data)| { - if !may_merge((id, &data), (topo, &crate_data)) { - return None; - } - - match (&data.origin, &crate_data.origin) { - (a, b) if a == b => { - if data.eq_ignoring_origin_and_deps(crate_data, false) { - return Some((id, false)); - } - } - (a @ CrateOrigin::Local { .. }, CrateOrigin::Library { .. }) - | (a @ CrateOrigin::Library { .. }, CrateOrigin::Local { .. }) => { - // If the origins differ, check if the two crates are equal without - // considering the dev dependencies, if they are, they most likely are in - // different loaded workspaces which may cause issues. We keep the local - // version and discard the library one as the local version may have - // dev-dependencies that we want to keep resolving. See #15656 for more - // information. - if data.eq_ignoring_origin_and_deps(crate_data, true) { - return Some((id, !a.is_local())); - } - } - (_, _) => return None, - } - - None - }); - - let new_id = if let Some((res, should_update_lib_to_local)) = res { - if should_update_lib_to_local { - assert!(self.arena[res].origin.is_lib()); - assert!(crate_data.origin.is_local()); - self.arena[res].origin = crate_data.origin.clone(); - - // Move local's dev dependencies into the newly-local-formerly-lib crate. - self.arena[res].dependencies = crate_data.dependencies.clone(); - } - res - } else { - self.arena.alloc(crate_data.clone()) - }; + let res = self + .arena + .iter_mut() + .take(m) + .find_map(|(id, data)| merge((id, data), (topo, &crate_data)).then_some(id)); + + let new_id = + if let Some(res) = res { res } else { self.arena.alloc(crate_data.clone()) }; id_map.insert(topo, new_id); } |