Skip to content

Commit 5e1b09b

Browse files
committed
Auto merge of rust-lang#16537 - Veykril:sysroot-tools, r=Veykril
internal: tool discovery prefers sysroot tools Fixes rust-lang/rust-analyzer#15927, Fixes rust-lang/rust-analyzer#16523 After this PR we will look for `cargo` and `rustc` in the sysroot if it was succesfully loaded instead of using the current lookup scheme. This should be more correct than the current approach as that relies on the working directory of the server binary or loade workspace, meaning it can behave a bit odd wrt overrides. Additionally, rust-project.json projects now get the target data layout set so there should be better const eval support now.
2 parents b7972e5 + 8f3209b commit 5e1b09b

File tree

14 files changed

+406
-250
lines changed

14 files changed

+406
-250
lines changed

crates/flycheck/src/lib.rs

+6-3
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

+7-1
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

+14-5
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

+17-8
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

+22-31
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)