From 950de7c3c355398a9c15812b74376e252cb176db Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 9 Aug 2022 14:31:17 +0200 Subject: [PATCH 1/2] Use `--keep-going` cargo flag when building build scripts --- crates/project-model/src/build_scripts.rs | 15 +++++++++++++-- crates/project-model/src/tests.rs | 1 + crates/project-model/src/workspace.rs | 18 ++++++++++++++---- crates/rust-analyzer/src/reload.rs | 1 + 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs index ee7f8339a76a..4b00479a4c9c 100644 --- a/crates/project-model/src/build_scripts.rs +++ b/crates/project-model/src/build_scripts.rs @@ -12,6 +12,7 @@ use cargo_metadata::{camino::Utf8Path, Message}; use la_arena::ArenaMap; use paths::AbsPathBuf; use rustc_hash::FxHashMap; +use semver::Version; use serde::Deserialize; use crate::{cfg_flag::CfgFlag, CargoConfig, CargoWorkspace, Package}; @@ -38,7 +39,7 @@ pub(crate) struct BuildScriptOutput { } impl WorkspaceBuildScripts { - fn build_command(config: &CargoConfig) -> Command { + fn build_command(config: &CargoConfig, toolchain: &Option) -> Command { if let Some([program, args @ ..]) = config.run_build_script_command.as_deref() { let mut cmd = Command::new(program); cmd.args(args); @@ -70,6 +71,15 @@ impl WorkspaceBuildScripts { } } + const RUST_1_62: Version = Version::new(1, 62, 0); + + match toolchain { + Some(v) if v >= &RUST_1_62 => { + cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1"); + } + _ => (), + } + cmd } @@ -77,8 +87,9 @@ impl WorkspaceBuildScripts { config: &CargoConfig, workspace: &CargoWorkspace, progress: &dyn Fn(String), + toolchain: &Option, ) -> io::Result { - let mut cmd = Self::build_command(config); + let mut cmd = Self::build_command(config, toolchain); if config.wrap_rustc_in_build_scripts { // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index e304a59c0180..8d0fa757c2e1 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -28,6 +28,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr rustc: None, rustc_cfg: Vec::new(), cfg_overrides, + toolchain: None, }; to_crate_graph(project_workspace) } diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index b144006b44e0..daabb299f76c 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -12,6 +12,7 @@ use base_db::{ use cfg::{CfgDiff, CfgOptions}; use paths::{AbsPath, AbsPathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; +use semver::Version; use stdx::always; use crate::{ @@ -77,6 +78,7 @@ pub enum ProjectWorkspace { /// different target. rustc_cfg: Vec, cfg_overrides: CfgOverrides, + toolchain: Option, }, /// Project workspace was manually specified using a `rust-project.json` file. Json { project: ProjectJson, sysroot: Option, rustc_cfg: Vec }, @@ -105,6 +107,7 @@ impl fmt::Debug for ProjectWorkspace { rustc, rustc_cfg, cfg_overrides, + toolchain, } => f .debug_struct("Cargo") .field("root", &cargo.workspace_root().file_name()) @@ -116,6 +119,7 @@ impl fmt::Debug for ProjectWorkspace { ) .field("n_rustc_cfg", &rustc_cfg.len()) .field("n_cfg_overrides", &cfg_overrides.len()) + .field("toolchain", &toolchain) .finish(), ProjectWorkspace::Json { project, sysroot, rustc_cfg } => { let mut debug_struct = f.debug_struct("Json"); @@ -160,6 +164,9 @@ impl ProjectWorkspace { cmd.arg("--version"); cmd })?; + let toolchain = cargo_version + .get("cargo ".len()..) + .and_then(|it| Version::parse(it.split_whitespace().next()?).ok()); let meta = CargoWorkspace::fetch_metadata( &cargo_toml, @@ -169,9 +176,9 @@ impl ProjectWorkspace { ) .with_context(|| { format!( - "Failed to read Cargo metadata from Cargo.toml file {}, {}", + "Failed to read Cargo metadata from Cargo.toml file {}, {:?}", cargo_toml.display(), - cargo_version + toolchain ) })?; let cargo = CargoWorkspace::new(meta); @@ -219,6 +226,7 @@ impl ProjectWorkspace { rustc, rustc_cfg, cfg_overrides, + toolchain, } } }; @@ -271,8 +279,8 @@ impl ProjectWorkspace { progress: &dyn Fn(String), ) -> Result { match self { - ProjectWorkspace::Cargo { cargo, .. } => { - WorkspaceBuildScripts::run(config, cargo, progress).with_context(|| { + ProjectWorkspace::Cargo { cargo, toolchain, .. } => { + WorkspaceBuildScripts::run(config, cargo, progress, toolchain).with_context(|| { format!("Failed to run build scripts for {}", &cargo.workspace_root().display()) }) } @@ -320,6 +328,7 @@ impl ProjectWorkspace { rustc_cfg: _, cfg_overrides: _, build_scripts, + toolchain: _, } => { cargo .packages() @@ -425,6 +434,7 @@ impl ProjectWorkspace { rustc_cfg, cfg_overrides, build_scripts, + toolchain: _, } => cargo_to_crate_graph( rustc_cfg.clone(), cfg_overrides, diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 49ccad71a10e..ceb2a6d703d9 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -219,6 +219,7 @@ impl GlobalState { cfg_overrides, build_scripts: _, + toolchain: _, } => Some((cargo, sysroot, rustc, rustc_cfg, cfg_overrides)), _ => None, }; From 25d4fbe9dae2b875ebfa81a28e10796475def74b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 10 Aug 2022 10:23:46 +0200 Subject: [PATCH 2/2] Re-try build script building with --keep-going --- crates/project-model/src/build_scripts.rs | 33 ++++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs index 4b00479a4c9c..84e772d1684a 100644 --- a/crates/project-model/src/build_scripts.rs +++ b/crates/project-model/src/build_scripts.rs @@ -39,7 +39,7 @@ pub(crate) struct BuildScriptOutput { } impl WorkspaceBuildScripts { - fn build_command(config: &CargoConfig, toolchain: &Option) -> Command { + fn build_command(config: &CargoConfig) -> Command { if let Some([program, args @ ..]) = config.run_build_script_command.as_deref() { let mut cmd = Command::new(program); cmd.args(args); @@ -71,26 +71,39 @@ impl WorkspaceBuildScripts { } } + cmd + } + + pub(crate) fn run( + config: &CargoConfig, + workspace: &CargoWorkspace, + progress: &dyn Fn(String), + toolchain: &Option, + ) -> io::Result { const RUST_1_62: Version = Version::new(1, 62, 0); - match toolchain { - Some(v) if v >= &RUST_1_62 => { + match Self::run_(Self::build_command(config), config, workspace, progress) { + Ok(WorkspaceBuildScripts { error: Some(error), .. }) + if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) => + { + // building build scripts failed, attempt to build with --keep-going so + // that we potentially get more build data + let mut cmd = Self::build_command(config); cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1"); + let mut res = Self::run_(cmd, config, workspace, progress)?; + res.error = Some(error); + Ok(res) } - _ => (), + res => res, } - - cmd } - pub(crate) fn run( + fn run_( + mut cmd: Command, config: &CargoConfig, workspace: &CargoWorkspace, progress: &dyn Fn(String), - toolchain: &Option, ) -> io::Result { - let mut cmd = Self::build_command(config, toolchain); - if config.wrap_rustc_in_build_scripts { // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use // that to compile only proc macros and build scripts during the initial