From 62cd64eb0ca872725ee9adf02ea8a593c886be32 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 12 Jan 2021 12:58:19 -0500 Subject: [PATCH 1/2] Add `x.py check --stage 1` This is useful for several cases: - Checking changes to the standard library with `cfg(not(bootstrap))` - Checking platform-specific changes to the compiler. In particular, checking with stage 1 doesn't require having a cross-compiling C native toolchain, unlike building. - Testing newly added internal lints without having to rebuild rustc_middle twice It is also very easy to support. --- src/bootstrap/check.rs | 8 ++++---- src/bootstrap/config.rs | 3 ++- src/bootstrap/flags.rs | 13 ------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index f65b2b2c79f75..0fb5cff45962c 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -62,7 +62,7 @@ impl Step for Std { fn run(self, builder: &Builder<'_>) { let target = self.target; - let compiler = builder.compiler(0, builder.config.build); + let compiler = builder.compiler(builder.top_stage, builder.config.build); let mut cargo = builder.cargo( compiler, @@ -152,7 +152,7 @@ impl Step for Rustc { /// the `compiler` targeting the `target` architecture. The artifacts /// created will also be linked into the sysroot directory. fn run(self, builder: &Builder<'_>) { - let compiler = builder.compiler(0, builder.config.build); + let compiler = builder.compiler(builder.top_stage, builder.config.build); let target = self.target; builder.ensure(Std { target }); @@ -214,7 +214,7 @@ impl Step for CodegenBackend { } fn run(self, builder: &Builder<'_>) { - let compiler = builder.compiler(0, builder.config.build); + let compiler = builder.compiler(builder.top_stage, builder.config.build); let target = self.target; let backend = self.backend; @@ -269,7 +269,7 @@ macro_rules! tool_check_step { } fn run(self, builder: &Builder<'_>) { - let compiler = builder.compiler(0, builder.config.build); + let compiler = builder.compiler(builder.top_stage, builder.config.build); let target = self.target; builder.ensure(Rustc { target }); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index def8f21543626..ef38136c6e324 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -376,6 +376,7 @@ struct Build { configure_args: Option>, local_rebuild: Option, print_step_timings: Option, + check_stage: Option, doc_stage: Option, build_stage: Option, test_stage: Option, @@ -674,6 +675,7 @@ impl Config { // See https://github.com/rust-lang/compiler-team/issues/326 config.stage = match config.cmd { + Subcommand::Check { .. } => flags.stage.or(build.check_stage).unwrap_or(0), Subcommand::Doc { .. } => flags.stage.or(build.doc_stage).unwrap_or(0), Subcommand::Build { .. } => flags.stage.or(build.build_stage).unwrap_or(1), Subcommand::Test { .. } => flags.stage.or(build.test_stage).unwrap_or(1), @@ -683,7 +685,6 @@ impl Config { // These are all bootstrap tools, which don't depend on the compiler. // The stage we pass shouldn't matter, but use 0 just in case. Subcommand::Clean { .. } - | Subcommand::Check { .. } | Subcommand::Clippy { .. } | Subcommand::Fix { .. } | Subcommand::Run { .. } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index d6a45f1c17076..9cec75404a766 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -613,19 +613,6 @@ Arguments: } }; - if let Subcommand::Check { .. } = &cmd { - if matches.opt_str("stage").is_some() { - println!("--stage not supported for x.py check, always treated as stage 0"); - process::exit(1); - } - if matches.opt_str("keep-stage").is_some() - || matches.opt_str("keep-stage-std").is_some() - { - println!("--keep-stage not supported for x.py check, only one stage available"); - process::exit(1); - } - } - Flags { verbose: matches.opt_count("verbose"), stage: matches.opt_str("stage").map(|j| j.parse().expect("`stage` should be a number")), From 7ed801048f4d9a8eb09b05ba7a818fb0a698fe4b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 12 Jan 2021 22:42:57 -0500 Subject: [PATCH 2/2] Always treat stage0 as the snapshot compiler when checking Otherwise, we may not have MIR for the standard library available: ``` error: internal compiler error: compiler/rustc_mir/src/monomorphize/collector.rs:826:9: cannot create local mono-item for DefId(2:6820 ~ core[92cf]::fmt::{impl#2}::new_v1) ``` The current error after this change is ``` error[E0514]: found crate `chalk_derive` compiled by an incompatible version of rustc --> /home/joshua/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/chalk-ir-0.36.0/src/lib.rs:13:5 | 13 | use chalk_derive::{Fold, HasInterner, SuperVisit, Visit, Zip}; | ^^^^^^^^^^^^ | = help: please recompile that crate using this compiler (rustc 1.51.0-dev) = note: the following crate versions were found: crate `chalk_derive` compiled by rustc 1.49.0-beta.1 (21dea46d8 2020-11-18): /home/joshua/rustc3/build/x86_64-unknown-linux-gnu/stage1-rustc/release/deps/libchalk_derive-843b3d0b9b865ca6.so ``` --- src/bootstrap/builder.rs | 6 +++++- src/bootstrap/check.rs | 17 +++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0fdafa3938634..1aefcad6da0f2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1187,7 +1187,11 @@ impl<'a> Builder<'a> { // For other crates, however, we know that we've already got a standard // library up and running, so we can use the normal compiler to compile // build scripts in that situation. - if mode == Mode::Std { + // + // Note that when we're checking the compiler for any stage other than 0, + // we may not have built the MIR for the standard library, only the check metadata. + // If so, we need to use stage 0 for build scripts still. + if mode == Mode::Std || self.kind == Kind::Check { cargo .env("RUSTC_SNAPSHOT", &self.initial_rustc) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()); diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 0fb5cff45962c..e4110f50c7057 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -73,7 +73,7 @@ impl Step for Std { ); std_cargo(builder, target, compiler.stage, &mut cargo); - builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target)); + builder.info(&format!("Checking stage{} std artifacts ({} -> {})", builder.top_stage, &compiler.host, target)); run_cargo( builder, cargo, @@ -113,8 +113,8 @@ impl Step for Std { } builder.info(&format!( - "Checking std test/bench/example targets ({} -> {})", - &compiler.host, target + "Checking stage{} std test/bench/example targets ({} -> {})", + builder.top_stage, &compiler.host, target )); run_cargo( builder, @@ -169,14 +169,14 @@ impl Step for Rustc { cargo.arg("--all-targets"); } - // Explicitly pass -p for all compiler krates -- this will force cargo + // Explicitly pass -p for all compiler crates -- this will force cargo // to also check the tests/benches/examples for these crates, rather // than just the leaf crate. for krate in builder.in_tree_crates("rustc-main", Some(target)) { cargo.arg("-p").arg(krate.name); } - builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target)); + builder.info(&format!("Checking stage{} compiler artifacts ({} -> {})", builder.top_stage, &compiler.host, target)); run_cargo( builder, cargo, @@ -233,8 +233,8 @@ impl Step for CodegenBackend { rustc_cargo_env(builder, &mut cargo, target); builder.info(&format!( - "Checking {} artifacts ({} -> {})", - backend, &compiler.host.triple, target.triple + "Checking stage{} {} artifacts ({} -> {})", + builder.top_stage, backend, &compiler.host.triple, target.triple )); run_cargo( @@ -290,7 +290,8 @@ macro_rules! tool_check_step { } builder.info(&format!( - "Checking {} artifacts ({} -> {})", + "Checking stage{} {} artifacts ({} -> {})", + builder.top_stage, stringify!($name).to_lowercase(), &compiler.host.triple, target.triple