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.rs51
1 files changed, 43 insertions, 8 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index e45a81238a..852f36ea71 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -9,7 +9,7 @@
use std::{fmt, mem, ops, str::FromStr};
use cfg::CfgOptions;
-use la_arena::{Arena, Idx};
+use la_arena::{Arena, Idx, RawIdx};
use rustc_hash::{FxHashMap, FxHashSet};
use semver::Version;
use syntax::SmolStr;
@@ -157,6 +157,10 @@ impl CrateOrigin {
pub fn is_lib(&self) -> bool {
matches!(self, CrateOrigin::Library { .. })
}
+
+ pub fn is_lang(&self) -> bool {
+ matches!(self, CrateOrigin::Lang { .. })
+ }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -174,7 +178,7 @@ impl From<&str> for LangCrateOrigin {
match s {
"alloc" => LangCrateOrigin::Alloc,
"core" => LangCrateOrigin::Core,
- "proc-macro" => LangCrateOrigin::ProcMacro,
+ "proc-macro" | "proc_macro" => LangCrateOrigin::ProcMacro,
"std" => LangCrateOrigin::Std,
"test" => LangCrateOrigin::Test,
_ => LangCrateOrigin::Other,
@@ -257,6 +261,7 @@ impl ReleaseChannel {
}
}
+ #[allow(clippy::should_implement_trait)]
pub fn from_str(str: &str) -> Option<Self> {
Some(match str {
"" | "stable" => ReleaseChannel::Stable,
@@ -326,7 +331,7 @@ impl CrateData {
return false;
}
- if let Some(_) = opts.next() {
+ if opts.next().is_some() {
return false;
}
}
@@ -522,7 +527,7 @@ impl CrateGraph {
self.arena.iter().map(|(idx, _)| idx)
}
- // FIXME: used for `handle_hack_cargo_workspace`, should be removed later
+ // FIXME: used for fixing up the toolchain sysroot, should be removed and done differently
#[doc(hidden)]
pub fn iter_mut(&mut self) -> impl Iterator<Item = (CrateId, &mut CrateData)> + '_ {
self.arena.iter_mut()
@@ -619,7 +624,12 @@ impl CrateGraph {
/// This will deduplicate the crates of the graph where possible.
/// Note that for deduplication to fully work, `self`'s crate dependencies must be sorted by crate id.
/// If the crate dependencies were sorted, the resulting graph from this `extend` call will also have the crate dependencies sorted.
- pub fn extend(&mut self, mut other: CrateGraph, proc_macros: &mut ProcMacroPaths) {
+ pub fn extend(
+ &mut self,
+ mut other: CrateGraph,
+ proc_macros: &mut ProcMacroPaths,
+ on_finished: impl FnOnce(&FxHashMap<CrateId, CrateId>),
+ ) {
let topo = other.crates_in_topological_order();
let mut id_map: FxHashMap<CrateId, CrateId> = FxHashMap::default();
for topo in topo {
@@ -630,7 +640,7 @@ impl CrateGraph {
let res = self.arena.iter().find_map(|(id, data)| {
match (&data.origin, &crate_data.origin) {
(a, b) if a == b => {
- if data.eq_ignoring_origin_and_deps(&crate_data, false) {
+ if data.eq_ignoring_origin_and_deps(crate_data, false) {
return Some((id, false));
}
}
@@ -642,8 +652,8 @@ impl CrateGraph {
// 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, if a.is_local() { false } else { true }));
+ if data.eq_ignoring_origin_and_deps(crate_data, true) {
+ return Some((id, !a.is_local()));
}
}
(_, _) => return None,
@@ -670,6 +680,8 @@ impl CrateGraph {
*proc_macros =
mem::take(proc_macros).into_iter().map(|(id, macros)| (id_map[&id], macros)).collect();
+
+ on_finished(&id_map);
}
fn find_path(
@@ -721,6 +733,29 @@ impl CrateGraph {
fn hacky_find_crate<'a>(&'a self, display_name: &'a str) -> impl Iterator<Item = CrateId> + 'a {
self.iter().filter(move |it| self[*it].display_name.as_deref() == Some(display_name))
}
+
+ /// Removes all crates from this crate graph except for the ones in `to_keep` and fixes up the dependencies.
+ /// Returns a mapping from old crate ids to new crate ids.
+ pub fn remove_crates_except(&mut self, to_keep: &[CrateId]) -> Vec<Option<CrateId>> {
+ let mut id_map = vec![None; self.arena.len()];
+ self.arena = std::mem::take(&mut self.arena)
+ .into_iter()
+ .filter_map(|(id, data)| if to_keep.contains(&id) { Some((id, data)) } else { None })
+ .enumerate()
+ .map(|(new_id, (id, data))| {
+ id_map[id.into_raw().into_u32() as usize] =
+ Some(CrateId::from_raw(RawIdx::from_u32(new_id as u32)));
+ data
+ })
+ .collect();
+ for (_, data) in self.arena.iter_mut() {
+ data.dependencies.iter_mut().for_each(|dep| {
+ dep.crate_id =
+ id_map[dep.crate_id.into_raw().into_u32() as usize].expect("crate was filtered")
+ });
+ }
+ id_map
+ }
}
impl ops::Index<CrateId> for CrateGraph {