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 | 84 |
1 files changed, 40 insertions, 44 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index ca09963aef..c4ada9c765 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -9,8 +9,8 @@ use std::{fmt, mem, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc}; use cfg::CfgOptions; -use rustc_hash::FxHashMap; -use stdx::hash::{NoHashHashMap, NoHashHashSet}; +use la_arena::{Arena, Idx, RawIdx}; +use rustc_hash::{FxHashMap, FxHashSet}; use syntax::SmolStr; use tt::token_id::Subtree; use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; @@ -84,17 +84,22 @@ impl SourceRoot { /// /// `CrateGraph` is `!Serialize` by design, see /// <https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/architecture.md#serialization> -#[derive(Debug, Clone, Default /* Serialize, Deserialize */)] +#[derive(Clone, Default)] pub struct CrateGraph { - arena: NoHashHashMap<CrateId, CrateData>, + arena: Arena<CrateData>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct CrateId(pub u32); +impl fmt::Debug for CrateGraph { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_map() + .entries(self.arena.iter().map(|(id, data)| (u32::from(id.into_raw()), data))) + .finish() + } +} -impl stdx::hash::NoHashHashable for CrateId {} +pub type CrateId = Idx<CrateData>; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct CrateName(SmolStr); impl CrateName { @@ -182,7 +187,7 @@ impl fmt::Display for LangCrateOrigin { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct CrateDisplayName { // The name we use to display various paths (with `_`). crate_name: CrateName, @@ -261,7 +266,7 @@ pub struct ProcMacro { pub expander: Arc<dyn ProcMacroExpander>, } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum ReleaseChannel { Stable, Beta, @@ -287,7 +292,7 @@ impl ReleaseChannel { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct CrateData { pub root_file_id: FileId, pub edition: Edition, @@ -327,7 +332,7 @@ pub struct Env { entries: FxHashMap<String, String>, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Dependency { pub crate_id: CrateId, pub name: CrateName, @@ -378,10 +383,7 @@ impl CrateGraph { is_proc_macro, channel, }; - let crate_id = CrateId(self.arena.len() as u32); - let prev = self.arena.insert(crate_id, data); - assert!(prev.is_none()); - crate_id + self.arena.alloc(data) } pub fn add_dep( @@ -394,14 +396,14 @@ impl CrateGraph { // Check if adding a dep from `from` to `to` creates a cycle. To figure // that out, look for a path in the *opposite* direction, from `to` to // `from`. - if let Some(path) = self.find_path(&mut NoHashHashSet::default(), dep.crate_id, from) { + if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) { let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect(); let err = CyclicDependenciesError { path }; assert!(err.from().0 == from && err.to().0 == dep.crate_id); return Err(err); } - self.arena.get_mut(&from).unwrap().add_dep(dep); + self.arena[from].add_dep(dep); Ok(()) } @@ -410,14 +412,14 @@ impl CrateGraph { } pub fn iter(&self) -> impl Iterator<Item = CrateId> + '_ { - self.arena.keys().copied() + self.arena.iter().map(|(idx, _)| idx) } /// Returns an iterator over all transitive dependencies of the given crate, /// including the crate itself. pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> { let mut worklist = vec![of]; - let mut deps = NoHashHashSet::default(); + let mut deps = FxHashSet::default(); while let Some(krate) = worklist.pop() { if !deps.insert(krate) { @@ -434,11 +436,11 @@ impl CrateGraph { /// including the crate itself. pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> { let mut worklist = vec![of]; - let mut rev_deps = NoHashHashSet::default(); + let mut rev_deps = FxHashSet::default(); rev_deps.insert(of); - let mut inverted_graph = NoHashHashMap::<_, Vec<_>>::default(); - self.arena.iter().for_each(|(&krate, data)| { + let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); + self.arena.iter().for_each(|(krate, data)| { data.dependencies .iter() .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) @@ -461,9 +463,9 @@ impl CrateGraph { /// come before the crate itself). pub fn crates_in_topological_order(&self) -> Vec<CrateId> { let mut res = Vec::new(); - let mut visited = NoHashHashSet::default(); + let mut visited = FxHashSet::default(); - for krate in self.arena.keys().copied() { + for krate in self.iter() { go(self, &mut visited, &mut res, krate); } @@ -471,7 +473,7 @@ impl CrateGraph { fn go( graph: &CrateGraph, - visited: &mut NoHashHashSet<CrateId>, + visited: &mut FxHashSet<CrateId>, res: &mut Vec<CrateId>, source: CrateId, ) { @@ -487,7 +489,7 @@ impl CrateGraph { // FIXME: this only finds one crate with the given root; we could have multiple pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { - let (&crate_id, _) = + let (crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.root_file_id == file_id)?; Some(crate_id) } @@ -499,24 +501,26 @@ impl CrateGraph { /// amount. pub fn extend(&mut self, other: CrateGraph, proc_macros: &mut ProcMacroPaths) -> u32 { let start = self.arena.len() as u32; - self.arena.extend(other.arena.into_iter().map(|(id, mut data)| { - let new_id = id.shift(start); + self.arena.extend(other.arena.into_iter().map(|(_, mut data)| { for dep in &mut data.dependencies { - dep.crate_id = dep.crate_id.shift(start); + dep.crate_id = + CrateId::from_raw(RawIdx::from(u32::from(dep.crate_id.into_raw()) + start)); } - (new_id, data) + data })); *proc_macros = mem::take(proc_macros) .into_iter() - .map(|(id, macros)| (id.shift(start), macros)) + .map(|(id, macros)| { + (CrateId::from_raw(RawIdx::from(u32::from(id.into_raw()) + start)), macros) + }) .collect(); start } fn find_path( &self, - visited: &mut NoHashHashSet<CrateId>, + visited: &mut FxHashSet<CrateId>, from: CrateId, to: CrateId, ) -> Option<Vec<CrateId>> { @@ -546,10 +550,8 @@ impl CrateGraph { let std = self.hacky_find_crate("std"); match (cfg_if, std) { (Some(cfg_if), Some(std)) => { - self.arena.get_mut(&cfg_if).unwrap().dependencies.clear(); - self.arena - .get_mut(&std) - .unwrap() + self.arena[cfg_if].dependencies.clear(); + self.arena[std] .dependencies .push(Dependency::new(CrateName::new("cfg_if").unwrap(), cfg_if)); true @@ -566,13 +568,7 @@ impl CrateGraph { impl ops::Index<CrateId> for CrateGraph { type Output = CrateData; fn index(&self, crate_id: CrateId) -> &CrateData { - &self.arena[&crate_id] - } -} - -impl CrateId { - fn shift(self, amount: u32) -> CrateId { - CrateId(self.0 + amount) + &self.arena[crate_id] } } |