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 | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index 9660e6e87c..745238167b 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -14,7 +14,7 @@ use dashmap::DashMap; use dashmap::mapref::entry::Entry; use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; -use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet, FxHasher}; use salsa::{Durability, Setter}; use span::Edition; use triomphe::Arc; @@ -24,6 +24,8 @@ use crate::{CrateWorkspaceData, EditionedFileId, RootQueryDb}; pub type ProcMacroPaths = FxHashMap<CrateBuilderId, Result<(String, AbsPathBuf), String>>; +type FxIndexSet<T> = indexmap::IndexSet<T, FxBuildHasher>; + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct SourceRootId(pub u32); @@ -393,21 +395,21 @@ impl BuiltDependency { pub type CratesIdMap = FxHashMap<CrateBuilderId, Crate>; #[salsa_macros::input] -#[derive(Debug)] +#[derive(Debug, PartialOrd, Ord)] pub struct Crate { - #[return_ref] + #[returns(ref)] pub data: BuiltCrateData, /// Crate data that is not needed for analysis. /// /// This is split into a separate field to increase incrementality. - #[return_ref] + #[returns(ref)] pub extra_data: ExtraCrateData, // This is in `Arc` because it is shared for all crates in a workspace. - #[return_ref] + #[returns(ref)] pub workspace_data: Arc<CrateWorkspaceData>, - #[return_ref] + #[returns(ref)] pub cfg_options: CfgOptions, - #[return_ref] + #[returns(ref)] pub env: Env, } @@ -474,7 +476,9 @@ impl CrateGraphBuilder { } pub fn set_in_db(self, db: &mut dyn RootQueryDb) -> CratesIdMap { - let mut all_crates = Vec::with_capacity(self.arena.len()); + // For some reason in some repositories we have duplicate crates, so we use a set and not `Vec`. + // We use an `IndexSet` because the list needs to be topologically sorted. + let mut all_crates = FxIndexSet::with_capacity_and_hasher(self.arena.len(), FxBuildHasher); let mut visited = FxHashMap::default(); let mut visited_root_files = FxHashSet::default(); @@ -494,9 +498,11 @@ impl CrateGraphBuilder { ); } - if **old_all_crates != *all_crates { + if old_all_crates.len() != all_crates.len() + || old_all_crates.iter().any(|&krate| !all_crates.contains(&krate)) + { db.set_all_crates_with_durability( - Arc::new(all_crates.into_boxed_slice()), + Arc::new(Vec::from_iter(all_crates).into_boxed_slice()), Durability::MEDIUM, ); } @@ -509,7 +515,7 @@ impl CrateGraphBuilder { crates_map: &CratesMap, visited: &mut FxHashMap<CrateBuilderId, Crate>, visited_root_files: &mut FxHashSet<FileId>, - all_crates: &mut Vec<Crate>, + all_crates: &mut FxIndexSet<Crate>, source: CrateBuilderId, ) -> Crate { if let Some(&crate_id) = visited.get(&source) { @@ -597,7 +603,7 @@ impl CrateGraphBuilder { input } }; - all_crates.push(crate_input); + all_crates.insert(crate_input); visited.insert(source, crate_input); crate_input } |