Unnamed repository; edit this file 'description' to name the repository.
Reduce cargo tool probing in crate graph construction
| -rw-r--r-- | crates/base-db/src/input.rs | 4 | ||||
| -rw-r--r-- | crates/project-model/src/env.rs | 5 | ||||
| -rw-r--r-- | crates/project-model/src/sysroot.rs | 27 | ||||
| -rw-r--r-- | crates/project-model/src/workspace.rs | 20 |
4 files changed, 47 insertions, 9 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index cac74778a2..ffd82d5043 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -867,6 +867,10 @@ impl Env { pub fn insert(&mut self, k: impl Into<String>, v: impl Into<String>) -> Option<String> { self.entries.insert(k.into(), v.into()) } + + pub fn contains_key(&self, arg: &str) -> bool { + self.entries.contains_key(arg) + } } impl From<Env> for Vec<(String, String)> { diff --git a/crates/project-model/src/env.rs b/crates/project-model/src/env.rs index ae0458af7a..8089155adf 100644 --- a/crates/project-model/src/env.rs +++ b/crates/project-model/src/env.rs @@ -2,7 +2,6 @@ use base_db::Env; use paths::Utf8Path; use rustc_hash::FxHashMap; -use toolchain::Tool; use crate::{ManifestPath, PackageData, TargetKind, cargo_config_file::CargoConfigFile}; @@ -48,8 +47,8 @@ pub(crate) fn inject_cargo_package_env(env: &mut Env, package: &PackageData) { ); } -pub(crate) fn inject_cargo_env(env: &mut Env) { - env.set("CARGO", Tool::Cargo.path().to_string()); +pub(crate) fn inject_cargo_env(env: &mut Env, cargo_path: &Utf8Path) { + env.set("CARGO", cargo_path.as_str()); } pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: TargetKind) { diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs index 920afe65d7..1b31138bec 100644 --- a/crates/project-model/src/sysroot.rs +++ b/crates/project-model/src/sysroot.rs @@ -8,6 +8,7 @@ use core::fmt; use std::{env, fs, ops::Not, path::Path, process::Command}; use anyhow::{Result, format_err}; +use base_db::Env; use itertools::Itertools; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::FxHashMap; @@ -172,6 +173,32 @@ impl Sysroot { } } + pub fn tool_path(&self, tool: Tool, current_dir: impl AsRef<Path>, envs: &Env) -> Utf8PathBuf { + match self.root() { + Some(root) => { + let mut cmd = toolchain::command( + Tool::Rustup.path(), + current_dir, + &envs + .into_iter() + .map(|(k, v)| (k.clone(), Some(v.clone()))) + .collect::<FxHashMap<_, _>>(), + ); + if !envs.contains_key("RUSTUP_TOOLCHAIN") + && std::env::var_os("RUSTUP_TOOLCHAIN").is_none() + { + cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(root)); + } + + cmd.arg("which"); + cmd.arg(tool.name()); + (|| Some(Utf8PathBuf::from(String::from_utf8(cmd.output().ok()?.stdout).ok()?)))() + .unwrap_or_else(|| Utf8PathBuf::from(tool.name())) + } + _ => tool.path(), + } + } + pub fn discover_proc_macro_srv(&self) -> Option<anyhow::Result<AbsPathBuf>> { let root = self.root()?; Some( diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index d119de37ab..fdb3e23aa1 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -13,7 +13,7 @@ use base_db::{ }; use cfg::{CfgAtom, CfgDiff, CfgOptions}; use intern::{Symbol, sym}; -use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; +use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; use semver::Version; use span::{Edition, FileId}; @@ -1216,6 +1216,7 @@ fn cargo_to_crate_graph( load, crate_ws_data.clone(), ); + let cargo_path = sysroot.tool_path(Tool::Cargo, cargo.workspace_root(), cargo.env()); let cfg_options = CfgOptions::from_iter(rustc_cfg); @@ -1290,6 +1291,7 @@ fn cargo_to_crate_graph( } else { Arc::new(pkg_data.manifest.parent().to_path_buf()) }, + &cargo_path, ); if let TargetKind::Lib { .. } = kind { lib_tgt = Some((crate_id, name.clone())); @@ -1397,6 +1399,7 @@ fn cargo_to_crate_graph( }, // FIXME: This looks incorrect but I don't think this causes problems. crate_ws_data, + &cargo_path, ); } } @@ -1475,6 +1478,7 @@ fn handle_rustc_crates( override_cfg: &CfgOverrides, build_scripts: &WorkspaceBuildScripts, crate_ws_data: Arc<CrateWorkspaceData>, + cargo_path: &Utf8Path, ) { let mut rustc_pkg_crates = FxHashMap::default(); // The root package of the rustc-dev component is rustc_driver, so we match that @@ -1525,6 +1529,7 @@ fn handle_rustc_crates( } else { Arc::new(pkg_data.manifest.parent().to_path_buf()) }, + cargo_path, ); pkg_to_lib_crate.insert(pkg, crate_id); // Add dependencies on core / std / alloc for this crate @@ -1582,11 +1587,12 @@ fn add_target_crate_root( build_data: Option<(&BuildScriptOutput, bool)>, cfg_options: CfgOptions, file_id: FileId, - cargo_name: &str, + cargo_crate_name: &str, kind: TargetKind, origin: CrateOrigin, crate_ws_data: Arc<CrateWorkspaceData>, proc_macro_cwd: Arc<AbsPathBuf>, + cargo_path: &Utf8Path, ) -> CrateBuilderId { let edition = pkg.edition; let potential_cfg_options = if pkg.features.is_empty() { @@ -1613,8 +1619,8 @@ fn add_target_crate_root( let mut env = cargo.env().clone(); inject_cargo_package_env(&mut env, pkg); - inject_cargo_env(&mut env); - inject_rustc_tool_env(&mut env, cargo_name, kind); + inject_cargo_env(&mut env, &cargo_path); + inject_rustc_tool_env(&mut env, cargo_crate_name, kind); if let Some(envs) = build_data.map(|(it, _)| &it.envs) { env.extend_from_other(envs); @@ -1622,7 +1628,7 @@ fn add_target_crate_root( let crate_id = crate_graph.add_crate_root( file_id, edition, - Some(CrateDisplayName::from_canonical_name(cargo_name)), + Some(CrateDisplayName::from_canonical_name(cargo_crate_name)), Some(pkg.version.to_string()), cfg_options, potential_cfg_options, @@ -1636,7 +1642,9 @@ fn add_target_crate_root( let proc_macro = match build_data { Some((BuildScriptOutput { proc_macro_dylib_path, .. }, has_errors)) => { match proc_macro_dylib_path { - ProcMacroDylibPath::Path(path) => Ok((cargo_name.to_owned(), path.clone())), + ProcMacroDylibPath::Path(path) => { + Ok((cargo_crate_name.to_owned(), path.clone())) + } ProcMacroDylibPath::NotBuilt => Err(ProcMacroLoadingError::NotYetBuilt), ProcMacroDylibPath::NotProcMacro | ProcMacroDylibPath::DylibNotFound if has_errors => |