diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bootstrap/src/core/build_steps/dist.rs | 40 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/doc.rs | 337 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/llvm.rs | 9 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/test.rs | 15 | ||||
| -rw-r--r-- | src/bootstrap/src/core/builder/cargo.rs | 4 | ||||
| -rw-r--r-- | src/bootstrap/src/core/builder/tests.rs | 354 | ||||
| -rw-r--r-- | src/bootstrap/src/core/config/config.rs | 707 | ||||
| -rw-r--r-- | src/bootstrap/src/core/download.rs | 37 | ||||
| -rw-r--r-- | src/bootstrap/src/utils/change_tracker.rs | 5 | ||||
| -rw-r--r-- | src/ci/docker/host-x86_64/pr-check-2/Dockerfile | 8 | ||||
| -rwxr-xr-x | src/ci/run.sh | 3 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs | 9 |
12 files changed, 973 insertions, 555 deletions
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 8f0de4c87d8..f9cb300b68e 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -93,7 +93,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 { @@ -106,24 +107,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<GeneratedTarball> { - let host = self.host; - builder.ensure(crate::core::build_steps::doc::Std::new( - builder.top_stage, - host, + let target = self.target; + let directory = 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(directory, dest); Some(tarball.generate()) } } @@ -926,6 +930,8 @@ fn copy_src_dirs( "llvm-project\\cmake", "llvm-project/runtimes", "llvm-project\\runtimes", + "llvm-project/third-party", + "llvm-project\\third-party", ]; if spath.contains("llvm-project") && !spath.ends_with("llvm-project") @@ -934,6 +940,18 @@ fn copy_src_dirs( return false; } + // Keep only these third party libraries + const LLVM_THIRD_PARTY: &[&str] = + &["llvm-project/third-party/siphash", "llvm-project\\third-party\\siphash"]; + if (spath.starts_with("llvm-project/third-party") + || spath.starts_with("llvm-project\\third-party")) + && !(spath.ends_with("llvm-project/third-party") + || spath.ends_with("llvm-project\\third-party")) + && !LLVM_THIRD_PARTY.iter().any(|path| spath.contains(path)) + { + return false; + } + const LLVM_TEST: &[&str] = &["llvm-project/llvm/test", "llvm-project\\llvm\\test"]; if LLVM_TEST.iter().any(|path| spath.contains(path)) && (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s")) @@ -1566,11 +1584,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() { @@ -1578,7 +1597,8 @@ impl Step for Extended { } add_component!("rust-docs" => Docs { host: target }); - add_component!("rust-json-docs" => JsonDocs { host: 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 434e9c0977d..ca7a6dc8e07 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, } @@ -57,7 +56,7 @@ macro_rules! book { src: builder.src.join($path), parent: Some(self), languages: $lang.into(), - rustdoc_compiler: None, + build_compiler: None, }) } } @@ -105,7 +104,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 +116,8 @@ struct RustbookSrc<P: Step> { src: PathBuf, parent: Option<P>, languages: Vec<&'static str>, - rustdoc_compiler: Option<Compiler>, + /// Compiler whose rustdoc should be used to document things using `mdbook-spec`. + build_compiler: Option<Compiler>, } impl<P: Step> Step for RustbookSrc<P> { @@ -150,7 +150,7 @@ impl<P: Step> Step for RustbookSrc<P> { 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 +193,21 @@ impl<P: Step> Step for RustbookSrc<P> { builder.maybe_open_in_browser::<P>(index) } } + + fn metadata(&self) -> Option<StepMetadata> { + 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 +222,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 +239,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 +252,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 +265,7 @@ impl Step for TheBook { // treat the other editions as not having a parent. parent: Option::<Self>::None, languages: vec![], - rustdoc_compiler: None, + build_compiler: None, }); } @@ -317,7 +327,7 @@ fn invoke_rustdoc( #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Standalone { - compiler: Compiler, + build_compiler: Compiler, target: TargetSelection, } @@ -332,7 +342,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, }); } @@ -347,8 +361,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)); @@ -367,7 +381,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) @@ -378,7 +392,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) @@ -415,11 +429,15 @@ impl Step for Standalone { builder.open_in_browser(index); } } + + fn metadata(&self) -> Option<StepMetadata> { + 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, } @@ -434,7 +452,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, }); } @@ -446,15 +468,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; @@ -465,7 +484,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) @@ -478,7 +497,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) @@ -511,6 +530,10 @@ impl Step for Releases { builder.open_in_browser(&html); } } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::doc("releases", self.target).built_by(self.build_compiler)) + } } #[derive(Debug, Clone)] @@ -556,22 +579,29 @@ 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<String>, } 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![] } } } 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<'_> { @@ -586,7 +616,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 @@ -601,8 +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<'_>) { - let stage = self.stage; + fn run(self, builder: &Builder<'_>) -> Self::Output { let target = self.target; let crates = if self.crates.is_empty() { builder @@ -644,32 +673,32 @@ 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 { - 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<StepMetadata> { Some( StepMetadata::doc("std", self.target) - .stage(self.stage) + .built_by(self.build_compiler) .with_metadata(format!("crates=[{}]", self.crates.join(","))), ) } @@ -705,24 +734,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 @@ -750,27 +784,46 @@ 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); } +/// 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 +} + +/// 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<String>, } 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<'_>, 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(); - Self { stage, target, crates } + Self { build_compiler, target, crates } } } @@ -787,11 +840,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.builder.top_stage, run.target)); } /// Generates compiler documentation. @@ -801,7 +850,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 +858,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 +890,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 +905,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 +927,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 +953,7 @@ impl Step for Rustc { } fn metadata(&self) -> Option<StepMetadata> { - Some(StepMetadata::doc("rustc", self.target).stage(self.stage)) + Some(StepMetadata::doc("rustc", self.target).built_by(self.build_compiler)) } } @@ -913,12 +961,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, } @@ -933,15 +983,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; @@ -950,31 +1011,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, @@ -1001,7 +1048,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))); @@ -1009,10 +1056,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() { @@ -1026,7 +1073,7 @@ macro_rules! tool_doc { } fn metadata(&self) -> Option<StepMetadata> { - Some(StepMetadata::doc(stringify!($tool), self.target)) + Some(StepMetadata::doc(stringify!($tool), self.target).built_by(self.build_compiler)) } } } @@ -1036,7 +1083,7 @@ macro_rules! tool_doc { tool_doc!( BuildHelper, "src/build_helper", - rustc_tool = false, + rustc_private_tool = false, is_library = true, crates = ["build_helper"] ); @@ -1047,7 +1094,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", @@ -1061,25 +1108,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"] ); @@ -1182,11 +1229,20 @@ 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 { - pub compiler: Compiler, - pub target: TargetSelection, - pub validate: bool, + build_compiler: Compiler, + target: TargetSelection, + /// Test that the examples of lints in the book produce the correct lints in the expected + /// format. + validate: bool, +} + +impl RustcBook { + pub fn validate(build_compiler: Compiler, target: TargetSelection) -> Self { + Self { build_compiler, target, validate: true } + } } impl Step for RustcBook { @@ -1200,8 +1256,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, }); @@ -1219,10 +1284,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")); @@ -1248,12 +1313,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); @@ -1266,15 +1331,18 @@ impl Step for RustcBook { src: out_base, parent: Some(self), languages: vec![], - rustdoc_compiler: None, + build_compiler: None, }); } } +/// Documents the reference. +/// 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 { - pub compiler: Compiler, - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl Step for Reference { @@ -1287,8 +1355,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, }); } @@ -1299,14 +1378,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/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 79244827059..16941a32bb1 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -196,7 +196,10 @@ pub(crate) fn detect_llvm_freshness(config: &Config, is_git: bool) -> PathFreshn /// /// This checks the build triple platform to confirm we're usable at all, and if LLVM /// with/without assertions is available. -pub(crate) fn is_ci_llvm_available_for_target(config: &Config, asserts: bool) -> bool { +pub(crate) fn is_ci_llvm_available_for_target( + host_target: &TargetSelection, + asserts: bool, +) -> bool { // This is currently all tier 1 targets and tier 2 targets with host tools // (since others may not have CI artifacts) // https://doc.rust-lang.org/rustc/platform-support.html#tier-1 @@ -235,8 +238,8 @@ pub(crate) fn is_ci_llvm_available_for_target(config: &Config, asserts: bool) -> ("x86_64-unknown-netbsd", false), ]; - if !supported_platforms.contains(&(&*config.host_target.triple, asserts)) - && (asserts || !supported_platforms.contains(&(&*config.host_target.triple, true))) + if !supported_platforms.contains(&(&*host_target.triple, asserts)) + && (asserts || !supported_platforms.contains(&(&*host_target.triple, true))) { return false; } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 32c3ef53e12..2f933baa4a4 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.ensure(crate::core::build_steps::doc::Rustc::for_stage( + builder, builder.top_stage, self.target, - builder, )); builder @@ -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, )); @@ -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)); } } diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 39f46bf43af..757b9277ec6 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -502,7 +502,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 4c7766e58c1..32d191c4265 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -742,6 +742,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 <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 0 <host> -> LldWrapper 1 <host> + "); + }); + } + + #[test] fn build_library_no_explicit_stage() { let ctx = TestCtx::new(); insta::assert_snapshot!( @@ -939,7 +954,7 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 <host> -> std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] "); } @@ -1008,19 +1023,36 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 1 <host> + [doc] rustc 1 <host> -> standalone 2 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 <host> -> error-index 2 <host> [doc] rustc 1 <host> -> error-index 2 <host> - [build] rustc 2 <host> -> std 2 <host> + [doc] nomicon (book) <host> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustdoc (book) <host> + [doc] rust-by-example (book) <host> [build] rustc 0 <host> -> LintDocs 1 <host> + [doc] rustc (book) <host> + [doc] cargo (book) <host> + [doc] clippy (book) <host> + [doc] embedded-book (book) <host> + [doc] edition-guide (book) <host> + [doc] style-guide (book) <host> + [doc] rustc 1 <host> -> releases 2 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> crates=[] + [doc] rustc 2 <host> -> std 2 <host> crates=[] [dist] mingw <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> @@ -1046,25 +1078,42 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 0 <host> -> LldWrapper 1 <host> [build] rustc 0 <host> -> WasmComponentLd 1 <host> [build] rustc 0 <host> -> LlvmBitcodeLinker 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 1 <host> + [doc] rustc 1 <host> -> standalone 2 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustc 1 <host> -> LldWrapper 2 <host> [build] rustc 1 <host> -> WasmComponentLd 2 <host> [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 <host> -> error-index 2 <host> [doc] rustc 1 <host> -> error-index 2 <host> - [build] rustc 2 <host> -> std 2 <host> + [doc] nomicon (book) <host> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustdoc (book) <host> + [doc] rust-by-example (book) <host> [build] rustc 0 <host> -> LintDocs 1 <host> + [doc] rustc (book) <host> + [doc] cargo (book) <host> + [doc] clippy (book) <host> + [doc] embedded-book (book) <host> + [doc] edition-guide (book) <host> + [doc] style-guide (book) <host> + [doc] rustc 1 <host> -> releases 2 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> crates=[] + [doc] rustc 2 <host> -> std 2 <host> crates=[] [dist] mingw <host> [build] rustc 1 <host> -> rust-analyzer-proc-macro-srv 2 <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> @@ -1093,22 +1142,56 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> + [doc] unstable-book (book) <target1> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 1 <host> + [build] rustc 1 <host> -> std 1 <target1> + [doc] book (book) <target1> + [doc] book/first-edition (book) <target1> + [doc] book/second-edition (book) <target1> + [doc] book/2018-edition (book) <target1> + [doc] rustc 1 <host> -> standalone 2 <host> + [doc] rustc 1 <host> -> standalone 2 <target1> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] - [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 <host> -> error-index 2 <host> [doc] rustc 1 <host> -> error-index 2 <host> - [build] rustc 2 <host> -> std 2 <host> + [doc] nomicon (book) <host> + [doc] nomicon (book) <target1> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustc 1 <host> -> reference (book) 2 <target1> + [doc] rustdoc (book) <host> + [doc] rustdoc (book) <target1> + [doc] rust-by-example (book) <host> + [doc] rust-by-example (book) <target1> [build] rustc 0 <host> -> LintDocs 1 <host> + [doc] rustc (book) <host> + [doc] cargo (book) <host> + [doc] cargo (book) <target1> + [doc] clippy (book) <host> + [doc] clippy (book) <target1> + [doc] embedded-book (book) <host> + [doc] embedded-book (book) <target1> + [doc] edition-guide (book) <host> + [doc] edition-guide (book) <target1> + [doc] style-guide (book) <host> + [doc] style-guide (book) <target1> + [doc] rustc 1 <host> -> releases 2 <host> + [doc] rustc 1 <host> -> releases 2 <target1> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [dist] docs <target1> - [doc] std 2 <host> crates=[] - [doc] std 2 <target1> crates=[] + [doc] rustc 2 <host> -> std 2 <host> crates=[] + [doc] rustc 2 <host> -> std 2 <target1> crates=[] [dist] mingw <host> [dist] mingw <target1> [build] rustc 0 <host> -> GenerateCopyright 1 <host> @@ -1132,12 +1215,19 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 1 <host> + [doc] rustc 1 <host> -> standalone 2 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 <host> -> error-index 2 <host> [doc] rustc 1 <host> -> error-index 2 <host> [build] llvm <target1> @@ -1145,12 +1235,22 @@ mod snapshot { [build] rustc 1 <host> -> rustc 2 <target1> [build] rustc 1 <host> -> error-index 2 <target1> [doc] rustc 1 <host> -> error-index 2 <target1> - [build] rustc 2 <host> -> std 2 <host> + [doc] nomicon (book) <host> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustdoc (book) <host> + [doc] rust-by-example (book) <host> [build] rustc 0 <host> -> LintDocs 1 <host> - [build] rustc 2 <host> -> std 2 <target1> + [doc] rustc (book) <host> + [doc] rustc (book) <target1> + [doc] cargo (book) <host> + [doc] clippy (book) <host> + [doc] embedded-book (book) <host> + [doc] edition-guide (book) <host> + [doc] style-guide (book) <host> + [doc] rustc 1 <host> -> releases 2 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> crates=[] + [doc] rustc 2 <host> -> std 2 <host> crates=[] [dist] mingw <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> @@ -1173,28 +1273,61 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> + [doc] unstable-book (book) <target1> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 1 <host> + [build] rustc 1 <host> -> std 1 <target1> + [doc] book (book) <target1> + [doc] book/first-edition (book) <target1> + [doc] book/second-edition (book) <target1> + [doc] book/2018-edition (book) <target1> + [doc] rustc 1 <host> -> standalone 2 <host> + [doc] rustc 1 <host> -> standalone 2 <target1> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] - [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 <host> -> error-index 2 <host> [doc] rustc 1 <host> -> error-index 2 <host> [build] llvm <target1> - [build] rustc 1 <host> -> std 1 <target1> [build] rustc 1 <host> -> rustc 2 <target1> [build] rustc 1 <host> -> error-index 2 <target1> [doc] rustc 1 <host> -> error-index 2 <target1> - [build] rustc 2 <host> -> std 2 <host> + [doc] nomicon (book) <host> + [doc] nomicon (book) <target1> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustc 1 <host> -> reference (book) 2 <target1> + [doc] rustdoc (book) <host> + [doc] rustdoc (book) <target1> + [doc] rust-by-example (book) <host> + [doc] rust-by-example (book) <target1> [build] rustc 0 <host> -> LintDocs 1 <host> - [build] rustc 2 <host> -> std 2 <target1> + [doc] rustc (book) <host> + [doc] rustc (book) <target1> + [doc] cargo (book) <host> + [doc] cargo (book) <target1> + [doc] clippy (book) <host> + [doc] clippy (book) <target1> + [doc] embedded-book (book) <host> + [doc] embedded-book (book) <target1> + [doc] edition-guide (book) <host> + [doc] edition-guide (book) <target1> + [doc] style-guide (book) <host> + [doc] style-guide (book) <target1> + [doc] rustc 1 <host> -> releases 2 <host> + [doc] rustc 1 <host> -> releases 2 <target1> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [dist] docs <target1> - [doc] std 2 <host> crates=[] - [doc] std 2 <target1> crates=[] + [doc] rustc 2 <host> -> std 2 <host> crates=[] + [doc] rustc 2 <host> -> std 2 <target1> crates=[] [dist] mingw <host> [dist] mingw <target1> [build] rustc 0 <host> -> GenerateCopyright 1 <host> @@ -1219,16 +1352,33 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <target1> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <target1> + [doc] book (book) <target1> + [doc] book/first-edition (book) <target1> + [doc] book/second-edition (book) <target1> + [doc] book/2018-edition (book) <target1> + [build] rustdoc 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] rustc 1 <host> -> standalone 2 <target1> [build] rustc 1 <host> -> rustc 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] - [build] rustc 2 <host> -> std 2 <host> + [doc] rustc 2 <host> -> std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] nomicon (book) <target1> + [doc] rustc 1 <host> -> reference (book) 2 <target1> + [doc] rustdoc (book) <target1> + [doc] rust-by-example (book) <target1> + [doc] cargo (book) <target1> + [doc] clippy (book) <target1> + [doc] embedded-book (book) <target1> + [doc] edition-guide (book) <target1> + [doc] style-guide (book) <target1> + [doc] rustc 1 <host> -> releases 2 <target1> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <target1> - [doc] std 2 <target1> crates=[] + [doc] rustc 2 <host> -> std 2 <target1> crates=[] [dist] mingw <target1> [build] rustc 2 <host> -> std 2 <target1> [dist] rustc 2 <host> -> std 2 <target1> @@ -1249,26 +1399,42 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <target1> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 0 <host> -> WasmComponentLd 1 <host> + [build] rustc 1 <host> -> std 1 <target1> + [doc] book (book) <target1> + [doc] book/first-edition (book) <target1> + [doc] book/second-edition (book) <target1> + [doc] book/2018-edition (book) <target1> + [build] rustdoc 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] rustc 1 <host> -> standalone 2 <target1> [build] rustc 1 <host> -> rustc 2 <host> [build] rustc 1 <host> -> WasmComponentLd 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] llvm <target1> - [build] rustc 1 <host> -> std 1 <target1> [build] rustc 1 <host> -> rustc 2 <target1> [build] rustc 1 <host> -> WasmComponentLd 2 <target1> [build] rustc 1 <host> -> error-index 2 <target1> [doc] rustc 1 <host> -> error-index 2 <target1> - [build] rustc 2 <host> -> std 2 <host> - [build] rustc 2 <host> -> std 2 <target1> + [doc] nomicon (book) <target1> + [doc] rustc 1 <host> -> reference (book) 2 <target1> + [doc] rustdoc (book) <target1> + [doc] rust-by-example (book) <target1> [build] rustc 0 <host> -> LintDocs 1 <host> + [doc] rustc (book) <target1> + [doc] cargo (book) <target1> + [doc] clippy (book) <target1> + [doc] embedded-book (book) <target1> + [doc] edition-guide (book) <target1> + [doc] style-guide (book) <target1> + [doc] rustc 1 <host> -> releases 2 <target1> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <target1> - [doc] std 2 <target1> crates=[] + [doc] rustc 2 <host> -> std 2 <target1> crates=[] [dist] mingw <target1> [build] rustdoc 2 <target1> [build] rustc 1 <host> -> rust-analyzer-proc-macro-srv 2 <target1> @@ -1285,6 +1451,7 @@ mod snapshot { [build] rustc 1 <host> -> miri 2 <target1> [build] rustc 1 <host> -> cargo-miri 2 <target1> [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <target1> + [doc] rustc 2 <target1> -> std 2 <target1> crates=[] "); } @@ -1300,21 +1467,38 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 0 <host> -> rustc_codegen_cranelift 1 <host> [build] rustc 1 <host> -> std 1 <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 1 <host> + [doc] rustc 1 <host> -> standalone 2 <host> [build] rustc 1 <host> -> rustc 2 <host> [build] rustc 1 <host> -> rustc_codegen_cranelift 2 <host> [build] rustdoc 2 <host> - [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 2 <host> -> std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 <host> -> error-index 2 <host> [doc] rustc 1 <host> -> error-index 2 <host> - [build] rustc 2 <host> -> std 2 <host> + [doc] nomicon (book) <host> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustdoc (book) <host> + [doc] rust-by-example (book) <host> [build] rustc 0 <host> -> LintDocs 1 <host> + [doc] rustc (book) <host> + [doc] cargo (book) <host> + [doc] clippy (book) <host> + [doc] embedded-book (book) <host> + [doc] edition-guide (book) <host> + [doc] style-guide (book) <host> + [doc] rustc 1 <host> -> releases 2 <host> [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> - [doc] std 2 <host> crates=[] + [doc] rustc 2 <host> -> std 2 <host> crates=[] [dist] mingw <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> @@ -1693,14 +1877,32 @@ mod snapshot { .render_steps(), @r" [build] rustc 0 <host> -> UnstableBookGen 1 <host> [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] unstable-book (book) <host> + [doc] book (book) <host> + [doc] book/first-edition (book) <host> + [doc] book/second-edition (book) <host> + [doc] book/2018-edition (book) <host> + [build] rustdoc 0 <host> + [doc] rustc 0 <host> -> standalone 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 <host> -> std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 0 <host> -> error-index 1 <host> [doc] rustc 0 <host> -> error-index 1 <host> + [doc] nomicon (book) <host> [build] rustc 1 <host> -> std 1 <host> + [doc] rustc 1 <host> -> reference (book) 2 <host> + [doc] rustdoc (book) <host> + [doc] rust-by-example (book) <host> [build] rustc 0 <host> -> LintDocs 1 <host> + [doc] rustc (book) <host> + [doc] cargo (book) <host> + [doc] clippy (book) <host> + [doc] embedded-book (book) <host> + [doc] edition-guide (book) <host> + [doc] style-guide (book) <host> + [doc] rustc 0 <host> -> releases 1 <host> "); } @@ -1714,7 +1916,7 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 <host> -> std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] "); } @@ -1728,7 +1930,7 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <host> crates=[core] + [doc] rustc 1 <host> -> std 1 <host> crates=[core] "); } @@ -1743,26 +1945,11 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <host> crates=[core] + [doc] rustc 1 <host> -> std 1 <host> crates=[core] "); } #[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 <host> - [build] rustc 0 <host> -> rustc 1 <host> - [build] rustc 0 <host> -> LldWrapper 1 <host> - "); - }); - } - - #[test] fn doc_library_no_std_target() { let ctx = TestCtx::new(); insta::assert_snapshot!( @@ -1773,7 +1960,7 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <host> crates=[alloc,core] + [doc] rustc 1 <host> -> std 1 <host> crates=[alloc,core] "); } @@ -1789,22 +1976,15 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustdoc 1 <host> - [doc] std 1 <target1> crates=[alloc,core] + [doc] rustc 1 <host> -> std 1 <target1> crates=[alloc,core] "); } #[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 <host> - [build] llvm <host> - [doc] rustc 0 <host> - "); + ctx.config("doc").path("compiler").stage(0).run(); } #[test] @@ -1815,11 +1995,9 @@ mod snapshot { .path("compiler") .stage(1) .render_steps(), @r" + [build] rustdoc 0 <host> [build] llvm <host> - [build] rustc 0 <host> -> rustc 1 <host> - [build] rustc 1 <host> -> std 1 <host> - [build] rustdoc 1 <host> - [doc] rustc 1 <host> + [doc] rustc 0 <host> -> rustc 1 <host> "); } @@ -1834,57 +2012,57 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> - [build] rustc 1 <host> -> rustc 2 <host> - [build] rustc 2 <host> -> std 2 <host> - [build] rustdoc 2 <host> - [doc] rustc 2 <host> + [build] rustdoc 1 <host> + [doc] rustc 1 <host> -> rustc 2 <host> "); } #[test] + #[should_panic] fn doc_compiletest_stage_0() { let ctx = TestCtx::new(); + ctx.config("doc").path("src/tools/compiletest").stage(0).run(); + } + + #[test] + fn doc_compiletest_stage_1() { + let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("doc") .path("src/tools/compiletest") - .stage(0) + .stage(1) .render_steps(), @r" [build] rustdoc 0 <host> - [doc] Compiletest <host> + [doc] rustc 0 <host> -> Compiletest 1 <host> "); } #[test] - fn doc_compiletest_stage_1() { + fn doc_compiletest_stage_2() { let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("doc") .path("src/tools/compiletest") - .stage(1) + .stage(2) .render_steps(), @r" - [build] llvm <host> - [build] rustc 0 <host> -> rustc 1 <host> - [build] rustc 1 <host> -> std 1 <host> - [build] rustdoc 1 <host> - [doc] Compiletest <host> + [build] rustdoc 0 <host> + [doc] rustc 0 <host> -> Compiletest 1 <host> "); } + // Reference should be auto-bumped to stage 2. #[test] - fn doc_compiletest_stage_2() { + fn doc_reference() { let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("doc") - .path("src/tools/compiletest") - .stage(2) + .path("reference") .render_steps(), @r" [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> - [build] rustc 1 <host> -> rustc 2 <host> - [build] rustc 2 <host> -> std 2 <host> - [build] rustdoc 2 <host> - [doc] Compiletest <host> + [build] rustc 0 <host> -> Rustbook 1 <host> + [doc] rustc 1 <host> -> reference (book) 2 <host> "); } } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index eb1ac8c637f..c505cacadb5 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -893,21 +893,25 @@ impl Config { let default = config.channel == "dev"; config.omit_git_hash = rust_omit_git_hash.unwrap_or(default); - config.rust_info = config.git_info(config.omit_git_hash, &config.src); + config.rust_info = git_info(&config.exec_ctx, config.omit_git_hash, &config.src); config.cargo_info = - config.git_info(config.omit_git_hash, &config.src.join("src/tools/cargo")); - config.rust_analyzer_info = - config.git_info(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer")); + git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/cargo")); + config.rust_analyzer_info = git_info( + &config.exec_ctx, + config.omit_git_hash, + &config.src.join("src/tools/rust-analyzer"), + ); config.clippy_info = - config.git_info(config.omit_git_hash, &config.src.join("src/tools/clippy")); + git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/clippy")); config.miri_info = - config.git_info(config.omit_git_hash, &config.src.join("src/tools/miri")); + git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/miri")); config.rustfmt_info = - config.git_info(config.omit_git_hash, &config.src.join("src/tools/rustfmt")); + git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/rustfmt")); config.enzyme_info = - config.git_info(config.omit_git_hash, &config.src.join("src/tools/enzyme")); - config.in_tree_llvm_info = config.git_info(false, &config.src.join("src/llvm-project")); - config.in_tree_gcc_info = config.git_info(false, &config.src.join("src/gcc")); + git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/enzyme")); + config.in_tree_llvm_info = + git_info(&config.exec_ctx, false, &config.src.join("src/llvm-project")); + config.in_tree_gcc_info = git_info(&config.exec_ctx, false, &config.src.join("src/gcc")); config.vendor = build_vendor.unwrap_or( config.rust_info.is_from_tarball() @@ -947,11 +951,18 @@ impl Config { ); } - config.download_rustc_commit = config.download_ci_rustc_commit( - rust_download_rustc, - debug_assertions_requested, - config.llvm_assertions, - ); + let dwn_ctx = DownloadContext::from(&config); + config.download_rustc_commit = + download_ci_rustc_commit(dwn_ctx, rust_download_rustc, config.llvm_assertions); + + if debug_assertions_requested { + eprintln!( + "WARN: `rust.debug-assertions = true` will prevent downloading CI rustc as alt CI \ + rustc is not currently built with debug assertions." + ); + // We need to put this later down_ci_rustc_commit. + config.download_rustc_commit = None; + } if let Some(t) = toml.target { for (triple, cfg) in t { @@ -1157,8 +1168,9 @@ impl Config { "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." ); + let dwn_ctx = DownloadContext::from(&config); let channel = - config.read_file_by_commit(Path::new("src/ci/channel"), commit).trim().to_owned(); + read_file_by_commit(dwn_ctx, Path::new("src/ci/channel"), commit).trim().to_owned(); config.channel = channel; } @@ -1193,8 +1205,9 @@ impl Config { config.llvm_enable_warnings = llvm_enable_warnings.unwrap_or(false); config.llvm_build_config = llvm_build_config.clone().unwrap_or(Default::default()); + let dwn_ctx = DownloadContext::from(&config); config.llvm_from_ci = - config.parse_download_ci_llvm(llvm_download_ci_llvm, config.llvm_assertions); + parse_download_ci_llvm(dwn_ctx, llvm_download_ci_llvm, config.llvm_assertions); if config.llvm_from_ci { let warn = |option: &str| { @@ -1256,7 +1269,8 @@ impl Config { if config.llvm_from_ci { let triple = &config.host_target.triple; - let ci_llvm_bin = config.ci_llvm_root().join("bin"); + let dwn_ctx = DownloadContext::from(&config); + let ci_llvm_bin = ci_llvm_root(dwn_ctx).join("bin"); let build_target = config .target_config .entry(config.host_target) @@ -1297,7 +1311,8 @@ impl Config { ); } - if config.lld_enabled && config.is_system_llvm(config.host_target) { + let dwn_ctx = DownloadContext::from(&config); + if config.lld_enabled && is_system_llvm(dwn_ctx, config.host_target) { panic!("Cannot enable LLD with `rust.lld = true` when using external llvm-config."); } @@ -1349,11 +1364,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); } _ => {} @@ -1432,14 +1451,8 @@ impl Config { /// Returns the content of the given file at a specific commit. pub(crate) fn read_file_by_commit(&self, file: &Path, commit: &str) -> String { - assert!( - self.rust_info.is_managed_git_subrepository(), - "`Config::read_file_by_commit` is not supported in non-git sources." - ); - - let mut git = helpers::git(Some(&self.src)); - git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); - git.run_capture_stdout(self).stdout() + let dwn_ctx = DownloadContext::from(self); + read_file_by_commit(dwn_ctx, file, commit) } /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. @@ -1510,8 +1523,8 @@ impl Config { /// The absolute path to the downloaded LLVM artifacts. pub(crate) fn ci_llvm_root(&self) -> PathBuf { - assert!(self.llvm_from_ci); - self.out.join(self.host_target).join("ci-llvm") + let dwn_ctx = DownloadContext::from(self); + ci_llvm_root(dwn_ctx) } /// Directory where the extracted `rustc-dev` component is stored. @@ -1674,261 +1687,14 @@ impl Config { ), )] pub(crate) fn update_submodule(&self, relative_path: &str) { - if self.rust_info.is_from_tarball() || !self.submodules() { - return; - } - - let absolute_path = self.src.join(relative_path); - - // NOTE: This check is required because `jj git clone` doesn't create directories for - // submodules, they are completely ignored. The code below assumes this directory exists, - // so create it here. - if !absolute_path.exists() { - t!(fs::create_dir_all(&absolute_path)); - } - - // NOTE: The check for the empty directory is here because when running x.py the first time, - // the submodule won't be checked out. Check it out now so we can build it. - if !self.git_info(false, &absolute_path).is_managed_git_subrepository() - && !helpers::dir_is_empty(&absolute_path) - { - return; - } - - // Submodule updating actually happens during in the dry run mode. We need to make sure that - // all the git commands below are actually executed, because some follow-up code - // in bootstrap might depend on the submodules being checked out. Furthermore, not all - // the command executions below work with an empty output (produced during dry run). - // Therefore, all commands below are marked with `run_in_dry_run()`, so that they also run in - // dry run mode. - let submodule_git = || { - let mut cmd = helpers::git(Some(&absolute_path)); - cmd.run_in_dry_run(); - cmd - }; - - // Determine commit checked out in submodule. - let checked_out_hash = - submodule_git().args(["rev-parse", "HEAD"]).run_capture_stdout(self).stdout(); - let checked_out_hash = checked_out_hash.trim_end(); - // Determine commit that the submodule *should* have. - let recorded = helpers::git(Some(&self.src)) - .run_in_dry_run() - .args(["ls-tree", "HEAD"]) - .arg(relative_path) - .run_capture_stdout(self) - .stdout(); - - let actual_hash = recorded - .split_whitespace() - .nth(2) - .unwrap_or_else(|| panic!("unexpected output `{recorded}`")); - - if actual_hash == checked_out_hash { - // already checked out - return; - } - - println!("Updating submodule {relative_path}"); - - helpers::git(Some(&self.src)) - .allow_failure() - .run_in_dry_run() - .args(["submodule", "-q", "sync"]) - .arg(relative_path) - .run(self); - - // Try passing `--progress` to start, then run git again without if that fails. - let update = |progress: bool| { - // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository, - // even though that has no relation to the upstream for the submodule. - let current_branch = helpers::git(Some(&self.src)) - .allow_failure() - .run_in_dry_run() - .args(["symbolic-ref", "--short", "HEAD"]) - .run_capture(self); - - let mut git = helpers::git(Some(&self.src)).allow_failure(); - git.run_in_dry_run(); - if current_branch.is_success() { - // If there is a tag named after the current branch, git will try to disambiguate by prepending `heads/` to the branch name. - // This syntax isn't accepted by `branch.{branch}`. Strip it. - let branch = current_branch.stdout(); - let branch = branch.trim(); - let branch = branch.strip_prefix("heads/").unwrap_or(branch); - git.arg("-c").arg(format!("branch.{branch}.remote=origin")); - } - git.args(["submodule", "update", "--init", "--recursive", "--depth=1"]); - if progress { - git.arg("--progress"); - } - git.arg(relative_path); - git - }; - if !update(true).allow_failure().run(self) { - update(false).allow_failure().run(self); - } - - // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). - // diff-index reports the modifications through the exit status - let has_local_modifications = - !submodule_git().allow_failure().args(["diff-index", "--quiet", "HEAD"]).run(self); - if has_local_modifications { - submodule_git().allow_failure().args(["stash", "push"]).run(self); - } - - submodule_git().allow_failure().args(["reset", "-q", "--hard"]).run(self); - submodule_git().allow_failure().args(["clean", "-qdfx"]).run(self); - - if has_local_modifications { - submodule_git().allow_failure().args(["stash", "pop"]).run(self); - } - } - - /// Returns the commit to download, or `None` if we shouldn't download CI artifacts. - pub fn download_ci_rustc_commit( - &self, - download_rustc: Option<StringOrBool>, - debug_assertions_requested: bool, - llvm_assertions: bool, - ) -> Option<String> { - if !is_download_ci_available(&self.host_target.triple, llvm_assertions) { - return None; - } - - // If `download-rustc` is not set, default to rebuilding. - let if_unchanged = match download_rustc { - // Globally default `download-rustc` to `false`, because some contributors don't use - // profiles for reasons such as: - // - They need to seamlessly switch between compiler/library work. - // - They don't want to use compiler profile because they need to override too many - // things and it's easier to not use a profile. - None | Some(StringOrBool::Bool(false)) => return None, - Some(StringOrBool::Bool(true)) => false, - Some(StringOrBool::String(s)) if s == "if-unchanged" => { - if !self.rust_info.is_managed_git_subrepository() { - println!( - "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." - ); - crate::exit!(1); - } - - true - } - Some(StringOrBool::String(other)) => { - panic!("unrecognized option for download-rustc: {other}") - } - }; - - let commit = if self.rust_info.is_managed_git_subrepository() { - // Look for a version to compare to based on the current commit. - // Only commits merged by bors will have CI artifacts. - let freshness = self.check_path_modifications(RUSTC_IF_UNCHANGED_ALLOWED_PATHS); - self.verbose(|| { - eprintln!("rustc freshness: {freshness:?}"); - }); - match freshness { - PathFreshness::LastModifiedUpstream { upstream } => upstream, - PathFreshness::HasLocalModifications { upstream } => { - if if_unchanged { - return None; - } - - if self.is_running_on_ci { - eprintln!("CI rustc commit matches with HEAD and we are in CI."); - eprintln!( - "`rustc.download-ci` functionality will be skipped as artifacts are not available." - ); - return None; - } - - upstream - } - PathFreshness::MissingUpstream => { - eprintln!("No upstream commit found"); - return None; - } - } - } else { - channel::read_commit_info_file(&self.src) - .map(|info| info.sha.trim().to_owned()) - .expect("git-commit-info is missing in the project root") - }; - - if debug_assertions_requested { - eprintln!( - "WARN: `rust.debug-assertions = true` will prevent downloading CI rustc as alt CI \ - rustc is not currently built with debug assertions." - ); - return None; - } - - Some(commit) - } - - pub fn parse_download_ci_llvm( - &self, - download_ci_llvm: Option<StringOrBool>, - asserts: bool, - ) -> bool { - // We don't ever want to use `true` on CI, as we should not - // download upstream artifacts if there are any local modifications. - let default = if self.is_running_on_ci { - StringOrBool::String("if-unchanged".to_string()) - } else { - StringOrBool::Bool(true) - }; - let download_ci_llvm = download_ci_llvm.unwrap_or(default); - - let if_unchanged = || { - if self.rust_info.is_from_tarball() { - // Git is needed for running "if-unchanged" logic. - println!("ERROR: 'if-unchanged' is only compatible with Git managed sources."); - crate::exit!(1); - } - - // Fetching the LLVM submodule is unnecessary for self-tests. - #[cfg(not(test))] - self.update_submodule("src/llvm-project"); - - // Check for untracked changes in `src/llvm-project` and other important places. - let has_changes = self.has_changes_from_upstream(LLVM_INVALIDATION_PATHS); - - // Return false if there are untracked changes, otherwise check if CI LLVM is available. - if has_changes { false } else { llvm::is_ci_llvm_available_for_target(self, asserts) } - }; - - match download_ci_llvm { - StringOrBool::Bool(b) => { - if !b && self.download_rustc_commit.is_some() { - panic!( - "`llvm.download-ci-llvm` cannot be set to `false` if `rust.download-rustc` is set to `true` or `if-unchanged`." - ); - } - - if b && self.is_running_on_ci { - // On CI, we must always rebuild LLVM if there were any modifications to it - panic!( - "`llvm.download-ci-llvm` cannot be set to `true` on CI. Use `if-unchanged` instead." - ); - } - - // If download-ci-llvm=true we also want to check that CI llvm is available - b && llvm::is_ci_llvm_available_for_target(self, asserts) - } - StringOrBool::String(s) if s == "if-unchanged" => if_unchanged(), - StringOrBool::String(other) => { - panic!("unrecognized option for download-ci-llvm: {other:?}") - } - } + let dwn_ctx = DownloadContext::from(self); + update_submodule(dwn_ctx, relative_path); } /// Returns true if any of the `paths` have been modified locally. pub fn has_changes_from_upstream(&self, paths: &[&'static str]) -> bool { - match self.check_path_modifications(paths) { - PathFreshness::LastModifiedUpstream { .. } => false, - PathFreshness::HasLocalModifications { .. } | PathFreshness::MissingUpstream => true, - } + let dwn_ctx = DownloadContext::from(self); + has_changes_from_upstream(dwn_ctx, paths) } /// Checks whether any of the given paths have been modified w.r.t. upstream. @@ -1949,10 +1715,6 @@ impl Config { .clone() } - pub fn ci_env(&self) -> CiEnv { - if self.is_running_on_ci { CiEnv::GitHubActions } else { CiEnv::None } - } - pub fn sanitizers_enabled(&self, target: TargetSelection) -> bool { self.target_config.get(&target).and_then(|t| t.sanitizers).unwrap_or(self.sanitizers) } @@ -2041,15 +1803,8 @@ impl Config { /// /// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set. pub fn is_system_llvm(&self, target: TargetSelection) -> bool { - match self.target_config.get(&target) { - Some(Target { llvm_config: Some(_), .. }) => { - let ci_llvm = self.llvm_from_ci && self.is_host_target(target); - !ci_llvm - } - // We're building from the in-tree src/llvm-project sources. - Some(Target { llvm_config: None, .. }) => false, - None => false, - } + let dwn_ctx = DownloadContext::from(self); + is_system_llvm(dwn_ctx, target) } /// Returns `true` if this is our custom, patched, version of LLVM. @@ -2340,3 +2095,365 @@ pub fn check_stage0_version( )); } } + +pub fn download_ci_rustc_commit<'a>( + dwn_ctx: impl AsRef<DownloadContext<'a>>, + download_rustc: Option<StringOrBool>, + llvm_assertions: bool, +) -> Option<String> { + let dwn_ctx = dwn_ctx.as_ref(); + + if !is_download_ci_available(&dwn_ctx.host_target.triple, llvm_assertions) { + return None; + } + + // If `download-rustc` is not set, default to rebuilding. + let if_unchanged = match download_rustc { + // Globally default `download-rustc` to `false`, because some contributors don't use + // profiles for reasons such as: + // - They need to seamlessly switch between compiler/library work. + // - They don't want to use compiler profile because they need to override too many + // things and it's easier to not use a profile. + None | Some(StringOrBool::Bool(false)) => return None, + Some(StringOrBool::Bool(true)) => false, + Some(StringOrBool::String(s)) if s == "if-unchanged" => { + if !dwn_ctx.rust_info.is_managed_git_subrepository() { + println!( + "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." + ); + crate::exit!(1); + } + + true + } + Some(StringOrBool::String(other)) => { + panic!("unrecognized option for download-rustc: {other}") + } + }; + + let commit = if dwn_ctx.rust_info.is_managed_git_subrepository() { + // Look for a version to compare to based on the current commit. + // Only commits merged by bors will have CI artifacts. + let freshness = check_path_modifications_(dwn_ctx, RUSTC_IF_UNCHANGED_ALLOWED_PATHS); + dwn_ctx.exec_ctx.verbose(|| { + eprintln!("rustc freshness: {freshness:?}"); + }); + match freshness { + PathFreshness::LastModifiedUpstream { upstream } => upstream, + PathFreshness::HasLocalModifications { upstream } => { + if if_unchanged { + return None; + } + + if dwn_ctx.is_running_on_ci { + eprintln!("CI rustc commit matches with HEAD and we are in CI."); + eprintln!( + "`rustc.download-ci` functionality will be skipped as artifacts are not available." + ); + return None; + } + + upstream + } + PathFreshness::MissingUpstream => { + eprintln!("No upstream commit found"); + return None; + } + } + } else { + channel::read_commit_info_file(dwn_ctx.src) + .map(|info| info.sha.trim().to_owned()) + .expect("git-commit-info is missing in the project root") + }; + + Some(commit) +} + +pub fn check_path_modifications_<'a>( + dwn_ctx: impl AsRef<DownloadContext<'a>>, + paths: &[&'static str], +) -> PathFreshness { + let dwn_ctx = dwn_ctx.as_ref(); + // Checking path modifications through git can be relatively expensive (>100ms). + // We do not assume that the sources would change during bootstrap's execution, + // so we can cache the results here. + // Note that we do not use a static variable for the cache, because it would cause problems + // in tests that create separate `Config` instsances. + dwn_ctx + .path_modification_cache + .lock() + .unwrap() + .entry(paths.to_vec()) + .or_insert_with(|| { + check_path_modifications( + dwn_ctx.src, + &git_config(dwn_ctx.stage0_metadata), + paths, + CiEnv::current(), + ) + .unwrap() + }) + .clone() +} + +pub fn git_config(stage0_metadata: &build_helper::stage0_parser::Stage0) -> GitConfig<'_> { + GitConfig { + nightly_branch: &stage0_metadata.config.nightly_branch, + git_merge_commit_email: &stage0_metadata.config.git_merge_commit_email, + } +} + +pub fn parse_download_ci_llvm<'a>( + dwn_ctx: impl AsRef<DownloadContext<'a>>, + download_ci_llvm: Option<StringOrBool>, + asserts: bool, +) -> bool { + let dwn_ctx = dwn_ctx.as_ref(); + + // We don't ever want to use `true` on CI, as we should not + // download upstream artifacts if there are any local modifications. + let default = if dwn_ctx.is_running_on_ci { + StringOrBool::String("if-unchanged".to_string()) + } else { + StringOrBool::Bool(true) + }; + let download_ci_llvm = download_ci_llvm.unwrap_or(default); + + let if_unchanged = || { + if dwn_ctx.rust_info.is_from_tarball() { + // Git is needed for running "if-unchanged" logic. + println!("ERROR: 'if-unchanged' is only compatible with Git managed sources."); + crate::exit!(1); + } + + // Fetching the LLVM submodule is unnecessary for self-tests. + #[cfg(not(test))] + update_submodule(dwn_ctx, "src/llvm-project"); + + // Check for untracked changes in `src/llvm-project` and other important places. + let has_changes = has_changes_from_upstream(dwn_ctx, LLVM_INVALIDATION_PATHS); + + // Return false if there are untracked changes, otherwise check if CI LLVM is available. + if has_changes { + false + } else { + llvm::is_ci_llvm_available_for_target(&dwn_ctx.host_target, asserts) + } + }; + + match download_ci_llvm { + StringOrBool::Bool(b) => { + if !b && dwn_ctx.download_rustc_commit.is_some() { + panic!( + "`llvm.download-ci-llvm` cannot be set to `false` if `rust.download-rustc` is set to `true` or `if-unchanged`." + ); + } + + if b && dwn_ctx.is_running_on_ci { + // On CI, we must always rebuild LLVM if there were any modifications to it + panic!( + "`llvm.download-ci-llvm` cannot be set to `true` on CI. Use `if-unchanged` instead." + ); + } + + // If download-ci-llvm=true we also want to check that CI llvm is available + b && llvm::is_ci_llvm_available_for_target(&dwn_ctx.host_target, asserts) + } + StringOrBool::String(s) if s == "if-unchanged" => if_unchanged(), + StringOrBool::String(other) => { + panic!("unrecognized option for download-ci-llvm: {other:?}") + } + } +} + +pub fn has_changes_from_upstream<'a>( + dwn_ctx: impl AsRef<DownloadContext<'a>>, + paths: &[&'static str], +) -> bool { + let dwn_ctx = dwn_ctx.as_ref(); + match check_path_modifications_(dwn_ctx, paths) { + PathFreshness::LastModifiedUpstream { .. } => false, + PathFreshness::HasLocalModifications { .. } | PathFreshness::MissingUpstream => true, + } +} + +#[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Config::update_submodule", + skip_all, + fields(relative_path = ?relative_path), + ), +)] +pub(crate) fn update_submodule<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>, relative_path: &str) { + let dwn_ctx = dwn_ctx.as_ref(); + if dwn_ctx.rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, dwn_ctx.rust_info) { + return; + } + + let absolute_path = dwn_ctx.src.join(relative_path); + + // NOTE: This check is required because `jj git clone` doesn't create directories for + // submodules, they are completely ignored. The code below assumes this directory exists, + // so create it here. + if !absolute_path.exists() { + t!(fs::create_dir_all(&absolute_path)); + } + + // NOTE: The check for the empty directory is here because when running x.py the first time, + // the submodule won't be checked out. Check it out now so we can build it. + if !git_info(dwn_ctx.exec_ctx, false, &absolute_path).is_managed_git_subrepository() + && !helpers::dir_is_empty(&absolute_path) + { + return; + } + + // Submodule updating actually happens during in the dry run mode. We need to make sure that + // all the git commands below are actually executed, because some follow-up code + // in bootstrap might depend on the submodules being checked out. Furthermore, not all + // the command executions below work with an empty output (produced during dry run). + // Therefore, all commands below are marked with `run_in_dry_run()`, so that they also run in + // dry run mode. + let submodule_git = || { + let mut cmd = helpers::git(Some(&absolute_path)); + cmd.run_in_dry_run(); + cmd + }; + + // Determine commit checked out in submodule. + let checked_out_hash = + submodule_git().args(["rev-parse", "HEAD"]).run_capture_stdout(dwn_ctx.exec_ctx).stdout(); + let checked_out_hash = checked_out_hash.trim_end(); + // Determine commit that the submodule *should* have. + let recorded = helpers::git(Some(dwn_ctx.src)) + .run_in_dry_run() + .args(["ls-tree", "HEAD"]) + .arg(relative_path) + .run_capture_stdout(dwn_ctx.exec_ctx) + .stdout(); + + let actual_hash = recorded + .split_whitespace() + .nth(2) + .unwrap_or_else(|| panic!("unexpected output `{recorded}`")); + + if actual_hash == checked_out_hash { + // already checked out + return; + } + + println!("Updating submodule {relative_path}"); + + helpers::git(Some(dwn_ctx.src)) + .allow_failure() + .run_in_dry_run() + .args(["submodule", "-q", "sync"]) + .arg(relative_path) + .run(dwn_ctx.exec_ctx); + + // Try passing `--progress` to start, then run git again without if that fails. + let update = |progress: bool| { + // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository, + // even though that has no relation to the upstream for the submodule. + let current_branch = helpers::git(Some(dwn_ctx.src)) + .allow_failure() + .run_in_dry_run() + .args(["symbolic-ref", "--short", "HEAD"]) + .run_capture(dwn_ctx.exec_ctx); + + let mut git = helpers::git(Some(dwn_ctx.src)).allow_failure(); + git.run_in_dry_run(); + if current_branch.is_success() { + // If there is a tag named after the current branch, git will try to disambiguate by prepending `heads/` to the branch name. + // This syntax isn't accepted by `branch.{branch}`. Strip it. + let branch = current_branch.stdout(); + let branch = branch.trim(); + let branch = branch.strip_prefix("heads/").unwrap_or(branch); + git.arg("-c").arg(format!("branch.{branch}.remote=origin")); + } + git.args(["submodule", "update", "--init", "--recursive", "--depth=1"]); + if progress { + git.arg("--progress"); + } + git.arg(relative_path); + git + }; + if !update(true).allow_failure().run(dwn_ctx.exec_ctx) { + update(false).allow_failure().run(dwn_ctx.exec_ctx); + } + + // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). + // diff-index reports the modifications through the exit status + let has_local_modifications = !submodule_git() + .allow_failure() + .args(["diff-index", "--quiet", "HEAD"]) + .run(dwn_ctx.exec_ctx); + if has_local_modifications { + submodule_git().allow_failure().args(["stash", "push"]).run(dwn_ctx.exec_ctx); + } + + submodule_git().allow_failure().args(["reset", "-q", "--hard"]).run(dwn_ctx.exec_ctx); + submodule_git().allow_failure().args(["clean", "-qdfx"]).run(dwn_ctx.exec_ctx); + + if has_local_modifications { + submodule_git().allow_failure().args(["stash", "pop"]).run(dwn_ctx.exec_ctx); + } +} + +pub fn git_info(exec_ctx: &ExecutionContext, omit_git_hash: bool, dir: &Path) -> GitInfo { + GitInfo::new(omit_git_hash, dir, exec_ctx) +} + +pub fn submodules_(submodules: &Option<bool>, rust_info: &channel::GitInfo) -> bool { + // If not specified in config, the default is to only manage + // submodules if we're currently inside a git repository. + submodules.unwrap_or(rust_info.is_managed_git_subrepository()) +} + +/// Returns `true` if this is an external version of LLVM not managed by bootstrap. +/// In particular, we expect llvm sources to be available when this is false. +/// +/// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set. +pub fn is_system_llvm<'a>( + dwn_ctx: impl AsRef<DownloadContext<'a>>, + target: TargetSelection, +) -> bool { + let dwn_ctx = dwn_ctx.as_ref(); + match dwn_ctx.target_config.get(&target) { + Some(Target { llvm_config: Some(_), .. }) => { + let ci_llvm = dwn_ctx.llvm_from_ci && is_host_target(&dwn_ctx.host_target, &target); + !ci_llvm + } + // We're building from the in-tree src/llvm-project sources. + Some(Target { llvm_config: None, .. }) => false, + None => false, + } +} + +pub fn is_host_target(host_target: &TargetSelection, target: &TargetSelection) -> bool { + host_target == target +} + +pub(crate) fn ci_llvm_root<'a>(dwn_ctx: impl AsRef<DownloadContext<'a>>) -> PathBuf { + let dwn_ctx = dwn_ctx.as_ref(); + assert!(dwn_ctx.llvm_from_ci); + dwn_ctx.out.join(dwn_ctx.host_target).join("ci-llvm") +} + +/// Returns the content of the given file at a specific commit. +pub(crate) fn read_file_by_commit<'a>( + dwn_ctx: impl AsRef<DownloadContext<'a>>, + file: &Path, + commit: &str, +) -> String { + let dwn_ctx = dwn_ctx.as_ref(); + assert!( + dwn_ctx.rust_info.is_managed_git_subrepository(), + "`Config::read_file_by_commit` is not supported in non-git sources." + ); + + let mut git = helpers::git(Some(dwn_ctx.src)); + git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); + git.run_capture_stdout(dwn_ctx.exec_ctx).stdout() +} diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 7ec6c62a07d..5ded44cef14 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -1,14 +1,17 @@ +use std::collections::HashMap; use std::env; use std::ffi::OsString; use std::fs::{self, File}; use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Write}; use std::path::{Path, PathBuf}; -use std::sync::OnceLock; +use std::sync::{Arc, Mutex, OnceLock}; +use build_helper::git::PathFreshness; use xz2::bufread::XzDecoder; -use crate::core::config::{BUILDER_CONFIG_FILENAME, TargetSelection}; +use crate::core::config::{BUILDER_CONFIG_FILENAME, Target, TargetSelection}; use crate::utils::build_stamp::BuildStamp; +use crate::utils::channel; use crate::utils::exec::{ExecutionContext, command}; use crate::utils::helpers::{exe, hex_encode, move_file}; use crate::{Config, t}; @@ -398,14 +401,21 @@ impl Config { /// Only should be used for pre config initialization downloads. pub(crate) struct DownloadContext<'a> { - host_target: TargetSelection, - out: &'a Path, - patch_binaries_for_nix: Option<bool>, - exec_ctx: &'a ExecutionContext, - stage0_metadata: &'a build_helper::stage0_parser::Stage0, - llvm_assertions: bool, - bootstrap_cache_path: &'a Option<PathBuf>, - is_running_on_ci: bool, + pub path_modification_cache: Arc<Mutex<HashMap<Vec<&'static str>, PathFreshness>>>, + pub src: &'a Path, + pub rust_info: &'a channel::GitInfo, + pub submodules: &'a Option<bool>, + pub download_rustc_commit: &'a Option<String>, + pub host_target: TargetSelection, + pub llvm_from_ci: bool, + pub target_config: &'a HashMap<TargetSelection, Target>, + pub out: &'a Path, + pub patch_binaries_for_nix: Option<bool>, + pub exec_ctx: &'a ExecutionContext, + pub stage0_metadata: &'a build_helper::stage0_parser::Stage0, + pub llvm_assertions: bool, + pub bootstrap_cache_path: &'a Option<PathBuf>, + pub is_running_on_ci: bool, } impl<'a> AsRef<DownloadContext<'a>> for DownloadContext<'a> { @@ -417,7 +427,14 @@ impl<'a> AsRef<DownloadContext<'a>> for DownloadContext<'a> { impl<'a> From<&'a Config> for DownloadContext<'a> { fn from(value: &'a Config) -> Self { DownloadContext { + path_modification_cache: value.path_modification_cache.clone(), + src: &value.src, host_target: value.host_target, + rust_info: &value.rust_info, + download_rustc_commit: &value.download_rustc_commit, + submodules: &value.submodules, + llvm_from_ci: value.llvm_from_ci, + target_config: &value.target_config, out: &value.out, patch_binaries_for_nix: value.patch_binaries_for_nix, exec_ctx: &value.exec_ctx, diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index d3331b81587..091956e7e5f 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+.", + }, ]; 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 f82e19bcbb4..1a219125593 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 --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 --stage 1 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 diff --git a/src/ci/run.sh b/src/ci/run.sh index f58a067041d..c9d81f1ff51 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -205,6 +205,9 @@ if [ "$ENABLE_GCC_CODEGEN" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-new-symbol-mangling" fi +# If bootstrap fails, we want to see its backtrace +export RUST_BACKTRACE=1 + # Print the date from the local machine and the date from an external source to # check for clock drifts. An HTTP URL is used instead of HTTPS since on Azure # Pipelines it happened that the certificates were marked as expired. diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 9c6141d8222..7317c62df7f 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::Msrv; -use clippy_utils::qualify_min_const_fn::is_stable_const_fn; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::implements_trait; use clippy_utils::visitors::for_each_expr_without_closures; @@ -21,7 +20,7 @@ pub(super) fn check<'tcx>( expr: &'tcx hir::Expr<'_>, assignee: &'tcx hir::Expr<'_>, e: &'tcx hir::Expr<'_>, - msrv: Msrv, + _msrv: Msrv, ) { if let hir::ExprKind::Binary(op, l, r) = &e.kind { let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| { @@ -45,10 +44,8 @@ pub(super) fn check<'tcx>( } // Skip if the trait is not stable in const contexts - if is_in_const_context(cx) - && let Some(binop_id) = cx.tcx.associated_item_def_ids(trait_id).first() - && !is_stable_const_fn(cx, *binop_id, msrv) - { + // FIXME: reintroduce a better check after this is merged back into Clippy + if is_in_const_context(cx) { return; } |
