From f707e726ba0eff5bd59d752b70aea084ae350053 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 9 May 2022 00:22:45 -0500 Subject: [PATCH] Fix spurious error when running `build --stage 2 compiler/rustc` https://github.com/rust-lang/rust/pull/89759 introduced a panic: ``` Assembling stage3 compiler (x86_64-apple-darwin) thread 'main' panicked at 'fs::read(stamp) failed with No such file or directory (os error 2) ("/Users/user/rust2/build/x86_64-apple-darwin/stage2-rustc/x86_64-apple-darwin/release/.librustc.stamp")', src/bootstrap/lib.rs:1296:24 ``` This wasn't actually a bug in that PR - the problem was that `x build --stage 3` is broken, and has been for quite some time, even ignoring the stamp file error: ``` thread 'main' panicked at 'src.symlink_metadata() failed with No such file or directory (os error 2) ("failed to determine metadata of /home/jnelson/rust-lang/rust/build/x86_64-unknown-linux-gnu/stage2-rustc/x86_64-unknown-linux-gnu/release/rustc-main")', src/bootstrap/lib.rs:1414:24 ``` It needs to take into account whether the artifacts from stage1 are being reused, rather than blindly assuming rustc will be recompiled. Doing so is kind of annoying, because it requires knowing the target the compiler is being built for. Instead, just revert to the old behavior of `build --stage 2 compiler/rustc`, which avoids trying to create the sysroot in the first place. --- src/bootstrap/builder/tests.rs | 5 ++++- src/bootstrap/compile.rs | 27 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index c084e77d3a994..b3bcaf3ea4ec2 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -501,7 +501,10 @@ mod dist { std!(A => C, stage = 2), ] ); - assert_eq!(builder.cache.all::().len(), 5); + // Theoretically this should be 5, the same as `compile::Rustc`. + // Unfortunately, the sysroot for the stage 3 compiler is broken; see #90244. + // Instead we only generate the sysroot for non-stage2 build compilers. + assert_eq!(builder.cache.all::().len(), 3); assert_eq!( first(builder.cache.all::()), &[ diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index ed5023ac61b0f..d83ef765b148b 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1104,9 +1104,30 @@ impl Step for Assemble { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Assemble { - target_compiler: run.builder.compiler(run.builder.top_stage + 1, run.target), - }); + // Trying to actually create the sysroot for stage 2 is tricky, because everywhere in + // bootstrap that touches self.rustc or self.cargo_out suddenly needs to know whether those + // artifacts actually exist or whether we're reusing the ones from stage 1. Instead, just + // build the artifacts, like we used to do before `compiler/rustc` implied assembling the + // compiler. + // + // When using full-bootstrap, we never reuse the artifacts from stage 1, so we don't have + // any issues. + // + // NOTE: Anywhere in bootstrap that calls `builder.compiler` has the side effect of running + // `Assemble`. In those cases, this workaround in `make_run` doesn't help, we'll still hit a + // panic (see #90224). In practice, that's probably ok: nothing currently uses the stage 2 + // sysroot. + if run.builder.top_stage >= 2 && !run.builder.config.full_bootstrap { + let build_compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.build); + run.builder.ensure(Rustc { + compiler: build_compiler, + target: run.target, + crates: Default::default(), + }); + return; + } + let target_compiler = Compiler { stage: run.builder.top_stage + 1, host: run.target }; + run.builder.ensure(Assemble { target_compiler }); } /// Prepare a new compiler from the artifacts in `stage`