From b3d90afb56e4016bbef162578e4fb0e1fc77d9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 15:39:56 +0200 Subject: [PATCH 01/13] Forbid documenting anything on stage 0 --- src/bootstrap/src/core/builder/tests.rs | 51 +++++++++---------------- src/bootstrap/src/core/config/config.rs | 8 +++- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 4c7766e58c1cf..3b1b3dd2edd1e 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -741,6 +741,21 @@ mod snapshot { ); } + #[test] + fn build_compiler_lld_opt_in() { + with_lld_opt_in_targets(vec![host_target()], || { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("build") + .path("compiler") + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 0 -> LldWrapper 1 + "); + }); + } + #[test] fn build_library_no_explicit_stage() { let ctx = TestCtx::new(); @@ -1747,21 +1762,6 @@ mod snapshot { "); } - #[test] - fn test_lld_opt_in() { - with_lld_opt_in_targets(vec![host_target()], || { - let ctx = TestCtx::new(); - insta::assert_snapshot!( - ctx.config("build") - .path("compiler") - .render_steps(), @r" - [build] llvm - [build] rustc 0 -> rustc 1 - [build] rustc 0 -> LldWrapper 1 - "); - }); - } - #[test] fn doc_library_no_std_target() { let ctx = TestCtx::new(); @@ -1794,17 +1794,10 @@ mod snapshot { } #[test] + #[should_panic] fn doc_compiler_stage_0() { let ctx = TestCtx::new(); - insta::assert_snapshot!( - ctx.config("doc") - .path("compiler") - .stage(0) - .render_steps(), @r" - [build] rustdoc 0 - [build] llvm - [doc] rustc 0 - "); + ctx.config("doc").path("compiler").stage(0).run(); } #[test] @@ -1842,16 +1835,10 @@ mod snapshot { } #[test] + #[should_panic] fn doc_compiletest_stage_0() { let ctx = TestCtx::new(); - insta::assert_snapshot!( - ctx.config("doc") - .path("src/tools/compiletest") - .stage(0) - .render_steps(), @r" - [build] rustdoc 0 - [doc] Compiletest - "); + ctx.config("doc").path("src/tools/compiletest").stage(0).run(); } #[test] diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index eb1ac8c637ffe..a6953bd4b2503 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1349,11 +1349,15 @@ impl Config { // Now check that the selected stage makes sense, and if not, print a warning and end match (config.stage, &config.cmd) { (0, Subcommand::Build) => { - eprintln!("WARNING: cannot build anything on stage 0. Use at least stage 1."); + eprintln!("ERROR: cannot build anything on stage 0. Use at least stage 1."); exit!(1); } (0, Subcommand::Check { .. }) => { - eprintln!("WARNING: cannot check anything on stage 0. Use at least stage 1."); + eprintln!("ERROR: cannot check anything on stage 0. Use at least stage 1."); + exit!(1); + } + (0, Subcommand::Doc { .. }) => { + eprintln!("ERROR: cannot document anything on stage 0. Use at least stage 1."); exit!(1); } _ => {} From 980fe06c62b96fcc200329fbd16535b20223b23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 16:19:19 +0200 Subject: [PATCH 02/13] Fix staging for `doc compiler` --- src/bootstrap/src/core/build_steps/doc.rs | 43 +++++++++++-------- src/bootstrap/src/core/build_steps/test.rs | 6 +-- src/bootstrap/src/core/builder/tests.rs | 12 ++---- .../docker/host-x86_64/pr-check-2/Dockerfile | 8 ++-- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 434e9c0977d26..dea1db1bc2b7e 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -756,21 +756,31 @@ fn doc_std( builder.cp_link_r(&out_dir, out); } +/// Prepare a compiler that will be able to document something for `target` at `stage`. +fn prepare_doc_compiler(builder: &Builder<'_>, target: TargetSelection, stage: u32) -> Compiler { + let build_compiler = builder.compiler(stage - 1, builder.host_target); + builder.std(build_compiler, target); + build_compiler +} + +/// Document the compiler for the given `target` using rustdoc from `build_compiler`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Rustc { - pub stage: u32, - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, crates: Vec, } impl Rustc { - pub(crate) fn new(stage: u32, target: TargetSelection, builder: &Builder<'_>) -> Self { + /// Document `stage` compiler for the given `target`. + pub(crate) fn for_stage(builder: &Builder<'_>, target: TargetSelection, stage: u32) -> Self { let crates = builder .in_tree_crates("rustc-main", Some(target)) .into_iter() .map(|krate| krate.name.to_string()) .collect(); - Self { stage, target, crates } + let build_compiler = prepare_doc_compiler(builder, target, stage); + Self { build_compiler, target, crates } } } @@ -787,11 +797,7 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustc { - stage: run.builder.top_stage, - target: run.target, - crates: run.make_run_crates(Alias::Compiler), - }); + run.builder.ensure(Rustc::for_stage(run.builder, run.target, run.builder.top_stage)); } /// Generates compiler documentation. @@ -801,7 +807,6 @@ impl Step for Rustc { /// we do not merge it with the other documentation from std, test and /// proc_macros. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) { - let stage = self.stage; let target = self.target; // This is the intended out directory for compiler documentation. @@ -810,21 +815,21 @@ impl Step for Rustc { // Build the standard library, so that proc-macros can use it. // (Normally, only the metadata would be necessary, but proc-macros are special since they run at compile-time.) - let compiler = builder.compiler(stage, builder.config.host_target); - builder.std(compiler, builder.config.host_target); + let build_compiler = self.build_compiler; + builder.std(build_compiler, builder.config.host_target); let _guard = builder.msg_rustc_tool( Kind::Doc, - stage, + build_compiler.stage, format!("compiler{}", crate_description(&self.crates)), - compiler.host, + build_compiler.host, target, ); // Build cargo command. let mut cargo = builder::Cargo::new( builder, - compiler, + build_compiler, Mode::Rustc, SourceType::InTree, target, @@ -842,7 +847,7 @@ impl Step for Rustc { // If there is any bug, please comment out the next line. cargo.rustdocflag("--generate-link-to-definition"); - compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); + compile::rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates); cargo.arg("-Zskip-rustdoc-fingerprint"); // Only include compiler crates, no dependencies of those, such as `libc`. @@ -857,7 +862,7 @@ impl Step for Rustc { let mut to_open = None; - let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target).join("doc"); + let out_dir = builder.stage_out(build_compiler, Mode::Rustc).join(target).join("doc"); for krate in &*self.crates { // Create all crate output directories first to make sure rustdoc uses // relative links. @@ -879,7 +884,7 @@ impl Step for Rustc { symlink_dir_force(&builder.config, &out, &out_dir); // Cargo puts proc macros in `target/doc` even if you pass `--target` // explicitly (https://github.com/rust-lang/cargo/issues/7677). - let proc_macro_out_dir = builder.stage_out(compiler, Mode::Rustc).join("doc"); + let proc_macro_out_dir = builder.stage_out(build_compiler, Mode::Rustc).join("doc"); symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); cargo.into_cmd().run(builder); @@ -905,7 +910,7 @@ impl Step for Rustc { } fn metadata(&self) -> Option { - Some(StepMetadata::doc("rustc", self.target).stage(self.stage)) + Some(StepMetadata::doc("rustc", self.target).built_by(self.build_compiler)) } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 32c3ef53e128f..5cce07019e9d6 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -212,10 +212,10 @@ impl Step for HtmlCheck { } // Ensure that a few different kinds of documentation are available. builder.default_doc(&[]); - builder.ensure(crate::core::build_steps::doc::Rustc::new( - builder.top_stage, - self.target, + builder.ensure(crate::core::build_steps::doc::Rustc::for_stage( builder, + self.target, + builder.top_stage, )); builder diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 3b1b3dd2edd1e..e45a5b8fba9b0 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1808,11 +1808,9 @@ mod snapshot { .path("compiler") .stage(1) .render_steps(), @r" + [build] rustdoc 0 [build] llvm - [build] rustc 0 -> rustc 1 - [build] rustc 1 -> std 1 - [build] rustdoc 1 - [doc] rustc 1 + [doc] rustc 0 -> rustc 1 "); } @@ -1827,10 +1825,8 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 - [build] rustc 1 -> rustc 2 - [build] rustc 2 -> std 2 - [build] rustdoc 2 - [doc] rustc 2 + [build] rustdoc 1 + [doc] rustc 1 -> rustc 2 "); } diff --git a/src/ci/docker/host-x86_64/pr-check-2/Dockerfile b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile index f82e19bcbb47e..e1d706ee8170c 100644 --- a/src/ci/docker/host-x86_64/pr-check-2/Dockerfile +++ b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile @@ -31,13 +31,13 @@ ENV SCRIPT \ python3 ../x.py clippy ci && \ python3 ../x.py test --stage 1 core alloc std test proc_macro && \ python3 ../x.py test --stage 1 src/tools/compiletest && \ - python3 ../x.py doc --stage 0 bootstrap && \ + python3 ../x.py doc bootstrap && \ # Build both public and internal documentation. - RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 compiler && \ - RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 1 library && \ + RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc compiler && \ + RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library && \ mkdir -p /checkout/obj/staging/doc && \ cp -r build/x86_64-unknown-linux-gnu/doc /checkout/obj/staging && \ - RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 1 library/test && \ + RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library/test && \ # The BOOTSTRAP_TRACING flag is added to verify whether the # bootstrap process compiles successfully with this flag enabled. BOOTSTRAP_TRACING=1 python3 ../x.py --help From 02fc091c9d9410cf5c679f11a9ee1b7a661bd31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 16:35:50 +0200 Subject: [PATCH 03/13] Update `Reference` doc step --- src/bootstrap/src/core/build_steps/doc.rs | 55 ++++++++++++++++------- src/bootstrap/src/core/builder/tests.rs | 16 +++++++ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index dea1db1bc2b7e..24dadcd831319 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -57,7 +57,7 @@ macro_rules! book { src: builder.src.join($path), parent: Some(self), languages: $lang.into(), - rustdoc_compiler: None, + build_compiler: None, }) } } @@ -105,7 +105,7 @@ impl Step for UnstableBook { src: builder.md_doc_out(self.target).join("unstable-book"), parent: Some(self), languages: vec![], - rustdoc_compiler: None, + build_compiler: None, }) } } @@ -117,7 +117,8 @@ struct RustbookSrc { src: PathBuf, parent: Option

, languages: Vec<&'static str>, - rustdoc_compiler: Option, + /// Compiler whose rustdoc should be used to document things using `mdbook-spec`. + build_compiler: Option, } impl Step for RustbookSrc

{ @@ -150,7 +151,7 @@ impl Step for RustbookSrc

{ let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); - if let Some(compiler) = self.rustdoc_compiler { + if let Some(compiler) = self.build_compiler { let mut rustdoc = builder.rustdoc_for_compiler(compiler); rustdoc.pop(); let old_path = env::var_os("PATH").unwrap_or_default(); @@ -193,11 +194,21 @@ impl Step for RustbookSrc

{ builder.maybe_open_in_browser::

(index) } } + + fn metadata(&self) -> Option { + let mut metadata = StepMetadata::doc(&format!("{} (book)", self.name), self.target); + if let Some(compiler) = self.build_compiler { + metadata = metadata.built_by(compiler); + } + + Some(metadata) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct TheBook { - compiler: Compiler, + /// Compiler whose rustdoc will be used to generated documentation. + build_compiler: Compiler, target: TargetSelection, } @@ -212,7 +223,7 @@ impl Step for TheBook { fn make_run(run: RunConfig<'_>) { run.builder.ensure(TheBook { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: prepare_doc_compiler(run.builder, run.target, run.builder.top_stage), target: run.target, }); } @@ -229,7 +240,7 @@ impl Step for TheBook { fn run(self, builder: &Builder<'_>) { builder.require_submodule("src/doc/book", None); - let compiler = self.compiler; + let compiler = self.build_compiler; let target = self.target; let absolute_path = builder.src.join("src/doc/book"); @@ -242,7 +253,7 @@ impl Step for TheBook { src: absolute_path.clone(), parent: Some(self), languages: vec![], - rustdoc_compiler: None, + build_compiler: None, }); // building older edition redirects @@ -255,7 +266,7 @@ impl Step for TheBook { // treat the other editions as not having a parent. parent: Option::::None, languages: vec![], - rustdoc_compiler: None, + build_compiler: None, }); } @@ -1271,15 +1282,18 @@ impl Step for RustcBook { src: out_base, parent: Some(self), languages: vec![], - rustdoc_compiler: None, + build_compiler: None, }); } } +/// Documents the reference. +/// It is always done using a stage 1+ compiler, because it references in-tree compiler/stdlib +/// concepts. #[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)] pub struct Reference { - pub compiler: Compiler, - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl Step for Reference { @@ -1292,8 +1306,19 @@ impl Step for Reference { } fn make_run(run: RunConfig<'_>) { + // Bump the stage to 2, because the reference requires an in-tree compiler. + // At the same time, since this step is enabled by default, we don't want `x doc` to fail + // in stage 1. + // FIXME: create a shared method on builder for auto-bumping, and print some warning when + // it happens. + let stage = if run.builder.config.is_explicit_stage() || run.builder.top_stage >= 2 { + run.builder.top_stage + } else { + 2 + }; + run.builder.ensure(Reference { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: prepare_doc_compiler(run.builder, run.target, stage), target: run.target, }); } @@ -1304,14 +1329,14 @@ impl Step for Reference { // This is needed for generating links to the standard library using // the mdbook-spec plugin. - builder.std(self.compiler, builder.config.host_target); + builder.std(self.build_compiler, builder.config.host_target); // Run rustbook/mdbook to generate the HTML pages. builder.ensure(RustbookSrc { target: self.target, name: "reference".to_owned(), src: builder.src.join("src/doc/reference"), - rustdoc_compiler: Some(self.compiler), + build_compiler: Some(self.build_compiler), parent: Some(self), languages: vec![], }); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index e45a5b8fba9b0..4fc2f56da8887 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1870,6 +1870,22 @@ mod snapshot { [doc] Compiletest "); } + + // Reference should be auto-bumped to stage 2. + #[test] + fn doc_reference() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("doc") + .path("reference") + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 0 -> Rustbook 1 + [doc] rustc 1 -> reference (book) 2 + "); + } } struct ExecutedSteps { From 5217eddf04421249a602e79d06d562d49d6c8195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 16:45:24 +0200 Subject: [PATCH 04/13] Update `RustcBook` doc step --- src/bootstrap/src/core/build_steps/doc.rs | 33 ++++++++++++++++------ src/bootstrap/src/core/build_steps/test.rs | 7 ++--- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 24dadcd831319..3034ebdf22bd3 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1200,9 +1200,15 @@ fn symlink_dir_force(config: &Config, original: &Path, link: &Path) { #[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)] pub struct RustcBook { - pub compiler: Compiler, - pub target: TargetSelection, - pub validate: bool, + build_compiler: Compiler, + target: TargetSelection, + validate: bool, +} + +impl RustcBook { + pub fn validate(build_compiler: Compiler, target: TargetSelection) -> Self { + Self { build_compiler, target, validate: true } + } } impl Step for RustcBook { @@ -1216,8 +1222,17 @@ impl Step for RustcBook { } fn make_run(run: RunConfig<'_>) { + // Bump the stage to 2, because the rustc book requires an in-tree compiler. + // At the same time, since this step is enabled by default, we don't want `x doc` to fail + // in stage 1. + let stage = if run.builder.config.is_explicit_stage() || run.builder.top_stage >= 2 { + run.builder.top_stage + } else { + 2 + }; + run.builder.ensure(RustcBook { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: prepare_doc_compiler(run.builder, run.target, stage), target: run.target, validate: false, }); @@ -1235,10 +1250,10 @@ impl Step for RustcBook { builder.cp_link_r(&builder.src.join("src/doc/rustc"), &out_base); builder.info(&format!("Generating lint docs ({})", self.target)); - let rustc = builder.rustc(self.compiler); + let rustc = builder.rustc(self.build_compiler); // The tool runs `rustc` for extracting output examples, so it needs a // functional sysroot. - builder.std(self.compiler, self.target); + builder.std(self.build_compiler, self.target); let mut cmd = builder.tool_cmd(Tool::LintDocs); cmd.arg("--src"); cmd.arg(builder.src.join("compiler")); @@ -1264,12 +1279,12 @@ impl Step for RustcBook { // If the lib directories are in an unusual location (changed in // bootstrap.toml), then this needs to explicitly update the dylib search // path. - builder.add_rustc_lib_path(self.compiler, &mut cmd); + builder.add_rustc_lib_path(self.build_compiler, &mut cmd); let doc_generator_guard = builder.msg( Kind::Run, - self.compiler.stage, + self.build_compiler.stage, "lint-docs", - self.compiler.host, + self.build_compiler.host, self.target, ); cmd.run(builder); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 5cce07019e9d6..df7016005e9dc 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3310,11 +3310,8 @@ impl Step for LintDocs { /// Tests that the lint examples in the rustc book generate the correct /// lints and have the expected format. fn run(self, builder: &Builder<'_>) { - builder.ensure(crate::core::build_steps::doc::RustcBook { - compiler: self.compiler, - target: self.target, - validate: true, - }); + builder + .ensure(crate::core::build_steps::doc::RustcBook::validate(self.compiler, self.target)); } } From c35e847a400e4bb9c25d58e539cfb47e6bb58062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 17:17:02 +0200 Subject: [PATCH 05/13] Update `Standalone` and `Releases` doc steps --- src/bootstrap/src/core/build_steps/doc.rs | 45 +++++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 3034ebdf22bd3..9968baf831445 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -328,7 +328,7 @@ fn invoke_rustdoc( #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Standalone { - compiler: Compiler, + build_compiler: Compiler, target: TargetSelection, } @@ -343,7 +343,11 @@ impl Step for Standalone { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Standalone { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: prepare_doc_compiler( + run.builder, + run.builder.host_target, + run.builder.top_stage, + ), target: run.target, }); } @@ -358,8 +362,8 @@ impl Step for Standalone { /// In the end, this is just a glorified wrapper around rustdoc! fn run(self, builder: &Builder<'_>) { let target = self.target; - let compiler = self.compiler; - let _guard = builder.msg_doc(compiler, "standalone", target); + let build_compiler = self.build_compiler; + let _guard = builder.msg_doc(build_compiler, "standalone", target); let out = builder.doc_out(target); t!(fs::create_dir_all(&out)); @@ -378,7 +382,7 @@ impl Step for Standalone { } let html = out.join(filename).with_extension("html"); - let rustdoc = builder.rustdoc_for_compiler(compiler); + let rustdoc = builder.rustdoc_for_compiler(build_compiler); if up_to_date(&path, &html) && up_to_date(&footer, &html) && up_to_date(&favicon, &html) @@ -389,7 +393,7 @@ impl Step for Standalone { continue; } - let mut cmd = builder.rustdoc_cmd(compiler); + let mut cmd = builder.rustdoc_cmd(build_compiler); cmd.arg("--html-after-content") .arg(&footer) @@ -426,11 +430,15 @@ impl Step for Standalone { builder.open_in_browser(index); } } + + fn metadata(&self) -> Option { + Some(StepMetadata::doc("standalone", self.target).built_by(self.build_compiler)) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Releases { - compiler: Compiler, + build_compiler: Compiler, target: TargetSelection, } @@ -445,7 +453,11 @@ impl Step for Releases { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Releases { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: prepare_doc_compiler( + run.builder, + run.builder.host_target, + run.builder.top_stage, + ), target: run.target, }); } @@ -457,15 +469,12 @@ impl Step for Releases { /// the headline added. In the end, the conversion is done by Rustdoc. fn run(self, builder: &Builder<'_>) { let target = self.target; - let compiler = self.compiler; - let _guard = builder.msg_doc(compiler, "releases", target); + let build_compiler = self.build_compiler; + let _guard = builder.msg_doc(build_compiler, "releases", target); let out = builder.doc_out(target); t!(fs::create_dir_all(&out)); - builder.ensure(Standalone { - compiler: builder.compiler(builder.top_stage, builder.config.host_target), - target, - }); + builder.ensure(Standalone { build_compiler, target }); let version_info = builder.ensure(SharedAssets { target: self.target }).version_info; @@ -476,7 +485,7 @@ impl Step for Releases { let html = out.join("releases.html"); let tmppath = out.join("releases.md"); let inpath = builder.src.join("RELEASES.md"); - let rustdoc = builder.rustdoc_for_compiler(compiler); + let rustdoc = builder.rustdoc_for_compiler(build_compiler); if !up_to_date(&inpath, &html) || !up_to_date(&footer, &html) || !up_to_date(&favicon, &html) @@ -489,7 +498,7 @@ impl Step for Releases { t!(tmpfile.write_all(b"% Rust Release Notes\n\n")); t!(io::copy(&mut t!(fs::File::open(&inpath)), &mut tmpfile)); mem::drop(tmpfile); - let mut cmd = builder.rustdoc_cmd(compiler); + let mut cmd = builder.rustdoc_cmd(build_compiler); cmd.arg("--html-after-content") .arg(&footer) @@ -522,6 +531,10 @@ impl Step for Releases { builder.open_in_browser(&html); } } + + fn metadata(&self) -> Option { + Some(StepMetadata::doc("releases", self.target).built_by(self.build_compiler)) + } } #[derive(Debug, Clone)] From bec8e1dc38526c8a2856deb0119131946ec10c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 18:03:17 +0200 Subject: [PATCH 06/13] Fix documentation of tools --- src/bootstrap/src/core/build_steps/doc.rs | 86 ++++++++++++---------- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/core/builder/cargo.rs | 4 +- src/bootstrap/src/core/builder/tests.rs | 16 +--- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 9968baf831445..5b536072b0182 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -16,8 +16,7 @@ use crate::core::build_steps::tool::{ self, RustcPrivateCompilers, SourceType, Tool, prepare_tool_cargo, }; use crate::core::builder::{ - self, Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step, StepMetadata, - crate_description, + self, Builder, Compiler, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description, }; use crate::core::config::{Config, TargetSelection}; use crate::helpers::{submodule_path_of, symlink_dir, t, up_to_date}; @@ -26,7 +25,7 @@ use crate::{FileType, Mode}; macro_rules! book { ($($name:ident, $path:expr, $book_name:expr, $lang:expr ;)+) => { $( - #[derive(Debug, Clone, Hash, PartialEq, Eq)] + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $name { target: TargetSelection, } @@ -797,13 +796,21 @@ pub struct Rustc { impl Rustc { /// Document `stage` compiler for the given `target`. - pub(crate) fn for_stage(builder: &Builder<'_>, target: TargetSelection, stage: u32) -> Self { + pub(crate) fn for_stage(builder: &Builder<'_>, stage: u32, target: TargetSelection) -> Self { + let build_compiler = prepare_doc_compiler(builder, target, stage); + Self::from_build_compiler(builder, build_compiler, target) + } + + fn from_build_compiler( + builder: &Builder<'_>, + build_compiler: Compiler, + target: TargetSelection, + ) -> Self { let crates = builder .in_tree_crates("rustc-main", Some(target)) .into_iter() .map(|krate| krate.name.to_string()) .collect(); - let build_compiler = prepare_doc_compiler(builder, target, stage); Self { build_compiler, target, crates } } } @@ -821,7 +828,7 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustc::for_stage(run.builder, run.target, run.builder.top_stage)); + run.builder.ensure(Rustc::for_stage(run.builder, run.builder.top_stage, run.target)); } /// Generates compiler documentation. @@ -942,12 +949,14 @@ macro_rules! tool_doc { ( $tool: ident, $path: literal, - $(rustc_tool = $rustc_tool:literal, )? + $(rustc_private_tool = $rustc_private_tool:literal, )? $(is_library = $is_library:expr,)? $(crates = $crates:expr)? ) => { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $tool { + build_compiler: Compiler, + mode: Mode, target: TargetSelection, } @@ -962,15 +971,26 @@ macro_rules! tool_doc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure($tool { target: run.target }); + let target = run.target; + let (build_compiler, mode) = if true $(&& $rustc_private_tool)? { + // Rustdoc needs the rustc sysroot available to build. + let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, target); + + // Build rustc docs so that we generate relative links. + run.builder.ensure(Rustc::from_build_compiler(run.builder, compilers.build_compiler(), target)); + + (compilers.build_compiler(), Mode::ToolRustc) + } else { + // bootstrap/host tools have to be documented with the stage 0 compiler + (prepare_doc_compiler(run.builder, target, 1), Mode::ToolBootstrap) + }; + + run.builder.ensure($tool { build_compiler, mode, target }); } - /// Generates compiler documentation. + /// Generates documentation for a tool. /// - /// This will generate all documentation for compiler and dependencies. - /// Compiler documentation is distributed separately, so we make sure - /// we do not merge it with the other documentation from std, test and - /// proc_macros. This is largely just a wrapper around `cargo doc`. + /// This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) { let mut source_type = SourceType::InTree; @@ -979,31 +999,17 @@ macro_rules! tool_doc { builder.require_submodule(&submodule_path, None); } - let stage = builder.top_stage; - let target = self.target; + let $tool { build_compiler, mode, target } = self; // This is the intended out directory for compiler documentation. let out = builder.compiler_doc_out(target); t!(fs::create_dir_all(&out)); - let compiler = builder.compiler(stage, builder.config.host_target); - builder.std(compiler, target); - - if true $(&& $rustc_tool)? { - // Build rustc docs so that we generate relative links. - builder.ensure(Rustc::new(stage, target, builder)); - - // Rustdoc needs the rustc sysroot available to build. - // FIXME: is there a way to only ensure `check::Rustc` here? Last time I tried it failed - // with strange errors, but only on a full bors test ... - builder.ensure(compile::Rustc::new(compiler, target)); - } - // Build cargo command. let mut cargo = prepare_tool_cargo( builder, - compiler, - Mode::ToolRustc, + build_compiler, + mode, target, Kind::Doc, $path, @@ -1030,7 +1036,7 @@ macro_rules! tool_doc { cargo.rustdocflag("--show-type-layout"); cargo.rustdocflag("--generate-link-to-definition"); - let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc"); + let out_dir = builder.stage_out(build_compiler, mode).join(target).join("doc"); $(for krate in $crates { let dir_name = krate.replace("-", "_"); t!(fs::create_dir_all(out_dir.join(&*dir_name))); @@ -1038,10 +1044,10 @@ macro_rules! tool_doc { // Symlink compiler docs to the output directory of rustdoc documentation. symlink_dir_force(&builder.config, &out, &out_dir); - let proc_macro_out_dir = builder.stage_out(compiler, Mode::ToolRustc).join("doc"); + let proc_macro_out_dir = builder.stage_out(build_compiler, mode).join("doc"); symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); - let _guard = builder.msg_doc(compiler, stringify!($tool).to_lowercase(), target); + let _guard = builder.msg_doc(build_compiler, stringify!($tool).to_lowercase(), target); cargo.into_cmd().run(builder); if !builder.config.dry_run() { @@ -1055,7 +1061,7 @@ macro_rules! tool_doc { } fn metadata(&self) -> Option { - Some(StepMetadata::doc(stringify!($tool), self.target)) + Some(StepMetadata::doc(stringify!($tool), self.target).built_by(self.build_compiler)) } } } @@ -1065,7 +1071,7 @@ macro_rules! tool_doc { tool_doc!( BuildHelper, "src/build_helper", - rustc_tool = false, + rustc_private_tool = false, is_library = true, crates = ["build_helper"] ); @@ -1076,7 +1082,7 @@ tool_doc!(Miri, "src/tools/miri", crates = ["miri"]); tool_doc!( Cargo, "src/tools/cargo", - rustc_tool = false, + rustc_private_tool = false, crates = [ "cargo", "cargo-credential", @@ -1090,25 +1096,25 @@ tool_doc!( "rustfix", ] ); -tool_doc!(Tidy, "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); +tool_doc!(Tidy, "src/tools/tidy", rustc_private_tool = false, crates = ["tidy"]); tool_doc!( Bootstrap, "src/bootstrap", - rustc_tool = false, + rustc_private_tool = false, is_library = true, crates = ["bootstrap"] ); tool_doc!( RunMakeSupport, "src/tools/run-make-support", - rustc_tool = false, + rustc_private_tool = false, is_library = true, crates = ["run_make_support"] ); tool_doc!( Compiletest, "src/tools/compiletest", - rustc_tool = false, + rustc_private_tool = false, is_library = true, crates = ["compiletest"] ); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index df7016005e9dc..d6d7f7be1dfbb 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -214,8 +214,8 @@ impl Step for HtmlCheck { builder.default_doc(&[]); builder.ensure(crate::core::build_steps::doc::Rustc::for_stage( builder, - self.target, builder.top_stage, + self.target, )); builder diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index e10af2b55f9e1..6910cc7c57948 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -493,7 +493,9 @@ impl Builder<'_> { if cmd_kind == Kind::Doc { let my_out = match mode { // This is the intended out directory for compiler documentation. - Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target), + Mode::Rustc | Mode::ToolRustc | Mode::ToolBootstrap => { + self.compiler_doc_out(target) + } Mode::Std => { if self.config.cmd.json() { out_dir.join(target).join("json-doc") diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 4fc2f56da8887..8a22633b362d7 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1845,11 +1845,8 @@ mod snapshot { .path("src/tools/compiletest") .stage(1) .render_steps(), @r" - [build] llvm - [build] rustc 0 -> rustc 1 - [build] rustc 1 -> std 1 - [build] rustdoc 1 - [doc] Compiletest + [build] rustdoc 0 + [doc] rustc 0 -> Compiletest 1 "); } @@ -1861,13 +1858,8 @@ mod snapshot { .path("src/tools/compiletest") .stage(2) .render_steps(), @r" - [build] llvm - [build] rustc 0 -> rustc 1 - [build] rustc 1 -> std 1 - [build] rustc 1 -> rustc 2 - [build] rustc 2 -> std 2 - [build] rustdoc 2 - [doc] Compiletest + [build] rustdoc 0 + [doc] rustc 0 -> Compiletest 1 "); } From 8f3f060c02d826d4b91bf1c936fce2ffea883bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 18:29:57 +0200 Subject: [PATCH 07/13] Update `Std` doc step --- src/bootstrap/src/core/build_steps/dist.rs | 22 +++++++----- src/bootstrap/src/core/build_steps/doc.rs | 41 +++++++++++++--------- src/bootstrap/src/core/build_steps/test.rs | 4 +-- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 3fbc8cdbcd5ad..f8393d8701472 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -92,7 +92,8 @@ impl Step for Docs { #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] pub struct JsonDocs { - pub host: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl Step for JsonDocs { @@ -105,24 +106,27 @@ impl Step for JsonDocs { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(JsonDocs { host: run.target }); + run.builder.ensure(JsonDocs { + build_compiler: run.builder.compiler(run.builder.top_stage, run.builder.host_target), + target: run.target, + }); } /// Builds the `rust-docs-json` installer component. fn run(self, builder: &Builder<'_>) -> Option { - let host = self.host; - builder.ensure(crate::core::build_steps::doc::Std::new( - builder.top_stage, - host, + let target = self.target; + builder.ensure(crate::core::build_steps::doc::Std::from_build_compiler( + self.build_compiler, + target, DocumentationFormat::Json, )); let dest = "share/doc/rust/json"; - let mut tarball = Tarball::new(builder, "rust-docs-json", &host.triple); + let mut tarball = Tarball::new(builder, "rust-docs-json", &target.triple); tarball.set_product_name("Rust Documentation In JSON Format"); tarball.is_preview(true); - tarball.add_bulk_dir(builder.json_doc_out(host), dest); + tarball.add_bulk_dir(builder.json_doc_out(target), dest); Some(tarball.generate()) } } @@ -1583,7 +1587,7 @@ impl Step for Extended { } add_component!("rust-docs" => Docs { host: target }); - add_component!("rust-json-docs" => JsonDocs { host: target }); + add_component!("rust-json-docs" => JsonDocs { build_compiler: compiler, target }); add_component!("cargo" => Cargo { build_compiler: compiler, target }); add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target }); add_component!("rust-analyzer" => RustAnalyzer { build_compiler: compiler, target }); diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 5b536072b0182..7ab50febad4a1 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -579,17 +579,22 @@ impl Step for SharedAssets { } } +/// Document the standard library using `build_compiler`. #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Std { - pub stage: u32, - pub target: TargetSelection, - pub format: DocumentationFormat, + build_compiler: Compiler, + target: TargetSelection, + format: DocumentationFormat, crates: Vec, } impl Std { - pub(crate) fn new(stage: u32, target: TargetSelection, format: DocumentationFormat) -> Self { - Std { stage, target, format, crates: vec![] } + pub(crate) fn from_build_compiler( + build_compiler: Compiler, + target: TargetSelection, + format: DocumentationFormat, + ) -> Self { + Std { build_compiler, target, format, crates: vec![] } } } @@ -609,7 +614,7 @@ impl Step for Std { return; } run.builder.ensure(Std { - stage: run.builder.top_stage, + build_compiler: run.builder.compiler(run.builder.top_stage, run.builder.host_target), target: run.target, format: if run.builder.config.cmd.json() { DocumentationFormat::Json @@ -625,7 +630,6 @@ impl Step for Std { /// This will generate all documentation for the standard library and its /// dependencies. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) { - let stage = self.stage; let target = self.target; let crates = if self.crates.is_empty() { builder @@ -667,7 +671,7 @@ impl Step for Std { // For `--index-page` and `--output-format=json`. extra_args.push("-Zunstable-options"); - doc_std(builder, self.format, stage, target, &out, &extra_args, &crates); + doc_std(builder, self.format, self.build_compiler, target, &out, &extra_args, &crates); // Don't open if the format is json if let DocumentationFormat::Json = self.format { @@ -692,7 +696,7 @@ impl Step for Std { fn metadata(&self) -> Option { Some( StepMetadata::doc("std", self.target) - .stage(self.stage) + .built_by(self.build_compiler) .with_metadata(format!("crates=[{}]", self.crates.join(","))), ) } @@ -728,24 +732,29 @@ impl DocumentationFormat { fn doc_std( builder: &Builder<'_>, format: DocumentationFormat, - stage: u32, + build_compiler: Compiler, target: TargetSelection, out: &Path, extra_args: &[&str], requested_crates: &[String], ) { - let compiler = builder.compiler(stage, builder.config.host_target); - let target_doc_dir_name = if format == DocumentationFormat::Json { "json-doc" } else { "doc" }; - let target_dir = builder.stage_out(compiler, Mode::Std).join(target).join(target_doc_dir_name); + let target_dir = + builder.stage_out(build_compiler, Mode::Std).join(target).join(target_doc_dir_name); // This is directory where the compiler will place the output of the command. // We will then copy the files from this directory into the final `out` directory, the specified // as a function parameter. let out_dir = target_dir.join(target).join("doc"); - let mut cargo = - builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, Kind::Doc); + let mut cargo = builder::Cargo::new( + builder, + build_compiler, + Mode::Std, + SourceType::InTree, + target, + Kind::Doc, + ); compile::std_cargo(builder, target, &mut cargo); cargo @@ -773,7 +782,7 @@ fn doc_std( let description = format!("library{} in {} format", crate_description(requested_crates), format.as_str()); - let _guard = builder.msg_doc(compiler, description, target); + let _guard = builder.msg_doc(build_compiler, description, target); cargo.into_cmd().run(builder); builder.cp_link_r(&out_dir, out); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index d6d7f7be1dfbb..2f933baa4a4cd 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -983,8 +983,8 @@ impl Step for RustdocJSStd { command.arg("--test-file").arg(path); } } - builder.ensure(crate::core::build_steps::doc::Std::new( - builder.top_stage, + builder.ensure(crate::core::build_steps::doc::Std::from_build_compiler( + builder.compiler(builder.top_stage, builder.host_target), self.target, DocumentationFormat::Html, )); From fe01f580e28c3864747c8115b0c3b402ebb38fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 6 Aug 2025 18:32:13 +0200 Subject: [PATCH 08/13] Update `doc` CI steps stage 2 As they were previously. --- src/ci/docker/host-x86_64/pr-check-2/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/pr-check-2/Dockerfile b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile index e1d706ee8170c..1a21912559365 100644 --- a/src/ci/docker/host-x86_64/pr-check-2/Dockerfile +++ b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile @@ -33,11 +33,11 @@ ENV SCRIPT \ python3 ../x.py test --stage 1 src/tools/compiletest && \ python3 ../x.py doc bootstrap && \ # Build both public and internal documentation. - RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc compiler && \ - RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library && \ + RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc compiler --stage 2 && \ + RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library --stage 2 && \ mkdir -p /checkout/obj/staging/doc && \ cp -r build/x86_64-unknown-linux-gnu/doc /checkout/obj/staging && \ - RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library/test && \ + RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library/test --stage 2 && \ # The BOOTSTRAP_TRACING flag is added to verify whether the # bootstrap process compiles successfully with this flag enabled. BOOTSTRAP_TRACING=1 python3 ../x.py --help From 6443dc0964101bdd73c8b4fd25868392f34f5955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 8 Aug 2025 08:16:32 +0200 Subject: [PATCH 09/13] Update tests --- src/bootstrap/src/core/builder/tests.rs | 245 ++++++++++++++++++++---- 1 file changed, 208 insertions(+), 37 deletions(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 8a22633b362d7..cfbd2a0f484b3 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -954,7 +954,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 -> std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] "); } @@ -1023,19 +1023,36 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [build] rustc 0 -> GenerateCopyright 1 [dist] rustc @@ -1061,25 +1078,42 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 0 -> LldWrapper 1 [build] rustc 0 -> WasmComponentLd 1 [build] rustc 0 -> LlvmBitcodeLinker 1 [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustc 1 -> LldWrapper 2 [build] rustc 1 -> WasmComponentLd 2 [build] rustc 1 -> LlvmBitcodeLinker 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 [build] rustc 0 -> GenerateCopyright 1 @@ -1094,6 +1128,7 @@ mod snapshot { [build] rustc 1 -> cargo-clippy 2 [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 + [doc] rustc 1 -> std 1 crates=[] "); } @@ -1108,22 +1143,56 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 + [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [doc] rustc 1 -> standalone 2 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rustdoc (book) + [doc] rust-by-example (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs [dist] docs - [doc] std 2 crates=[] - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [dist] mingw [build] rustc 0 -> GenerateCopyright 1 @@ -1147,12 +1216,19 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 [build] llvm @@ -1160,12 +1236,22 @@ mod snapshot { [build] rustc 1 -> rustc 2 [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 - [build] rustc 2 -> std 2 + [doc] rustc (book) + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [build] rustc 0 -> GenerateCopyright 1 [dist] rustc @@ -1188,28 +1274,61 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 + [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [doc] rustc 1 -> standalone 2 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 [build] llvm - [build] rustc 1 -> std 1 [build] rustc 1 -> rustc 2 [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rustdoc (book) + [doc] rust-by-example (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 - [build] rustc 2 -> std 2 + [doc] rustc (book) + [doc] rustc (book) + [doc] cargo (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs [dist] docs - [doc] std 2 crates=[] - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [dist] mingw [build] rustc 0 -> GenerateCopyright 1 @@ -1234,16 +1353,33 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 [build] rustc 1 -> std 1 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] - [build] rustc 2 -> std 2 + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [build] rustc 2 -> std 2 [dist] rustc 2 -> std 2 @@ -1264,26 +1400,42 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 0 -> WasmComponentLd 1 + [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 [build] rustc 1 -> std 1 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustc 1 -> WasmComponentLd 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] llvm - [build] rustc 1 -> std 1 [build] rustc 1 -> rustc 2 [build] rustc 1 -> WasmComponentLd 2 [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [build] rustdoc 2 [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 @@ -1300,6 +1452,7 @@ mod snapshot { [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 [build] rustc 1 -> LlvmBitcodeLinker 2 + [doc] rustc 1 -> std 1 crates=[] "); } @@ -1708,14 +1861,32 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 0 + [doc] rustc 0 -> standalone 1 [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 -> std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 0 -> error-index 1 [doc] rustc 0 -> error-index 1 + [doc] nomicon (book) [build] rustc 1 -> std 1 + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 0 -> releases 1 "); } @@ -1729,7 +1900,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 -> std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] "); } @@ -1743,7 +1914,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[core] + [doc] rustc 1 -> std 1 crates=[core] "); } @@ -1758,7 +1929,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[core] + [doc] rustc 1 -> std 1 crates=[core] "); } @@ -1773,7 +1944,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[alloc,core] + [doc] rustc 1 -> std 1 crates=[alloc,core] "); } @@ -1789,7 +1960,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustdoc 1 - [doc] std 1 crates=[alloc,core] + [doc] rustc 1 -> std 1 crates=[alloc,core] "); } From c843e1d28f564d623c90b4cb3ee009ba6bebc1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 8 Aug 2025 08:18:48 +0200 Subject: [PATCH 10/13] Add change tracker entry --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index d3331b81587ee..091956e7e5f3e 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -491,4 +491,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "Added `build.compiletest-allow-stage0` flag instead of `COMPILETEST_FORCE_STAGE0` env var, and reject running `compiletest` self tests against stage 0 rustc unless explicitly allowed.", }, + ChangeInfo { + change_id: 145011, + severity: ChangeSeverity::Warning, + summary: "It is no longer possible to `x doc` with stage 0. All doc commands have to be on stage 1+.", + }, ]; From 89a27d26dcc36c3286cc1e88de704bc83f5f9859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 10 Aug 2025 11:29:44 +0200 Subject: [PATCH 11/13] Review remarks --- src/bootstrap/src/core/build_steps/doc.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 7ab50febad4a1..28a764dc8ba0b 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -790,6 +790,7 @@ fn doc_std( /// Prepare a compiler that will be able to document something for `target` at `stage`. fn prepare_doc_compiler(builder: &Builder<'_>, target: TargetSelection, stage: u32) -> Compiler { + assert!(stage > 0, "Cannot document anything in stage 0"); let build_compiler = builder.compiler(stage - 1, builder.host_target); builder.std(build_compiler, target); build_compiler @@ -1226,10 +1227,13 @@ fn symlink_dir_force(config: &Config, original: &Path, link: &Path) { ); } +/// Builds the Rust compiler book. #[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)] pub struct RustcBook { build_compiler: Compiler, target: TargetSelection, + /// Test that the examples of lints in the book produce the correct lints in the expected + /// format. validate: bool, } @@ -1331,8 +1335,8 @@ impl Step for RustcBook { } /// Documents the reference. -/// It is always done using a stage 1+ compiler, because it references in-tree compiler/stdlib -/// concepts. +/// It has to always be done using a stage 1+ compiler, because it references in-tree +/// compiler/stdlib concepts. #[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)] pub struct Reference { build_compiler: Compiler, From 8d53418bd4648e738a0d9b03570d0f66fe24415c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 10 Aug 2025 11:40:43 +0200 Subject: [PATCH 12/13] Bless tests --- src/bootstrap/src/core/builder/tests.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index cfbd2a0f484b3..b60ca5f428fdb 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1468,21 +1468,38 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 0 -> rustc_codegen_cranelift 1 [build] rustc 1 -> std 1 + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [build] rustdoc 1 + [doc] rustc 1 -> standalone 2 [build] rustc 1 -> rustc 2 [build] rustc 1 -> rustc_codegen_cranelift 2 [build] rustdoc 2 - [doc] std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 - [build] rustc 2 -> std 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [doc] std 2 crates=[] + [doc] rustc 2 -> std 2 crates=[] [dist] mingw [build] rustc 0 -> GenerateCopyright 1 [dist] rustc From 8b4d9411bacf46fcdd47c8613dee9b4ebe3a1cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 10 Aug 2025 16:32:40 +0200 Subject: [PATCH 13/13] Explicitly pass path to built stdlib JSON docs and use the correct compiler for it --- src/bootstrap/src/core/build_steps/dist.rs | 10 +++--- src/bootstrap/src/core/build_steps/doc.rs | 36 ++++++++++++---------- src/bootstrap/src/core/builder/tests.rs | 3 +- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f8393d8701472..c2f46e66c3f56 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -115,7 +115,7 @@ impl Step for JsonDocs { /// Builds the `rust-docs-json` installer component. fn run(self, builder: &Builder<'_>) -> Option { let target = self.target; - builder.ensure(crate::core::build_steps::doc::Std::from_build_compiler( + let directory = builder.ensure(crate::core::build_steps::doc::Std::from_build_compiler( self.build_compiler, target, DocumentationFormat::Json, @@ -126,7 +126,7 @@ impl Step for JsonDocs { let mut tarball = Tarball::new(builder, "rust-docs-json", &target.triple); tarball.set_product_name("Rust Documentation In JSON Format"); tarball.is_preview(true); - tarball.add_bulk_dir(builder.json_doc_out(target), dest); + tarball.add_bulk_dir(directory, dest); Some(tarball.generate()) } } @@ -1575,11 +1575,12 @@ impl Step for Extended { }; } + let target_compiler = builder.compiler(stage, target); // When rust-std package split from rustc, we needed to ensure that during // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering // the std files during uninstall. To do this ensure that rustc comes // before rust-std in the list below. - tarballs.push(builder.ensure(Rustc { compiler: builder.compiler(stage, target) })); + tarballs.push(builder.ensure(Rustc { compiler: target_compiler })); tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std")); if target.is_windows_gnu() { @@ -1587,7 +1588,8 @@ impl Step for Extended { } add_component!("rust-docs" => Docs { host: target }); - add_component!("rust-json-docs" => JsonDocs { build_compiler: compiler, target }); + // Std stage N is documented with compiler stage N + add_component!("rust-json-docs" => JsonDocs { build_compiler: target_compiler, target }); add_component!("cargo" => Cargo { build_compiler: compiler, target }); add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target }); add_component!("rust-analyzer" => RustAnalyzer { build_compiler: compiler, target }); diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 28a764dc8ba0b..ca7a6dc8e07ed 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -599,7 +599,9 @@ impl Std { } impl Step for Std { - type Output = (); + /// Path to a directory with the built documentation. + type Output = PathBuf; + const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -629,7 +631,7 @@ impl Step for Std { /// /// This will generate all documentation for the standard library and its /// dependencies. This is largely just a wrapper around `cargo doc`. - fn run(self, builder: &Builder<'_>) { + fn run(self, builder: &Builder<'_>) -> Self::Output { let target = self.target; let crates = if self.crates.is_empty() { builder @@ -673,24 +675,24 @@ impl Step for Std { doc_std(builder, self.format, self.build_compiler, target, &out, &extra_args, &crates); - // Don't open if the format is json - if let DocumentationFormat::Json = self.format { - return; - } - - if builder.paths.iter().any(|path| path.ends_with("library")) { - // For `x.py doc library --open`, open `std` by default. - let index = out.join("std").join("index.html"); - builder.open_in_browser(index); - } else { - for requested_crate in crates { - if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) { - let index = out.join(requested_crate).join("index.html"); - builder.open_in_browser(index); - break; + // Open if the format is HTML + if let DocumentationFormat::Html = self.format { + if builder.paths.iter().any(|path| path.ends_with("library")) { + // For `x.py doc library --open`, open `std` by default. + let index = out.join("std").join("index.html"); + builder.open_in_browser(index); + } else { + for requested_crate in crates { + if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) { + let index = out.join(requested_crate).join("index.html"); + builder.open_in_browser(index); + break; + } } } } + + out } fn metadata(&self) -> Option { diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b60ca5f428fdb..32d191c4265de 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1128,7 +1128,6 @@ mod snapshot { [build] rustc 1 -> cargo-clippy 2 [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 - [doc] rustc 1 -> std 1 crates=[] "); } @@ -1452,7 +1451,7 @@ mod snapshot { [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 [build] rustc 1 -> LlvmBitcodeLinker 2 - [doc] rustc 1 -> std 1 crates=[] + [doc] rustc 2 -> std 2 crates=[] "); }