about summary refs log tree commit diff
diff options
context:
space:
mode:
-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)?)
 }