Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/project-model/src/env.rs22
-rw-r--r--crates/project-model/src/workspace.rs32
2 files changed, 44 insertions, 10 deletions
diff --git a/crates/project-model/src/env.rs b/crates/project-model/src/env.rs
index 450def5461..9e0415c3b3 100644
--- a/crates/project-model/src/env.rs
+++ b/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/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index dfa409bb32..151e1c8116 100644
--- a/crates/project-model/src/workspace.rs
+++ b/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,