From a7641a8f5781fce232bc100de9face29bb55788a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 12 Feb 2024 21:29:52 +0100 Subject: [PATCH] fix: Fix target layout fetching --- crates/project-model/src/rustc_cfg.rs | 32 ++++++++------ .../project-model/src/target_data_layout.rs | 42 ++++++++++++------- 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 efbdfffd9a4f..1d07e4a8a656 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, config: RustcCfgConfig<'_>, ) -> anyhow::Result { - 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 847829be1808..4c5200cee81b 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, ) -> anyhow::Result { - 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)?) }