about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-02-12 20:34:59 +0000
committerbors <bors@rust-lang.org>2024-02-12 20:34:59 +0000
commit3770f73bd661514b14a67f9ebd314e9ffa264fd7 (patch)
tree3ddd4d5880aa203d0a4a7069e175a014595119a0
parentcf8733353de5a2b3e7ba3d07dfed19918645ebb0 (diff)
parenta7641a8f5781fce232bc100de9face29bb55788a (diff)
downloadrust-3770f73bd661514b14a67f9ebd314e9ffa264fd7.tar.gz
rust-3770f73bd661514b14a67f9ebd314e9ffa264fd7.zip
Auto merge of #16545 - Veykril:fix-target-layout-fetch, r=Veykril
fix: Fix target layout fetching

https://github.com/rust-lang/rust-analyzer/pull/16537 broke this, as `cargo rustc` cannot run against a virtual workspace, so it will always fail in such projects (like rust-analyzer itself). This brings back the plain rustc fallback,
-rw-r--r--crates/project-model/src/rustc_cfg.rs32
-rw-r--r--crates/project-model/src/target_data_layout.rs42
2 files changed, 45 insertions, 29 deletions
diff --git a/crates/project-model/src/rustc_cfg.rs b/crates/project-model/src/rustc_cfg.rs
index efbdfffd9a4..1d07e4a8a65 100644
--- a/crates/project-model/src/rustc_cfg.rs
+++ b/crates/project-model/src/rustc_cfg.rs
@@ -67,7 +67,7 @@ fn get_rust_cfgs(
     extra_env: &FxHashMap<String, String>,
     config: RustcCfgConfig<'_>,
 ) -> anyhow::Result<String> {
-    match config {
+    let sysroot = match config {
         RustcCfgConfig::Cargo(sysroot, cargo_oml) => {
             let cargo = Sysroot::discover_tool(sysroot, toolchain::Tool::Cargo)?;
             let mut cmd = Command::new(cargo);
@@ -79,19 +79,25 @@ fn get_rust_cfgs(
                 cmd.args(["--target", target]);
             }
 
-            utf8_stdout(cmd).context("Unable to run `cargo rustc`")
-        }
-        RustcCfgConfig::Rustc(sysroot) => {
-            let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
-            tracing::debug!(?rustc, "using explicit rustc from sysroot");
-            let mut cmd = Command::new(rustc);
-            cmd.envs(extra_env);
-            cmd.args(["--print", "cfg", "-O"]);
-            if let Some(target) = target {
-                cmd.args(["--target", target]);
+            match utf8_stdout(cmd) {
+                Ok(it) => return Ok(it),
+                Err(e) => {
+                    tracing::warn!("failed to run `cargo rustc --print cfg`, falling back to invoking rustc directly: {e}");
+                    sysroot
+                }
             }
-
-            utf8_stdout(cmd).context("Unable to run `rustc`")
         }
+        RustcCfgConfig::Rustc(sysroot) => sysroot,
+    };
+
+    let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
+    tracing::debug!(?rustc, "using explicit rustc from sysroot");
+    let mut cmd = Command::new(rustc);
+    cmd.envs(extra_env);
+    cmd.args(["--print", "cfg", "-O"]);
+    if let Some(target) = target {
+        cmd.args(["--target", target]);
     }
+
+    utf8_stdout(cmd).context("unable to fetch cfgs via `rustc --print cfg -O`")
 }
diff --git a/crates/project-model/src/target_data_layout.rs b/crates/project-model/src/target_data_layout.rs
index 847829be180..4c5200cee81 100644
--- a/crates/project-model/src/target_data_layout.rs
+++ b/crates/project-model/src/target_data_layout.rs
@@ -20,31 +20,41 @@ pub fn get(
     target: Option<&str>,
     extra_env: &FxHashMap<String, String>,
 ) -> anyhow::Result<String> {
-    let output = match config {
+    let process = |output: String| {
+        (|| Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned()))()
+            .ok_or_else(|| {
+                anyhow::format_err!("could not fetch target-spec-json from command output")
+            })
+    };
+    let sysroot = match config {
         RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => {
             let cargo = Sysroot::discover_tool(sysroot, toolchain::Tool::Cargo)?;
             let mut cmd = Command::new(cargo);
             cmd.envs(extra_env);
             cmd.current_dir(cargo_toml.parent())
-                .args(["-Z", "unstable-options", "--print", "target-spec-json"])
+                .args(["rustc", "--", "-Z", "unstable-options", "--print", "target-spec-json"])
                 .env("RUSTC_BOOTSTRAP", "1");
             if let Some(target) = target {
                 cmd.args(["--target", target]);
             }
-            utf8_stdout(cmd)
-        }
-        RustcDataLayoutConfig::Rustc(sysroot) => {
-            let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
-            let mut cmd = Command::new(rustc);
-            cmd.envs(extra_env)
-                .args(["-Z", "unstable-options", "--print", "target-spec-json"])
-                .env("RUSTC_BOOTSTRAP", "1");
-            if let Some(target) = target {
-                cmd.args(["--target", target]);
+            match utf8_stdout(cmd) {
+                Ok(output) => return process(output),
+                Err(e) => {
+                    tracing::warn!("failed to run `cargo rustc --print target-spec-json`, falling back to invoking rustc directly: {e}");
+                    sysroot
+                }
             }
-            utf8_stdout(cmd)
         }
-    }?;
-    (|| Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned()))()
-        .ok_or_else(|| anyhow::format_err!("could not fetch target-spec-json from command output"))
+        RustcDataLayoutConfig::Rustc(sysroot) => sysroot,
+    };
+
+    let rustc = Sysroot::discover_tool(sysroot, toolchain::Tool::Rustc)?;
+    let mut cmd = Command::new(rustc);
+    cmd.envs(extra_env)
+        .args(["-Z", "unstable-options", "--print", "target-spec-json"])
+        .env("RUSTC_BOOTSTRAP", "1");
+    if let Some(target) = target {
+        cmd.args(["--target", target]);
+    }
+    process(utf8_stdout(cmd)?)
 }