about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorLukas Wirth <me@lukaswirth.dev>2025-06-24 05:50:47 +0000
committerGitHub <noreply@github.com>2025-06-24 05:50:47 +0000
commit7ce7c2eed64af29c55efd2219ab019a7f72a50b5 (patch)
treeed216395077ba23c14c467cb0fb7da7022516d48 /src/tools/rust-analyzer
parentc75104957eb9a6e53d706f43cb4d75b5677a7e1f (diff)
parentc37994c726574c47aa5d02099b25637f3e8faea6 (diff)
downloadrust-7ce7c2eed64af29c55efd2219ab019a7f72a50b5.tar.gz
rust-7ce7c2eed64af29c55efd2219ab019a7f72a50b5.zip
Merge pull request #20072 from Veykril/push-sorvvvzskywv
fix: Respect `.cargo/config.toml` `build.target-dir`
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/env.rs22
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs32
2 files changed, 44 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/crates/project-model/src/env.rs b/src/tools/rust-analyzer/crates/project-model/src/env.rs
index 450def5461d..9e0415c3b39 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/env.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/env.rs
@@ -1,6 +1,6 @@
 //! Cargo-like environment variables injection.
 use base_db::Env;
-use paths::Utf8Path;
+use paths::{Utf8Path, Utf8PathBuf};
 use rustc_hash::FxHashMap;
 use toolchain::Tool;
 
@@ -123,6 +123,26 @@ fn parse_output_cargo_config_env(manifest: &ManifestPath, stdout: &str) -> Env {
     env
 }
 
+pub(crate) fn cargo_config_build_target_dir(
+    manifest: &ManifestPath,
+    extra_env: &FxHashMap<String, Option<String>>,
+    sysroot: &Sysroot,
+) -> Option<Utf8PathBuf> {
+    let mut cargo_config = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
+    cargo_config
+        .args(["-Z", "unstable-options", "config", "get", "build.target-dir"])
+        .env("RUSTC_BOOTSTRAP", "1");
+    if manifest.is_rust_manifest() {
+        cargo_config.arg("-Zscript");
+    }
+    utf8_stdout(&mut cargo_config)
+        .map(|stdout| {
+            Utf8Path::new(stdout.trim_start_matches("build.target-dir = ").trim_matches('"'))
+                .to_owned()
+        })
+        .ok()
+}
+
 #[test]
 fn parse_output_cargo_config_env_works() {
     let stdout = r#"
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index dfa409bb32b..151e1c81163 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -26,7 +26,10 @@ use crate::{
     WorkspaceBuildScripts,
     build_dependencies::BuildScriptOutput,
     cargo_workspace::{CargoMetadataConfig, DepKind, PackageData, RustLibSource},
-    env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
+    env::{
+        cargo_config_build_target_dir, cargo_config_env, inject_cargo_env,
+        inject_cargo_package_env, inject_rustc_tool_env,
+    },
     project_json::{Crate, CrateArrayIdx},
     sysroot::RustLibSrcWorkspace,
     toolchain_info::{QueryConfig, rustc_cfg, target_data_layout, target_tuple, version},
@@ -280,8 +283,11 @@ impl ProjectWorkspace {
             .ok()
             .flatten();
 
-        let target_dir =
-            config.target_dir.clone().unwrap_or_else(|| workspace_dir.join("target").into());
+        let target_dir = config
+            .target_dir
+            .clone()
+            .or_else(|| cargo_config_build_target_dir(cargo_toml, extra_env, &sysroot))
+            .unwrap_or_else(|| workspace_dir.join("target").into());
 
         // We spawn a bunch of processes to query various information about the workspace's
         // toolchain and sysroot
@@ -452,6 +458,14 @@ impl ProjectWorkspace {
         let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env)
             .unwrap_or_default();
         let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
+        let project_root = project_json.project_root();
+        let target_dir = config
+            .target_dir
+            .clone()
+            .or_else(|| {
+                cargo_config_build_target_dir(project_json.manifest()?, &config.extra_env, &sysroot)
+            })
+            .unwrap_or_else(|| project_root.join("target").into());
 
         // We spawn a bunch of processes to query various information about the workspace's
         // toolchain and sysroot
@@ -469,7 +483,6 @@ impl ProjectWorkspace {
                 )
             });
             let loaded_sysroot = s.spawn(|| {
-                let project_root = project_json.project_root();
                 if let Some(sysroot_project) = sysroot_project {
                     sysroot.load_workspace(
                         &RustSourceWorkspaceConfig::Json(*sysroot_project),
@@ -477,10 +490,6 @@ impl ProjectWorkspace {
                         progress,
                     )
                 } else {
-                    let target_dir = config
-                        .target_dir
-                        .clone()
-                        .unwrap_or_else(|| project_root.join("target").into());
                     sysroot.load_workspace(
                         &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config(
                             config,
@@ -535,7 +544,12 @@ impl ProjectWorkspace {
             .unwrap_or_default();
         let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env);
         let data_layout = target_data_layout::get(query_config, None, &config.extra_env);
-        let target_dir = config.target_dir.clone().unwrap_or_else(|| dir.join("target").into());
+        let target_dir = config
+            .target_dir
+            .clone()
+            .or_else(|| cargo_config_build_target_dir(detached_file, &config.extra_env, &sysroot))
+            .unwrap_or_else(|| dir.join("target").into());
+
         let loaded_sysroot = sysroot.load_workspace(
             &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config(
                 config,