Unnamed repository; edit this file 'description' to name the repository.
Reduce cargo tool probing in crate graph construction
Lukas Wirth 5 months ago
parent 2c171f8 · commit 917734c
-rw-r--r--crates/base-db/src/input.rs4
-rw-r--r--crates/project-model/src/env.rs5
-rw-r--r--crates/project-model/src/sysroot.rs27
-rw-r--r--crates/project-model/src/workspace.rs20
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 =>