diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index ca7a6dc8e07ed..6f32c23a909a7 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -80,6 +80,7 @@ book!( #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct UnstableBook { + build_compiler: Compiler, target: TargetSelection, } @@ -93,11 +94,24 @@ impl Step for UnstableBook { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(UnstableBook { target: run.target }); + // Bump the stage to 2, because the unstable 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(UnstableBook { + build_compiler: prepare_doc_compiler(run.builder, run.target, stage), + target: run.target, + }); } fn run(self, builder: &Builder<'_>) { - builder.ensure(UnstableBookGen { target: self.target }); + builder + .ensure(UnstableBookGen { build_compiler: self.build_compiler, target: self.target }); builder.ensure(RustbookSrc { target: self.target, name: "unstable-book".to_owned(), @@ -1175,6 +1189,7 @@ impl Step for ErrorIndex { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct UnstableBookGen { + build_compiler: Compiler, target: TargetSelection, } @@ -1189,11 +1204,15 @@ impl Step for UnstableBookGen { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(UnstableBookGen { target: run.target }); + run.builder.ensure(UnstableBookGen { + build_compiler: prepare_doc_compiler(run.builder, run.target, run.builder.top_stage), + target: run.target, + }); } fn run(self, builder: &Builder<'_>) { let target = self.target; + let rustc_path = builder.rustc(self.build_compiler); builder.info(&format!("Generating unstable book md files ({target})")); let out = builder.md_doc_out(target).join("unstable-book"); @@ -1203,6 +1222,7 @@ impl Step for UnstableBookGen { cmd.arg(builder.src.join("library")); cmd.arg(builder.src.join("compiler")); cmd.arg(builder.src.join("src")); + cmd.arg(rustc_path); cmd.arg(out); cmd.run(builder); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 32d191c4265de..59d66bdb496f0 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1021,12 +1021,12 @@ mod snapshot { ctx .config("dist") .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 + [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) @@ -1076,15 +1076,15 @@ mod snapshot { "rust.lld=true", ]) .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 + [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) @@ -1140,19 +1140,19 @@ mod snapshot { .hosts(&[&host_target()]) .targets(&[&host_target(), TEST_TRIPLE_1]) .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 [doc] unstable-book (book) + [build] rustc 1 -> std 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] book (book) [doc] book/first-edition (book) [doc] book/second-edition (book) @@ -1213,12 +1213,13 @@ mod snapshot { .hosts(&[&host_target(), TEST_TRIPLE_1]) .targets(&[&host_target()]) .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 + [build] rustc 0 -> UnstableBookGen 1 + [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) + [build] rustc 1 -> std 1 [doc] book (book) [doc] book/first-edition (book) [doc] book/second-edition (book) @@ -1231,7 +1232,6 @@ mod snapshot { [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 @@ -1271,19 +1271,19 @@ mod snapshot { .hosts(&[&host_target(), TEST_TRIPLE_1]) .targets(&[&host_target(), TEST_TRIPLE_1]) .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 [doc] unstable-book (book) + [build] rustc 1 -> std 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] book (book) [doc] book/first-edition (book) [doc] book/second-edition (book) @@ -1350,12 +1350,12 @@ mod snapshot { .hosts(&[]) .targets(&[TEST_TRIPLE_1]) .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 + [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) @@ -1397,13 +1397,13 @@ mod snapshot { .targets(&[TEST_TRIPLE_1]) .args(&["--set", "rust.channel=nightly", "--set", "build.extended=true"]) .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 + [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) @@ -1465,13 +1465,13 @@ mod snapshot { .config("dist") .args(&["--set", "rust.codegen-backends=['llvm', 'cranelift']"]) .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 + [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) @@ -1875,6 +1875,9 @@ mod snapshot { insta::assert_snapshot!( ctx.config("doc") .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 [doc] unstable-book (book) @@ -1884,14 +1887,11 @@ mod snapshot { [doc] book/2018-edition (book) [build] rustdoc 0 [doc] rustc 0 -> standalone 1 - [build] llvm - [build] rustc 0 -> rustc 1 [build] rustdoc 1 [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) diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index a7c6173d88c48..38f58a85ccc0f 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -4,11 +4,14 @@ use std::collections::BTreeSet; use std::env; use std::fs::{self, write}; use std::path::Path; +use std::process::Command; -use tidy::features::{Features, collect_env_vars, collect_lang_features, collect_lib_features}; +use tidy::features::{ + Feature, Features, Status, collect_env_vars, collect_lang_features, collect_lib_features, +}; use tidy::t; use tidy::unstable_book::{ - ENV_VARS_DIR, LANG_FEATURES_DIR, LIB_FEATURES_DIR, PATH_STR, + COMPILER_FLAGS_DIR, ENV_VARS_DIR, LANG_FEATURES_DIR, LIB_FEATURES_DIR, PATH_STR, collect_unstable_book_section_file_names, collect_unstable_feature_names, }; @@ -38,8 +41,15 @@ fn set_to_summary_str(set: &BTreeSet, dir: &str) -> String { .fold("".to_owned(), |s, a| s + &a + "\n") } -fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Features) { - let compiler_flags = collect_unstable_book_section_file_names(&path.join("src/compiler-flags")); +fn generate_summary( + path: &Path, + lang_features: &Features, + lib_features: &Features, + compiler_flags: &Features, +) { + let compiler_flags = + &collect_unstable_book_section_file_names(&path.join("src/compiler-flags")) + | &collect_unstable_feature_names(&compiler_flags); let compiler_env_vars = collect_unstable_book_section_file_names(&path.join("src/compiler-environment-variables")); @@ -112,14 +122,48 @@ fn copy_recursive(from: &Path, to: &Path) { } } +fn collect_compiler_flags(rustc_path: impl AsRef) -> Features { + let mut rustc = Command::new(rustc_path.as_ref()); + rustc.arg("-Zhelp"); + + let output = t!(rustc.output()); + let help_str = t!(String::from_utf8(output.stdout)); + let parts = help_str.split("\n -Z").collect::>(); + assert!(!parts[1..].is_empty(), "no -Z options were found"); + + let mut features = Features::new(); + for part in parts.into_iter().skip(1) { + let (name, description) = + part.split_once("--").expect("name and description should be delimited by '--'"); + let name = name.trim().trim_end_matches("=val"); + let description = description.trim(); + + features.insert( + name.replace('-', "_"), + Feature { + level: Status::Unstable, + since: None, + has_gate_test: false, + tracking_issue: None, + file: "".into(), + line: 0, + description: Some(description.to_owned()), + }, + ); + } + features +} + fn main() { let library_path_str = env::args_os().nth(1).expect("library/ path required"); let compiler_path_str = env::args_os().nth(2).expect("compiler/ path required"); let src_path_str = env::args_os().nth(3).expect("src/ path required"); - let dest_path_str = env::args_os().nth(4).expect("destination path required"); + let rustc_path_str = env::args_os().nth(4).expect("rustc path required"); + let dest_path_str = env::args_os().nth(5).expect("destination path required"); let library_path = Path::new(&library_path_str); let compiler_path = Path::new(&compiler_path_str); let src_path = Path::new(&src_path_str); + let rustc_path = Path::new(&rustc_path_str); let dest_path = Path::new(&dest_path_str); let lang_features = collect_lang_features(compiler_path, &mut false); @@ -128,6 +172,7 @@ fn main() { .filter(|&(ref name, _)| !lang_features.contains_key(name)) .collect(); let env_vars = collect_env_vars(compiler_path); + let compiler_flags = collect_compiler_flags(rustc_path); let doc_src_path = src_path.join(PATH_STR); @@ -143,9 +188,14 @@ fn main() { &dest_path.join(LIB_FEATURES_DIR), &lib_features, ); + generate_feature_files( + &doc_src_path.join(COMPILER_FLAGS_DIR), + &dest_path.join(COMPILER_FLAGS_DIR), + &compiler_flags, + ); generate_env_files(&doc_src_path.join(ENV_VARS_DIR), &dest_path.join(ENV_VARS_DIR), &env_vars); copy_recursive(&doc_src_path, &dest_path); - generate_summary(&dest_path, &lang_features, &lib_features); + generate_summary(&dest_path, &lang_features, &lib_features, &compiler_flags); }