Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8f3209b

Browse files
committed
internal: tool discovery prefers sysroot tools
1 parent ddf105b commit 8f3209b

File tree

14 files changed

+406
-250
lines changed

14 files changed

+406
-250
lines changed

crates/flycheck/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ impl FlycheckHandle {
8989
id: usize,
9090
sender: Box<dyn Fn(Message) + Send>,
9191
config: FlycheckConfig,
92+
cargo: PathBuf,
9293
workspace_root: AbsPathBuf,
9394
) -> FlycheckHandle {
94-
let actor = FlycheckActor::new(id, sender, config, workspace_root);
95+
let actor = FlycheckActor::new(id, sender, config, cargo, workspace_root);
9596
let (sender, receiver) = unbounded::<StateChange>();
9697
let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
9798
.name("Flycheck".to_owned())
@@ -171,6 +172,7 @@ struct FlycheckActor {
171172
/// Either the workspace root of the workspace we are flychecking,
172173
/// or the project root of the project.
173174
root: AbsPathBuf,
175+
cargo: PathBuf,
174176
/// CargoHandle exists to wrap around the communication needed to be able to
175177
/// run `cargo check` without blocking. Currently the Rust standard library
176178
/// doesn't provide a way to read sub-process output without blocking, so we
@@ -189,10 +191,11 @@ impl FlycheckActor {
189191
id: usize,
190192
sender: Box<dyn Fn(Message) + Send>,
191193
config: FlycheckConfig,
194+
cargo: PathBuf,
192195
workspace_root: AbsPathBuf,
193196
) -> FlycheckActor {
194197
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
195-
FlycheckActor { id, sender, config, root: workspace_root, command_handle: None }
198+
FlycheckActor { id, sender, config, cargo, root: workspace_root, command_handle: None }
196199
}
197200

198201
fn report_progress(&self, progress: Progress) {
@@ -316,7 +319,7 @@ impl FlycheckActor {
316319
ansi_color_output,
317320
target_dir,
318321
} => {
319-
let mut cmd = Command::new(toolchain::cargo());
322+
let mut cmd = Command::new(&self.cargo);
320323
cmd.arg(command);
321324
cmd.current_dir(&self.root);
322325

crates/hir-ty/src/layout/tests.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use chalk_ir::{AdtId, TyKind};
22
use either::Either;
33
use hir_def::db::DefDatabase;
4+
use project_model::target_data_layout::RustcDataLayoutConfig;
45
use rustc_hash::FxHashMap;
56
use test_fixture::WithFixture;
67
use triomphe::Arc;
@@ -15,7 +16,12 @@ use crate::{
1516
mod closure;
1617

1718
fn current_machine_data_layout() -> String {
18-
project_model::target_data_layout::get(None, None, &FxHashMap::default()).unwrap()
19+
project_model::target_data_layout::get(
20+
RustcDataLayoutConfig::Rustc(None),
21+
None,
22+
&FxHashMap::default(),
23+
)
24+
.unwrap()
1925
}
2026

2127
fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutError> {

crates/project-model/src/build_scripts.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ use paths::{AbsPath, AbsPathBuf};
2020
use rustc_hash::{FxHashMap, FxHashSet};
2121
use semver::Version;
2222
use serde::Deserialize;
23+
use toolchain::Tool;
2324

2425
use crate::{
2526
cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
26-
InvocationStrategy, Package,
27+
InvocationStrategy, Package, Sysroot,
2728
};
2829

2930
#[derive(Debug, Default, Clone, PartialEq, Eq)]
@@ -61,6 +62,7 @@ impl WorkspaceBuildScripts {
6162
config: &CargoConfig,
6263
allowed_features: &FxHashSet<String>,
6364
workspace_root: &AbsPathBuf,
65+
sysroot: Option<&Sysroot>,
6466
) -> io::Result<Command> {
6567
let mut cmd = match config.run_build_script_command.as_deref() {
6668
Some([program, args @ ..]) => {
@@ -69,7 +71,10 @@ impl WorkspaceBuildScripts {
6971
cmd
7072
}
7173
_ => {
72-
let mut cmd = Command::new(toolchain::cargo());
74+
let mut cmd = Command::new(
75+
Sysroot::discover_tool(sysroot, Tool::Cargo)
76+
.map_err(|e| io::Error::new(io::ErrorKind::NotFound, e))?,
77+
);
7378

7479
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
7580
cmd.args(&config.extra_args);
@@ -133,6 +138,7 @@ impl WorkspaceBuildScripts {
133138
workspace: &CargoWorkspace,
134139
progress: &dyn Fn(String),
135140
toolchain: &Option<Version>,
141+
sysroot: Option<&Sysroot>,
136142
) -> io::Result<WorkspaceBuildScripts> {
137143
const RUST_1_62: Version = Version::new(1, 62, 0);
138144

@@ -151,6 +157,7 @@ impl WorkspaceBuildScripts {
151157
config,
152158
&allowed_features,
153159
&workspace.workspace_root().to_path_buf(),
160+
sysroot,
154161
)?,
155162
workspace,
156163
current_dir,
@@ -165,6 +172,7 @@ impl WorkspaceBuildScripts {
165172
config,
166173
&allowed_features,
167174
&workspace.workspace_root().to_path_buf(),
175+
sysroot,
168176
)?;
169177
cmd.args(["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
170178
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
@@ -194,7 +202,7 @@ impl WorkspaceBuildScripts {
194202
))
195203
}
196204
};
197-
let cmd = Self::build_command(config, &Default::default(), workspace_root)?;
205+
let cmd = Self::build_command(config, &Default::default(), workspace_root, None)?;
198206
// NB: Cargo.toml could have been modified between `cargo metadata` and
199207
// `cargo check`. We shouldn't assume that package ids we see here are
200208
// exactly those from `config`.
@@ -415,14 +423,15 @@ impl WorkspaceBuildScripts {
415423
rustc: &CargoWorkspace,
416424
current_dir: &AbsPath,
417425
extra_env: &FxHashMap<String, String>,
426+
sysroot: Option<&Sysroot>,
418427
) -> Self {
419428
let mut bs = WorkspaceBuildScripts::default();
420429
for p in rustc.packages() {
421430
bs.outputs.insert(p, BuildScriptOutput::default());
422431
}
423432
let res = (|| {
424433
let target_libdir = (|| {
425-
let mut cargo_config = Command::new(toolchain::cargo());
434+
let mut cargo_config = Command::new(Sysroot::discover_tool(sysroot, Tool::Cargo)?);
426435
cargo_config.envs(extra_env);
427436
cargo_config
428437
.current_dir(current_dir)
@@ -431,7 +440,7 @@ impl WorkspaceBuildScripts {
431440
if let Ok(it) = utf8_stdout(cargo_config) {
432441
return Ok(it);
433442
}
434-
let mut cmd = Command::new(toolchain::rustc());
443+
let mut cmd = Command::new(Sysroot::discover_tool(sysroot, Tool::Rustc)?);
435444
cmd.envs(extra_env);
436445
cmd.args(["--print", "target-libdir"]);
437446
utf8_stdout(cmd)

crates/project-model/src/cargo_workspace.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use paths::{AbsPath, AbsPathBuf};
1212
use rustc_hash::{FxHashMap, FxHashSet};
1313
use serde::Deserialize;
1414
use serde_json::from_value;
15+
use toolchain::Tool;
1516

16-
use crate::{utf8_stdout, InvocationLocation, ManifestPath};
17+
use crate::{utf8_stdout, InvocationLocation, ManifestPath, Sysroot};
1718
use crate::{CfgOverrides, InvocationStrategy};
1819

1920
/// [`CargoWorkspace`] represents the logical structure of, well, a Cargo
@@ -236,12 +237,13 @@ impl CargoWorkspace {
236237
cargo_toml: &ManifestPath,
237238
current_dir: &AbsPath,
238239
config: &CargoConfig,
240+
sysroot: Option<&Sysroot>,
239241
progress: &dyn Fn(String),
240242
) -> anyhow::Result<cargo_metadata::Metadata> {
241-
let targets = find_list_of_build_targets(config, cargo_toml);
243+
let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
242244

243245
let mut meta = MetadataCommand::new();
244-
meta.cargo_path(toolchain::cargo());
246+
meta.cargo_path(Sysroot::discover_tool(sysroot, Tool::Cargo)?);
245247
meta.manifest_path(cargo_toml.to_path_buf());
246248
match &config.features {
247249
CargoFeatures::All => {
@@ -476,24 +478,29 @@ impl CargoWorkspace {
476478
}
477479
}
478480

479-
fn find_list_of_build_targets(config: &CargoConfig, cargo_toml: &ManifestPath) -> Vec<String> {
481+
fn find_list_of_build_targets(
482+
config: &CargoConfig,
483+
cargo_toml: &ManifestPath,
484+
sysroot: Option<&Sysroot>,
485+
) -> Vec<String> {
480486
if let Some(target) = &config.target {
481487
return [target.into()].to_vec();
482488
}
483489

484-
let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env);
490+
let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env, sysroot);
485491
if !build_targets.is_empty() {
486492
return build_targets;
487493
}
488494

489-
rustc_discover_host_triple(cargo_toml, &config.extra_env).into_iter().collect()
495+
rustc_discover_host_triple(cargo_toml, &config.extra_env, sysroot).into_iter().collect()
490496
}
491497

492498
fn rustc_discover_host_triple(
493499
cargo_toml: &ManifestPath,
494500
extra_env: &FxHashMap<String, String>,
501+
sysroot: Option<&Sysroot>,
495502
) -> Option<String> {
496-
let mut rustc = Command::new(toolchain::rustc());
503+
let mut rustc = Command::new(Sysroot::discover_tool(sysroot, Tool::Rustc).ok()?);
497504
rustc.envs(extra_env);
498505
rustc.current_dir(cargo_toml.parent()).arg("-vV");
499506
tracing::debug!("Discovering host platform by {:?}", rustc);
@@ -519,8 +526,10 @@ fn rustc_discover_host_triple(
519526
fn cargo_config_build_target(
520527
cargo_toml: &ManifestPath,
521528
extra_env: &FxHashMap<String, String>,
529+
sysroot: Option<&Sysroot>,
522530
) -> Vec<String> {
523-
let mut cargo_config = Command::new(toolchain::cargo());
531+
let Ok(program) = Sysroot::discover_tool(sysroot, Tool::Cargo) else { return vec![] };
532+
let mut cargo_config = Command::new(program);
524533
cargo_config.envs(extra_env);
525534
cargo_config
526535
.current_dir(cargo_toml.parent())

crates/project-model/src/rustc_cfg.rs

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@ use rustc_hash::FxHashMap;
88
use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
99

1010
/// Determines how `rustc --print cfg` is discovered and invoked.
11-
///
12-
/// There options are supported:
13-
/// - [`RustcCfgConfig::Cargo`], which relies on `cargo rustc --print cfg`
14-
/// and `RUSTC_BOOTSTRAP`.
15-
/// - [`RustcCfgConfig::Explicit`], which uses an explicit path to the `rustc`
16-
/// binary in the sysroot.
17-
/// - [`RustcCfgConfig::Discover`], which uses [`toolchain::rustc`].
1811
pub(crate) enum RustcCfgConfig<'a> {
19-
Cargo(&'a ManifestPath),
20-
Explicit(&'a Sysroot),
21-
Discover,
12+
/// Use `rustc --print cfg`, either from with the binary from the sysroot or by discovering via
13+
/// [`toolchain::rustc`].
14+
Rustc(Option<&'a Sysroot>),
15+
/// Use `cargo --print cfg`, either from with the binary from the sysroot or by discovering via
16+
/// [`toolchain::cargo`].
17+
Cargo(Option<&'a Sysroot>, &'a ManifestPath),
2218
}
2319

2420
pub(crate) fn get(
@@ -71,36 +67,31 @@ fn get_rust_cfgs(
7167
extra_env: &FxHashMap<String, String>,
7268
config: RustcCfgConfig<'_>,
7369
) -> anyhow::Result<String> {
74-
let mut cmd = match config {
75-
RustcCfgConfig::Cargo(cargo_toml) => {
76-
let mut cmd = Command::new(toolchain::cargo());
70+
match config {
71+
RustcCfgConfig::Cargo(sysroot, cargo_oml) => {
72+
let cargo = Sysroot::discover_tool(sysroot, toolchain::Tool::Cargo)?;
73+
let mut cmd = Command::new(cargo);
7774
cmd.envs(extra_env);
78-
cmd.current_dir(cargo_toml.parent())
75+
cmd.current_dir(cargo_oml.parent())
7976
.args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
8077
.env("RUSTC_BOOTSTRAP", "1");
8178
if let Some(target) = target {
8279
cmd.args(["--target", target]);
8380
}
8481

85-
return utf8_stdout(cmd).context("Unable to run `cargo rustc`");
82+
utf8_stdout(cmd).context("Unable to run `cargo rustc`")
8683
}
87-
RustcCfgConfig::Explicit(sysroot) => {
88-
let rustc: std::path::PathBuf = sysroot.discover_rustc()?.into();
84+
RustcCfgConfig::Rustc(sysroot) => {
85+
let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
8986
tracing::debug!(?rustc, "using explicit rustc from sysroot");
90-
Command::new(rustc)
91-
}
92-
RustcCfgConfig::Discover => {
93-
let rustc = toolchain::rustc();
94-
tracing::debug!(?rustc, "using rustc from env");
95-
Command::new(rustc)
96-
}
97-
};
87+
let mut cmd = Command::new(rustc);
88+
cmd.envs(extra_env);
89+
cmd.args(["--print", "cfg", "-O"]);
90+
if let Some(target) = target {
91+
cmd.args(["--target", target]);
92+
}
9893

99-
cmd.envs(extra_env);
100-
cmd.args(["--print", "cfg", "-O"]);
101-
if let Some(target) = target {
102-
cmd.args(["--target", target]);
94+
utf8_stdout(cmd).context("Unable to run `rustc`")
95+
}
10396
}
104-
105-
utf8_stdout(cmd).context("Unable to run `rustc`")
10697
}

0 commit comments

Comments
 (0)