Skip to content

Commit 465ddef

Browse files
committed
fix: Set RUSTUP_TOOLCHAIN and invoke the proxies instead of directly invoking sysroot binaries
1 parent 000ce5d commit 465ddef

File tree

9 files changed

+82
-79
lines changed

9 files changed

+82
-79
lines changed

crates/flycheck/src/lib.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub use cargo_metadata::diagnostic::{
2323
Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
2424
DiagnosticSpanMacroExpansion,
2525
};
26+
use toolchain::Tool;
2627

2728
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
2829
pub enum InvocationStrategy {
@@ -89,10 +90,10 @@ impl FlycheckHandle {
8990
id: usize,
9091
sender: Box<dyn Fn(Message) + Send>,
9192
config: FlycheckConfig,
92-
cargo: PathBuf,
93+
sysroot_root: Option<AbsPathBuf>,
9394
workspace_root: AbsPathBuf,
9495
) -> FlycheckHandle {
95-
let actor = FlycheckActor::new(id, sender, config, cargo, workspace_root);
96+
let actor = FlycheckActor::new(id, sender, config, sysroot_root, workspace_root);
9697
let (sender, receiver) = unbounded::<StateChange>();
9798
let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker)
9899
.name("Flycheck".to_owned())
@@ -174,7 +175,7 @@ struct FlycheckActor {
174175
/// Either the workspace root of the workspace we are flychecking,
175176
/// or the project root of the project.
176177
root: AbsPathBuf,
177-
cargo: PathBuf,
178+
sysroot_root: Option<AbsPathBuf>,
178179
/// CargoHandle exists to wrap around the communication needed to be able to
179180
/// run `cargo check` without blocking. Currently the Rust standard library
180181
/// doesn't provide a way to read sub-process output without blocking, so we
@@ -195,11 +196,18 @@ impl FlycheckActor {
195196
id: usize,
196197
sender: Box<dyn Fn(Message) + Send>,
197198
config: FlycheckConfig,
198-
cargo: PathBuf,
199+
sysroot_root: Option<AbsPathBuf>,
199200
workspace_root: AbsPathBuf,
200201
) -> FlycheckActor {
201202
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
202-
FlycheckActor { id, sender, config, cargo, root: workspace_root, command_handle: None }
203+
FlycheckActor {
204+
id,
205+
sender,
206+
config,
207+
sysroot_root,
208+
root: workspace_root,
209+
command_handle: None,
210+
}
203211
}
204212

205213
fn report_progress(&self, progress: Progress) {
@@ -334,7 +342,10 @@ impl FlycheckActor {
334342
ansi_color_output,
335343
target_dir,
336344
} => {
337-
let mut cmd = Command::new(&self.cargo);
345+
let mut cmd = Command::new(Tool::Cargo.path());
346+
if let Some(sysroot_root) = &self.sysroot_root {
347+
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(sysroot_root));
348+
}
338349
cmd.arg(command);
339350
cmd.current_dir(&self.root);
340351

crates/project-model/src/build_scripts.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,8 @@ impl WorkspaceBuildScripts {
7171
cmd
7272
}
7373
_ => {
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-
);
74+
let mut cmd = Command::new(Tool::Cargo.path());
75+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
7876

7977
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
8078
cmd.args(&config.extra_args);
@@ -431,7 +429,8 @@ impl WorkspaceBuildScripts {
431429
}
432430
let res = (|| {
433431
let target_libdir = (|| {
434-
let mut cargo_config = Command::new(Sysroot::discover_tool(sysroot, Tool::Cargo)?);
432+
let mut cargo_config = Command::new(Tool::Cargo.path());
433+
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
435434
cargo_config.envs(extra_env);
436435
cargo_config
437436
.current_dir(current_dir)
@@ -440,7 +439,8 @@ impl WorkspaceBuildScripts {
440439
if let Ok(it) = utf8_stdout(cargo_config) {
441440
return Ok(it);
442441
}
443-
let mut cmd = Command::new(Sysroot::discover_tool(sysroot, Tool::Rustc)?);
442+
let mut cmd = Command::new(Tool::Rustc.path());
443+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
444444
cmd.envs(extra_env);
445445
cmd.args(["--print", "target-libdir"]);
446446
utf8_stdout(cmd)

crates/project-model/src/cargo_workspace.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl CargoWorkspace {
243243
let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
244244

245245
let mut meta = MetadataCommand::new();
246-
meta.cargo_path(Sysroot::discover_tool(sysroot, Tool::Cargo)?);
246+
meta.cargo_path(Tool::Cargo.path());
247247
meta.manifest_path(cargo_toml.to_path_buf());
248248
match &config.features {
249249
CargoFeatures::All => {
@@ -291,6 +291,7 @@ impl CargoWorkspace {
291291

292292
(|| -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
293293
let mut command = meta.cargo_command();
294+
Sysroot::set_rustup_toolchain_env(&mut command, sysroot);
294295
command.envs(&config.extra_env);
295296
let output = command.output()?;
296297
if !output.status.success() {
@@ -500,7 +501,8 @@ fn rustc_discover_host_triple(
500501
extra_env: &FxHashMap<String, String>,
501502
sysroot: Option<&Sysroot>,
502503
) -> Option<String> {
503-
let mut rustc = Command::new(Sysroot::discover_tool(sysroot, Tool::Rustc).ok()?);
504+
let mut rustc = Command::new(Tool::Rustc.path());
505+
Sysroot::set_rustup_toolchain_env(&mut rustc, sysroot);
504506
rustc.envs(extra_env);
505507
rustc.current_dir(cargo_toml.parent()).arg("-vV");
506508
tracing::debug!("Discovering host platform by {:?}", rustc);
@@ -528,8 +530,8 @@ fn cargo_config_build_target(
528530
extra_env: &FxHashMap<String, String>,
529531
sysroot: Option<&Sysroot>,
530532
) -> Vec<String> {
531-
let Ok(program) = Sysroot::discover_tool(sysroot, Tool::Cargo) else { return vec![] };
532-
let mut cargo_config = Command::new(program);
533+
let mut cargo_config = Command::new(Tool::Cargo.path());
534+
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
533535
cargo_config.envs(extra_env);
534536
cargo_config
535537
.current_dir(cargo_toml.parent())

crates/project-model/src/rustc_cfg.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ fn get_rust_cfgs(
6868
config: RustcCfgConfig<'_>,
6969
) -> anyhow::Result<String> {
7070
let sysroot = 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);
71+
RustcCfgConfig::Cargo(sysroot, cargo_toml) => {
72+
let mut cmd = Command::new(toolchain::Tool::Cargo.path());
73+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
7474
cmd.envs(extra_env);
75-
cmd.current_dir(cargo_oml.parent())
75+
cmd.current_dir(cargo_toml.parent())
7676
.args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
7777
.env("RUSTC_BOOTSTRAP", "1");
7878
if let Some(target) = target {
@@ -90,9 +90,8 @@ fn get_rust_cfgs(
9090
RustcCfgConfig::Rustc(sysroot) => sysroot,
9191
};
9292

93-
let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
94-
tracing::debug!(?rustc, "using explicit rustc from sysroot");
95-
let mut cmd = Command::new(rustc);
93+
let mut cmd = Command::new(toolchain::Tool::Rustc.path());
94+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
9695
cmd.envs(extra_env);
9796
cmd.args(["--print", "cfg", "-O"]);
9897
if let Some(target) = target {

crates/project-model/src/sysroot.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
77
use std::{env, fs, iter, ops, path::PathBuf, process::Command, sync::Arc};
88

9-
use anyhow::{format_err, Context, Result};
9+
use anyhow::{format_err, Result};
1010
use base_db::CrateName;
1111
use itertools::Itertools;
1212
use la_arena::{Arena, Idx};
1313
use paths::{AbsPath, AbsPathBuf};
1414
use rustc_hash::FxHashMap;
15-
use toolchain::{probe_for_binary, Tool};
15+
use toolchain::probe_for_binary;
1616

1717
use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath};
1818

@@ -193,23 +193,9 @@ impl Sysroot {
193193
Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata))
194194
}
195195

196-
pub fn discover_binary(&self, binary: &str) -> anyhow::Result<AbsPathBuf> {
197-
toolchain::probe_for_binary(self.root.join("bin").join(binary).into())
198-
.ok_or_else(|| anyhow::anyhow!("no rustc binary found in {}", self.root.join("bin")))
199-
.and_then(|rustc| {
200-
fs::metadata(&rustc).map(|_| AbsPathBuf::assert(rustc)).with_context(|| {
201-
format!(
202-
"failed to discover rustc in sysroot: {:?}",
203-
AsRef::<std::path::Path>::as_ref(&self.root)
204-
)
205-
})
206-
})
207-
}
208-
209-
pub fn discover_tool(sysroot: Option<&Self>, tool: Tool) -> anyhow::Result<PathBuf> {
210-
match sysroot {
211-
Some(sysroot) => sysroot.discover_binary(tool.name()).map(Into::into),
212-
None => Ok(tool.path()),
196+
pub fn set_rustup_toolchain_env(cmd: &mut Command, sysroot: Option<&Self>) {
197+
if let Some(sysroot) = sysroot {
198+
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root));
213199
}
214200
}
215201

crates/project-model/src/target_data_layout.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ pub fn get(
2828
};
2929
let sysroot = match config {
3030
RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => {
31-
let cargo = Sysroot::discover_tool(sysroot, toolchain::Tool::Cargo)?;
32-
let mut cmd = Command::new(cargo);
31+
let mut cmd = Command::new(toolchain::Tool::Cargo.path());
32+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
3333
cmd.envs(extra_env);
3434
cmd.current_dir(cargo_toml.parent())
3535
.args(["rustc", "--", "-Z", "unstable-options", "--print", "target-spec-json"])
@@ -48,8 +48,8 @@ pub fn get(
4848
RustcDataLayoutConfig::Rustc(sysroot) => sysroot,
4949
};
5050

51-
let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
52-
let mut cmd = Command::new(rustc);
51+
let mut cmd = Command::new(toolchain::Tool::Rustc.path());
52+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
5353
cmd.envs(extra_env)
5454
.args(["-Z", "unstable-options", "--print", "target-spec-json"])
5555
.env("RUSTC_BOOTSTRAP", "1");

crates/project-model/src/workspace.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
//! metadata` or `rust-project.json`) into representation stored in the salsa
33
//! database -- `CrateGraph`.
44
5-
use std::{
6-
collections::VecDeque, fmt, fs, iter, path::PathBuf, process::Command, str::FromStr, sync,
7-
};
5+
use std::{collections::VecDeque, fmt, fs, iter, process::Command, str::FromStr, sync};
86

97
use anyhow::{format_err, Context};
108
use base_db::{
@@ -16,6 +14,7 @@ use paths::{AbsPath, AbsPathBuf};
1614
use rustc_hash::{FxHashMap, FxHashSet};
1715
use semver::Version;
1816
use stdx::always;
17+
use toolchain::Tool;
1918
use triomphe::Arc;
2019

2120
use crate::{
@@ -163,12 +162,14 @@ impl fmt::Debug for ProjectWorkspace {
163162

164163
fn get_toolchain_version(
165164
current_dir: &AbsPath,
166-
cmd_path: Result<PathBuf, anyhow::Error>,
165+
sysroot: Option<&Sysroot>,
166+
tool: Tool,
167167
extra_env: &FxHashMap<String, String>,
168168
prefix: &str,
169169
) -> Result<Option<Version>, anyhow::Error> {
170170
let cargo_version = utf8_stdout({
171-
let mut cmd = Command::new(cmd_path?);
171+
let mut cmd = Command::new(tool.path());
172+
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
172173
cmd.envs(extra_env);
173174
cmd.arg("--version").current_dir(current_dir);
174175
cmd
@@ -289,7 +290,8 @@ impl ProjectWorkspace {
289290

290291
let toolchain = get_toolchain_version(
291292
cargo_toml.parent(),
292-
Sysroot::discover_tool(sysroot_ref, toolchain::Tool::Cargo),
293+
sysroot_ref,
294+
toolchain::Tool::Cargo,
293295
&config.extra_env,
294296
"cargo ",
295297
)?;
@@ -370,9 +372,13 @@ impl ProjectWorkspace {
370372
let sysroot_ref = sysroot.as_ref().ok();
371373
let cfg_config = RustcCfgConfig::Rustc(sysroot_ref);
372374
let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref);
373-
let rustc = Sysroot::discover_tool(sysroot_ref, toolchain::Tool::Rustc).map(Into::into);
374-
let toolchain = match get_toolchain_version(project_json.path(), rustc, extra_env, "rustc ")
375-
{
375+
let toolchain = match get_toolchain_version(
376+
project_json.path(),
377+
sysroot_ref,
378+
toolchain::Tool::Rustc,
379+
extra_env,
380+
"rustc ",
381+
) {
376382
Ok(it) => it,
377383
Err(e) => {
378384
tracing::error!("{e}");
@@ -1615,10 +1621,8 @@ fn cargo_config_env(
16151621
extra_env: &FxHashMap<String, String>,
16161622
sysroot: Option<&Sysroot>,
16171623
) -> FxHashMap<String, String> {
1618-
let Ok(program) = Sysroot::discover_tool(sysroot, toolchain::Tool::Cargo) else {
1619-
return Default::default();
1620-
};
1621-
let mut cargo_config = Command::new(program);
1624+
let mut cargo_config = Command::new(Tool::Cargo.path());
1625+
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
16221626
cargo_config.envs(extra_env);
16231627
cargo_config
16241628
.current_dir(cargo_toml.parent())

crates/rust-analyzer/src/handlers/request.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ fn run_rustfmt(
19371937

19381938
let mut command = match snap.config.rustfmt() {
19391939
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
1940-
// FIXME: This should use the sysroot's rustfmt if its loaded
1940+
// FIXME: Set RUSTUP_TOOLCHAIN
19411941
let mut cmd = process::Command::new(toolchain::rustfmt());
19421942
cmd.envs(snap.config.extra_env());
19431943
cmd.args(extra_args);

crates/rust-analyzer/src/reload.rs

+20-19
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use ide_db::{
2424
use itertools::Itertools;
2525
use load_cargo::{load_proc_macro, ProjectFolders};
2626
use proc_macro_api::ProcMacroServer;
27-
use project_model::{ProjectWorkspace, Sysroot, WorkspaceBuildScripts};
27+
use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
2828
use rustc_hash::FxHashSet;
2929
use stdx::{format_to, thread::ThreadIntent};
3030
use triomphe::Arc;
@@ -468,16 +468,20 @@ impl GlobalState {
468468
None => ws.find_sysroot_proc_macro_srv()?,
469469
};
470470

471-
let env = match ws {
472-
ProjectWorkspace::Cargo { cargo_config_extra_env, .. } => {
473-
cargo_config_extra_env
474-
.iter()
475-
.chain(self.config.extra_env())
476-
.map(|(a, b)| (a.clone(), b.clone()))
477-
.collect()
478-
}
479-
_ => Default::default(),
480-
};
471+
let env =
472+
match ws {
473+
ProjectWorkspace::Cargo { cargo_config_extra_env, sysroot, .. } => {
474+
cargo_config_extra_env
475+
.iter()
476+
.chain(self.config.extra_env())
477+
.map(|(a, b)| (a.clone(), b.clone()))
478+
.chain(sysroot.as_ref().map(|it| {
479+
("RUSTUP_TOOLCHAIN".to_owned(), it.root().to_string())
480+
}))
481+
.collect()
482+
}
483+
_ => Default::default(),
484+
};
481485
tracing::info!("Using proc-macro server at {path}");
482486

483487
ProcMacroServer::spawn(path.clone(), &env).map_err(|err| {
@@ -620,7 +624,7 @@ impl GlobalState {
620624
0,
621625
Box::new(move |msg| sender.send(msg).unwrap()),
622626
config,
623-
toolchain::cargo(),
627+
None,
624628
self.config.root_path().clone(),
625629
)],
626630
flycheck::InvocationStrategy::PerWorkspace => {
@@ -631,7 +635,7 @@ impl GlobalState {
631635
ProjectWorkspace::Cargo { cargo, sysroot, .. } => Some((
632636
id,
633637
cargo.workspace_root(),
634-
Sysroot::discover_tool(sysroot.as_ref().ok(), toolchain::Tool::Cargo),
638+
sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()),
635639
)),
636640
ProjectWorkspace::Json { project, sysroot, .. } => {
637641
// Enable flychecks for json projects if a custom flycheck command was supplied
@@ -640,23 +644,20 @@ impl GlobalState {
640644
FlycheckConfig::CustomCommand { .. } => Some((
641645
id,
642646
project.path(),
643-
Sysroot::discover_tool(
644-
sysroot.as_ref().ok(),
645-
toolchain::Tool::Cargo,
646-
),
647+
sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()),
647648
)),
648649
_ => None,
649650
}
650651
}
651652
ProjectWorkspace::DetachedFiles { .. } => None,
652653
})
653-
.map(|(id, root, cargo)| {
654+
.map(|(id, root, sysroot_root)| {
654655
let sender = sender.clone();
655656
FlycheckHandle::spawn(
656657
id,
657658
Box::new(move |msg| sender.send(msg).unwrap()),
658659
config.clone(),
659-
cargo.unwrap_or_else(|_| toolchain::cargo()),
660+
sysroot_root,
660661
root.to_path_buf(),
661662
)
662663
})

0 commit comments

Comments
 (0)