Skip to content

Commit 917734c

Browse files
committed
Reduce cargo tool probing in crate graph construction
1 parent 2c171f8 commit 917734c

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

crates/base-db/src/input.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,10 @@ impl Env {
867867
pub fn insert(&mut self, k: impl Into<String>, v: impl Into<String>) -> Option<String> {
868868
self.entries.insert(k.into(), v.into())
869869
}
870+
871+
pub fn contains_key(&self, arg: &str) -> bool {
872+
self.entries.contains_key(arg)
873+
}
870874
}
871875

872876
impl From<Env> for Vec<(String, String)> {

crates/project-model/src/env.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
use base_db::Env;
33
use paths::Utf8Path;
44
use rustc_hash::FxHashMap;
5-
use toolchain::Tool;
65

76
use crate::{ManifestPath, PackageData, TargetKind, cargo_config_file::CargoConfigFile};
87

@@ -48,8 +47,8 @@ pub(crate) fn inject_cargo_package_env(env: &mut Env, package: &PackageData) {
4847
);
4948
}
5049

51-
pub(crate) fn inject_cargo_env(env: &mut Env) {
52-
env.set("CARGO", Tool::Cargo.path().to_string());
50+
pub(crate) fn inject_cargo_env(env: &mut Env, cargo_path: &Utf8Path) {
51+
env.set("CARGO", cargo_path.as_str());
5352
}
5453

5554
pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: TargetKind) {

crates/project-model/src/sysroot.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use core::fmt;
88
use std::{env, fs, ops::Not, path::Path, process::Command};
99

1010
use anyhow::{Result, format_err};
11+
use base_db::Env;
1112
use itertools::Itertools;
1213
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
1314
use rustc_hash::FxHashMap;
@@ -172,6 +173,32 @@ impl Sysroot {
172173
}
173174
}
174175

176+
pub fn tool_path(&self, tool: Tool, current_dir: impl AsRef<Path>, envs: &Env) -> Utf8PathBuf {
177+
match self.root() {
178+
Some(root) => {
179+
let mut cmd = toolchain::command(
180+
Tool::Rustup.path(),
181+
current_dir,
182+
&envs
183+
.into_iter()
184+
.map(|(k, v)| (k.clone(), Some(v.clone())))
185+
.collect::<FxHashMap<_, _>>(),
186+
);
187+
if !envs.contains_key("RUSTUP_TOOLCHAIN")
188+
&& std::env::var_os("RUSTUP_TOOLCHAIN").is_none()
189+
{
190+
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(root));
191+
}
192+
193+
cmd.arg("which");
194+
cmd.arg(tool.name());
195+
(|| Some(Utf8PathBuf::from(String::from_utf8(cmd.output().ok()?.stdout).ok()?)))()
196+
.unwrap_or_else(|| Utf8PathBuf::from(tool.name()))
197+
}
198+
_ => tool.path(),
199+
}
200+
}
201+
175202
pub fn discover_proc_macro_srv(&self) -> Option<anyhow::Result<AbsPathBuf>> {
176203
let root = self.root()?;
177204
Some(

crates/project-model/src/workspace.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use base_db::{
1313
};
1414
use cfg::{CfgAtom, CfgDiff, CfgOptions};
1515
use intern::{Symbol, sym};
16-
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
16+
use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf};
1717
use rustc_hash::{FxHashMap, FxHashSet};
1818
use semver::Version;
1919
use span::{Edition, FileId};
@@ -1216,6 +1216,7 @@ fn cargo_to_crate_graph(
12161216
load,
12171217
crate_ws_data.clone(),
12181218
);
1219+
let cargo_path = sysroot.tool_path(Tool::Cargo, cargo.workspace_root(), cargo.env());
12191220

12201221
let cfg_options = CfgOptions::from_iter(rustc_cfg);
12211222

@@ -1290,6 +1291,7 @@ fn cargo_to_crate_graph(
12901291
} else {
12911292
Arc::new(pkg_data.manifest.parent().to_path_buf())
12921293
},
1294+
&cargo_path,
12931295
);
12941296
if let TargetKind::Lib { .. } = kind {
12951297
lib_tgt = Some((crate_id, name.clone()));
@@ -1397,6 +1399,7 @@ fn cargo_to_crate_graph(
13971399
},
13981400
// FIXME: This looks incorrect but I don't think this causes problems.
13991401
crate_ws_data,
1402+
&cargo_path,
14001403
);
14011404
}
14021405
}
@@ -1475,6 +1478,7 @@ fn handle_rustc_crates(
14751478
override_cfg: &CfgOverrides,
14761479
build_scripts: &WorkspaceBuildScripts,
14771480
crate_ws_data: Arc<CrateWorkspaceData>,
1481+
cargo_path: &Utf8Path,
14781482
) {
14791483
let mut rustc_pkg_crates = FxHashMap::default();
14801484
// The root package of the rustc-dev component is rustc_driver, so we match that
@@ -1525,6 +1529,7 @@ fn handle_rustc_crates(
15251529
} else {
15261530
Arc::new(pkg_data.manifest.parent().to_path_buf())
15271531
},
1532+
cargo_path,
15281533
);
15291534
pkg_to_lib_crate.insert(pkg, crate_id);
15301535
// Add dependencies on core / std / alloc for this crate
@@ -1582,11 +1587,12 @@ fn add_target_crate_root(
15821587
build_data: Option<(&BuildScriptOutput, bool)>,
15831588
cfg_options: CfgOptions,
15841589
file_id: FileId,
1585-
cargo_name: &str,
1590+
cargo_crate_name: &str,
15861591
kind: TargetKind,
15871592
origin: CrateOrigin,
15881593
crate_ws_data: Arc<CrateWorkspaceData>,
15891594
proc_macro_cwd: Arc<AbsPathBuf>,
1595+
cargo_path: &Utf8Path,
15901596
) -> CrateBuilderId {
15911597
let edition = pkg.edition;
15921598
let potential_cfg_options = if pkg.features.is_empty() {
@@ -1613,16 +1619,16 @@ fn add_target_crate_root(
16131619

16141620
let mut env = cargo.env().clone();
16151621
inject_cargo_package_env(&mut env, pkg);
1616-
inject_cargo_env(&mut env);
1617-
inject_rustc_tool_env(&mut env, cargo_name, kind);
1622+
inject_cargo_env(&mut env, &cargo_path);
1623+
inject_rustc_tool_env(&mut env, cargo_crate_name, kind);
16181624

16191625
if let Some(envs) = build_data.map(|(it, _)| &it.envs) {
16201626
env.extend_from_other(envs);
16211627
}
16221628
let crate_id = crate_graph.add_crate_root(
16231629
file_id,
16241630
edition,
1625-
Some(CrateDisplayName::from_canonical_name(cargo_name)),
1631+
Some(CrateDisplayName::from_canonical_name(cargo_crate_name)),
16261632
Some(pkg.version.to_string()),
16271633
cfg_options,
16281634
potential_cfg_options,
@@ -1636,7 +1642,9 @@ fn add_target_crate_root(
16361642
let proc_macro = match build_data {
16371643
Some((BuildScriptOutput { proc_macro_dylib_path, .. }, has_errors)) => {
16381644
match proc_macro_dylib_path {
1639-
ProcMacroDylibPath::Path(path) => Ok((cargo_name.to_owned(), path.clone())),
1645+
ProcMacroDylibPath::Path(path) => {
1646+
Ok((cargo_crate_name.to_owned(), path.clone()))
1647+
}
16401648
ProcMacroDylibPath::NotBuilt => Err(ProcMacroLoadingError::NotYetBuilt),
16411649
ProcMacroDylibPath::NotProcMacro | ProcMacroDylibPath::DylibNotFound
16421650
if has_errors =>

0 commit comments

Comments
 (0)