about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/project-model/src/build_scripts.rs8
-rw-r--r--crates/project-model/src/cargo_workspace.rs17
-rw-r--r--crates/project-model/src/rustc_cfg.rs9
-rw-r--r--crates/project-model/src/sysroot.rs33
-rw-r--r--crates/project-model/src/target_data_layout.rs7
-rw-r--r--crates/project-model/src/workspace.rs40
-rw-r--r--crates/toolchain/src/lib.rs4
7 files changed, 54 insertions, 64 deletions
diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs
index 27a8db40a99..709fc037174 100644
--- a/crates/project-model/src/build_scripts.rs
+++ b/crates/project-model/src/build_scripts.rs
@@ -71,8 +71,7 @@ impl WorkspaceBuildScripts {
                 cmd
             }
             _ => {
-                let mut cmd = Command::new(Tool::Cargo.path());
-                Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
+                let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
 
                 cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
                 cmd.args(&config.extra_args);
@@ -430,8 +429,7 @@ impl WorkspaceBuildScripts {
         }
         let res = (|| {
             let target_libdir = (|| {
-                let mut cargo_config = Command::new(Tool::Cargo.path());
-                Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
+                let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
                 cargo_config.envs(extra_env);
                 cargo_config
                     .current_dir(current_dir)
@@ -440,7 +438,7 @@ impl WorkspaceBuildScripts {
                 if let Ok(it) = utf8_stdout(cargo_config) {
                     return Ok(it);
                 }
-                let mut cmd = Sysroot::rustc(sysroot);
+                let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
                 cmd.envs(extra_env);
                 cmd.args(["--print", "target-libdir"]);
                 utf8_stdout(cmd)
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index 609b1f67b57..53b41ea1e87 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -1,8 +1,8 @@
 //! See [`CargoWorkspace`].
 
+use std::ops;
 use std::path::PathBuf;
 use std::str::from_utf8;
-use std::{ops, process::Command};
 
 use anyhow::Context;
 use base_db::Edition;
@@ -243,8 +243,11 @@ impl CargoWorkspace {
     ) -> anyhow::Result<cargo_metadata::Metadata> {
         let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
 
+        let cargo = Sysroot::tool(sysroot, Tool::Cargo);
         let mut meta = MetadataCommand::new();
-        meta.cargo_path(Tool::Cargo.path());
+        meta.cargo_path(cargo.get_program());
+        cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default()));
+        config.extra_env.iter().for_each(|(var, val)| _ = meta.env(var, val));
         meta.manifest_path(cargo_toml.to_path_buf());
         match &config.features {
             CargoFeatures::All => {
@@ -291,10 +294,7 @@ impl CargoWorkspace {
         progress("metadata".to_owned());
 
         (|| -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
-            let mut command = meta.cargo_command();
-            Sysroot::set_rustup_toolchain_env(&mut command, sysroot);
-            command.envs(&config.extra_env);
-            let output = command.output()?;
+            let output = meta.cargo_command().output()?;
             if !output.status.success() {
                 return Err(cargo_metadata::Error::CargoMetadata {
                     stderr: String::from_utf8(output.stderr)?,
@@ -501,7 +501,7 @@ fn rustc_discover_host_triple(
     extra_env: &FxHashMap<String, String>,
     sysroot: Option<&Sysroot>,
 ) -> Option<String> {
-    let mut rustc = Sysroot::rustc(sysroot);
+    let mut rustc = Sysroot::tool(sysroot, Tool::Rustc);
     rustc.envs(extra_env);
     rustc.current_dir(cargo_toml.parent()).arg("-vV");
     tracing::debug!("Discovering host platform by {:?}", rustc);
@@ -529,8 +529,7 @@ fn cargo_config_build_target(
     extra_env: &FxHashMap<String, String>,
     sysroot: Option<&Sysroot>,
 ) -> Vec<String> {
-    let mut cargo_config = Command::new(Tool::Cargo.path());
-    Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
+    let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
     cargo_config.envs(extra_env);
     cargo_config
         .current_dir(cargo_toml.parent())
diff --git a/crates/project-model/src/rustc_cfg.rs b/crates/project-model/src/rustc_cfg.rs
index 001296fb000..501b1fdc8c5 100644
--- a/crates/project-model/src/rustc_cfg.rs
+++ b/crates/project-model/src/rustc_cfg.rs
@@ -1,9 +1,8 @@
 //! Runs `rustc --print cfg` to get built-in cfg flags.
 
-use std::process::Command;
-
 use anyhow::Context;
 use rustc_hash::FxHashMap;
+use toolchain::Tool;
 
 use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
 
@@ -69,8 +68,8 @@ fn get_rust_cfgs(
 ) -> anyhow::Result<String> {
     let sysroot = match config {
         RustcCfgConfig::Cargo(sysroot, cargo_toml) => {
-            let mut cmd = Command::new(toolchain::Tool::Cargo.path());
-            Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
+            let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
+
             cmd.envs(extra_env);
             cmd.current_dir(cargo_toml.parent())
                 .args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
@@ -90,7 +89,7 @@ fn get_rust_cfgs(
         RustcCfgConfig::Rustc(sysroot) => sysroot,
     };
 
-    let mut cmd = Sysroot::rustc(sysroot);
+    let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
     cmd.envs(extra_env);
     cmd.args(["--print", "cfg", "-O"]);
     if let Some(target) = target {
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs
index a486a38510a..3127bae8b0c 100644
--- a/crates/project-model/src/sysroot.rs
+++ b/crates/project-model/src/sysroot.rs
@@ -193,23 +193,26 @@ impl Sysroot {
         Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata))
     }
 
-    pub fn set_rustup_toolchain_env(cmd: &mut Command, sysroot: Option<&Self>) {
-        if let Some(sysroot) = sysroot {
-            cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root));
-        }
-    }
-
-    /// Returns a `Command` that is configured to run `rustc` from the sysroot if it exists,
-    /// otherwise returns what [toolchain::Tool::Rustc] returns.
-    pub fn rustc(sysroot: Option<&Self>) -> Command {
-        let mut cmd = Command::new(match sysroot {
+    /// Returns a command to run a tool preferring the cargo proxies if the sysroot exists.
+    pub fn tool(sysroot: Option<&Self>, tool: Tool) -> Command {
+        match sysroot {
             Some(sysroot) => {
-                toolchain::Tool::Rustc.path_in_or_discover(sysroot.root.join("bin").as_ref())
+                // special case rustc, we can look that up directly in the sysroot's bin folder
+                // as it should never invoke another cargo binary
+                if let Tool::Rustc = tool {
+                    if let Some(path) =
+                        probe_for_binary(sysroot.root.join("bin").join(Tool::Rustc.name()).into())
+                    {
+                        return Command::new(path);
+                    }
+                }
+
+                let mut cmd = Command::new(tool.prefer_proxy());
+                cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root));
+                cmd
             }
-            None => toolchain::Tool::Rustc.path(),
-        });
-        Self::set_rustup_toolchain_env(&mut cmd, sysroot);
-        cmd
+            _ => Command::new(tool.path()),
+        }
     }
 
     pub fn discover_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> {
diff --git a/crates/project-model/src/target_data_layout.rs b/crates/project-model/src/target_data_layout.rs
index df77541762d..4e810a0232e 100644
--- a/crates/project-model/src/target_data_layout.rs
+++ b/crates/project-model/src/target_data_layout.rs
@@ -1,7 +1,7 @@
 //! Runs `rustc --print target-spec-json` to get the target_data_layout.
-use std::process::Command;
 
 use rustc_hash::FxHashMap;
+use toolchain::Tool;
 
 use crate::{utf8_stdout, ManifestPath, Sysroot};
 
@@ -28,8 +28,7 @@ pub fn get(
     };
     let sysroot = match config {
         RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => {
-            let mut cmd = Command::new(toolchain::Tool::Cargo.path());
-            Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
+            let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
             cmd.envs(extra_env);
             cmd.current_dir(cargo_toml.parent())
                 .args([
@@ -57,7 +56,7 @@ pub fn get(
         RustcDataLayoutConfig::Rustc(sysroot) => sysroot,
     };
 
-    let mut cmd = Sysroot::rustc(sysroot);
+    let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
     cmd.envs(extra_env)
         .args(["-Z", "unstable-options", "--print", "target-spec-json"])
         .env("RUSTC_BOOTSTRAP", "1");
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index adf15d45fc6..1a138b17bad 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -2,7 +2,7 @@
 //! metadata` or `rust-project.json`) into representation stored in the salsa
 //! database -- `CrateGraph`.
 
-use std::{collections::VecDeque, fmt, fs, iter, process::Command, str::FromStr, sync};
+use std::{collections::VecDeque, fmt, fs, iter, str::FromStr, sync};
 
 use anyhow::{format_err, Context};
 use base_db::{
@@ -172,11 +172,13 @@ impl fmt::Debug for ProjectWorkspace {
 
 fn get_toolchain_version(
     current_dir: &AbsPath,
-    mut cmd: Command,
+    sysroot: Option<&Sysroot>,
+    tool: Tool,
     extra_env: &FxHashMap<String, String>,
     prefix: &str,
 ) -> Result<Option<Version>, anyhow::Error> {
     let cargo_version = utf8_stdout({
+        let mut cmd = Sysroot::tool(sysroot, tool);
         cmd.envs(extra_env);
         cmd.arg("--version").current_dir(current_dir);
         cmd
@@ -297,11 +299,8 @@ impl ProjectWorkspace {
 
                 let toolchain = get_toolchain_version(
                     cargo_toml.parent(),
-                    {
-                        let mut cmd = Command::new(toolchain::Tool::Cargo.path());
-                        Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot_ref);
-                        cmd
-                    },
+                    sysroot_ref,
+                    Tool::Cargo,
                     &config.extra_env,
                     "cargo ",
                 )?;
@@ -386,7 +385,8 @@ impl ProjectWorkspace {
         let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref);
         let toolchain = match get_toolchain_version(
             project_json.path(),
-            Sysroot::rustc(sysroot_ref),
+            sysroot_ref,
+            Tool::Rustc,
             extra_env,
             "rustc ",
         ) {
@@ -433,18 +433,15 @@ impl ProjectWorkspace {
         };
 
         let sysroot_ref = sysroot.as_ref().ok();
-        let toolchain = match get_toolchain_version(
-            dir,
-            Sysroot::rustc(sysroot_ref),
-            &config.extra_env,
-            "rustc ",
-        ) {
-            Ok(it) => it,
-            Err(e) => {
-                tracing::error!("{e}");
-                None
-            }
-        };
+        let toolchain =
+            match get_toolchain_version(dir, sysroot_ref, Tool::Rustc, &config.extra_env, "rustc ")
+            {
+                Ok(it) => it,
+                Err(e) => {
+                    tracing::error!("{e}");
+                    None
+                }
+            };
 
         let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(sysroot_ref));
         let data_layout = target_data_layout::get(
@@ -1573,8 +1570,7 @@ fn cargo_config_env(
     extra_env: &FxHashMap<String, String>,
     sysroot: Option<&Sysroot>,
 ) -> FxHashMap<String, String> {
-    let mut cargo_config = Command::new(Tool::Cargo.path());
-    Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
+    let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
     cargo_config.envs(extra_env);
     cargo_config
         .current_dir(cargo_toml.parent())
diff --git a/crates/toolchain/src/lib.rs b/crates/toolchain/src/lib.rs
index e65a060672e..a77fed585af 100644
--- a/crates/toolchain/src/lib.rs
+++ b/crates/toolchain/src/lib.rs
@@ -58,10 +58,6 @@ impl Tool {
         probe_for_binary(path.join(self.name()))
     }
 
-    pub fn path_in_or_discover(self, path: &Path) -> PathBuf {
-        probe_for_binary(path.join(self.name())).unwrap_or_else(|| self.path())
-    }
-
     pub fn name(self) -> &'static str {
         match self {
             Tool::Cargo => "cargo",