diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs index 54674a6f0f144..1872d27c567cb 100644 --- a/crates/project-model/src/project_json.rs +++ b/crates/project-model/src/project_json.rs @@ -49,8 +49,7 @@ //! user explores them belongs to that extension (it's totally valid to change //! rust-project.json over time via configuration request!) -use base_db::{CrateDisplayName, CrateId, CrateName, Dependency}; -use la_arena::RawIdx; +use base_db::{CrateDisplayName, CrateName}; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashMap; use serde::{de, Deserialize}; @@ -77,7 +76,7 @@ pub struct Crate { pub root_module: AbsPathBuf, pub(crate) edition: Edition, pub(crate) version: Option, - pub(crate) deps: Vec, + pub(crate) deps: Vec, pub(crate) cfg: Vec, pub(crate) target: Option, pub(crate) env: FxHashMap, @@ -128,16 +127,7 @@ impl ProjectJson { root_module, edition: crate_data.edition.into(), version: crate_data.version.as_ref().map(ToString::to_string), - deps: crate_data - .deps - .into_iter() - .map(|dep_data| { - Dependency::new( - dep_data.name, - CrateId::from_raw(RawIdx::from(dep_data.krate as u32)), - ) - }) - .collect::>(), + deps: crate_data.deps, cfg: crate_data.cfg, target: crate_data.target, env: crate_data.env, @@ -161,11 +151,8 @@ impl ProjectJson { } /// Returns an iterator over the crates in the project. - pub fn crates(&self) -> impl Iterator + '_ { - self.crates - .iter() - .enumerate() - .map(|(idx, krate)| (CrateId::from_raw(RawIdx::from(idx as u32)), krate)) + pub fn crates(&self) -> impl Iterator { + self.crates.iter().enumerate().map(|(idx, krate)| (CrateArrayIdx(idx), krate)) } /// Returns the path to the project's root folder. @@ -188,7 +175,7 @@ struct CrateData { edition: EditionData, #[serde(default)] version: Option, - deps: Vec, + deps: Vec, #[serde(default)] cfg: Vec, target: Option, @@ -227,13 +214,21 @@ impl From for Edition { } } -#[derive(Deserialize, Debug, Clone)] -struct DepData { +/// Identifies a crate by position in the crates array. +/// +/// This will differ from `CrateId` when multiple `ProjectJson` +/// workspaces are loaded. +#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[serde(transparent)] +pub struct CrateArrayIdx(pub usize); + +#[derive(Deserialize, Debug, Clone, Eq, PartialEq)] +pub(crate) struct Dep { /// Identifies a crate by position in the crates array. #[serde(rename = "crate")] - krate: usize, + pub(crate) krate: CrateArrayIdx, #[serde(deserialize_with = "deserialize_crate_name")] - name: CrateName, + pub(crate) name: CrateName, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index b8c5885108d3d..d752b2f32ee5e 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -22,7 +22,7 @@ use crate::{ build_scripts::BuildScriptOutput, cargo_workspace::{DepKind, PackageData, RustLibSource}, cfg_flag::CfgFlag, - project_json::Crate, + project_json::{Crate, CrateArrayIdx}, rustc_cfg::{self, RustcCfgConfig}, sysroot::{SysrootCrate, SysrootMode}, target_data_layout::{self, RustcDataLayoutConfig}, @@ -878,12 +878,13 @@ fn project_json_to_crate_graph( let r_a_cfg_flag = CfgFlag::Atom("rust_analyzer".to_owned()); let mut cfg_cache: FxHashMap<&str, Vec> = FxHashMap::default(); - let crates: FxHashMap = project + + let idx_to_crate_id: FxHashMap = project .crates() - .filter_map(|(crate_id, krate)| Some((crate_id, krate, load(&krate.root_module)?))) + .filter_map(|(idx, krate)| Some((idx, krate, load(&krate.root_module)?))) .map( |( - crate_id, + idx, Crate { display_name, edition, @@ -939,13 +940,13 @@ fn project_json_to_crate_graph( proc_macros.insert(crate_graph_crate_id, node); } } - (crate_id, crate_graph_crate_id) + (idx, crate_graph_crate_id) }, ) .collect(); - for (from, krate) in project.crates() { - if let Some(&from) = crates.get(&from) { + for (from_idx, krate) in project.crates() { + if let Some(&from) = idx_to_crate_id.get(&from_idx) { if let Some((public_deps, libproc_macro)) = &sysroot_deps { public_deps.add_to_crate_graph(crate_graph, from); if let Some(proc_macro) = libproc_macro { @@ -954,8 +955,8 @@ fn project_json_to_crate_graph( } for dep in &krate.deps { - if let Some(&to) = crates.get(&dep.crate_id) { - add_dep(crate_graph, from, dep.name.clone(), to) + if let Some(&to) = idx_to_crate_id.get(&dep.krate) { + add_dep(crate_graph, from, dep.name.clone(), to); } } }