diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index b936e9b1dd6b..d95c79254966 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -185,8 +185,20 @@ impl Step for Std { let mut target_deps = builder.ensure(StartupObjects { compiler, target }); - let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); - if compiler_to_use != compiler { + let mut compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); + + // We only need to build std twice; therefore, + // - If stage 2 std is built, the artifacts are fully up to date. For the next stages, uplift the artifacts instead of compiling std again. + // - If `--build-std-on-stage0` was used it means std was already built on stage 0. So, if stage 1 is built, that means std is fully up to date. + // For the next stages, uplift the artifacts instead of compiling std again. + if (compiler.stage > 2 || builder.config.build_std_on_stage0) && compiler_to_use != compiler + { + // If stage 2 std was built (not uplifted), uplift the artifacts from stage 2. + // (This is necessary; without this, they will be uplifted from stage 1). + if !builder.config.build_std_on_stage0 && compiler.stage > 2 { + compiler_to_use.stage = 2; + } + builder.ensure(Std::new(compiler_to_use, target)); let msg = if compiler_to_use.host == target { format!(