From 1bb9b151c9f9b5116254827f04add845aff33408 Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Mon, 11 Aug 2025 00:57:29 +0000 Subject: refactor: Hard-code `char::is_control` According to https://www.unicode.org/policies/stability_policy.html#Property_Value, the set of codepoints in `Cc` will never change. So we can hard-code the patterns to match against instead of using a table. --- src/tools/unicode-table-generator/src/main.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index 6cdb82a87bd..38e5e8bbdb9 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -92,7 +92,6 @@ static PROPERTIES: &[&str] = &[ "Case_Ignorable", "Grapheme_Extend", "White_Space", - "Cc", "N", ]; -- cgit 1.4.1-3-g733a5 From aa0887b223d3af4570f2a6f31c9d85d792a7b4de Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 25 Jul 2025 15:12:44 +0200 Subject: accept integer `target-pointer-width` in compiletest --- src/tools/compiletest/src/common.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 7fc80c1edb1..645ed474b60 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -6,7 +6,6 @@ use std::sync::OnceLock; use build_helper::git::GitConfig; use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; -use serde::de::{Deserialize, Deserializer, Error as _}; use crate::executor::{ColorConfig, OutputFormat}; use crate::fatal; @@ -1080,7 +1079,7 @@ pub struct TargetCfg { pub(crate) abi: String, #[serde(rename = "target-family", default)] pub(crate) families: Vec, - #[serde(rename = "target-pointer-width", deserialize_with = "serde_parse_u32")] + #[serde(rename = "target-pointer-width")] pub(crate) pointer_width: u32, #[serde(rename = "target-endian", default)] endian: Endian, @@ -1190,11 +1189,6 @@ fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap>(deserializer: D) -> Result { - let string = String::deserialize(deserializer)?; - string.parse().map_err(D::Error::custom) -} - #[derive(Debug, Clone)] pub struct TestPaths { pub file: Utf8PathBuf, // e.g., compile-test/foo/bar/baz.rs -- cgit 1.4.1-3-g733a5 From 6a3187af13e59beb00f6eaff8c4c9da19b382d36 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 31 Jul 2025 19:03:22 +0200 Subject: fix target-pointer-width in tests --- compiler/rustc_codegen_gcc/target_specs/m68k-unknown-linux-gnu.json | 2 +- compiler/rustc_target/src/tests.rs | 2 +- library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json | 2 +- src/tools/miri/tests/x86_64-unknown-kernel.json | 2 +- tests/ui/check-cfg/my-awesome-platform.json | 2 +- tests/ui/codegen/mismatched-data-layout.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/compiler/rustc_codegen_gcc/target_specs/m68k-unknown-linux-gnu.json b/compiler/rustc_codegen_gcc/target_specs/m68k-unknown-linux-gnu.json index 95ea06106fb..b13b640a7c7 100644 --- a/compiler/rustc_codegen_gcc/target_specs/m68k-unknown-linux-gnu.json +++ b/compiler/rustc_codegen_gcc/target_specs/m68k-unknown-linux-gnu.json @@ -22,5 +22,5 @@ "unix" ], "target-mcount": "_mcount", - "target-pointer-width": "32" + "target-pointer-width": 32 } diff --git a/compiler/rustc_target/src/tests.rs b/compiler/rustc_target/src/tests.rs index ee847a84007..a2692ea6be5 100644 --- a/compiler/rustc_target/src/tests.rs +++ b/compiler/rustc_target/src/tests.rs @@ -7,7 +7,7 @@ fn report_unused_fields() { "arch": "powerpc64", "data-layout": "e-m:e-i64:64-n32:64", "llvm-target": "powerpc64le-elf", - "target-pointer-width": "64", + "target-pointer-width": 64, "code-mode": "foo" } "#; diff --git a/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json b/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json index 81273d44e49..6369bbe2547 100644 --- a/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json +++ b/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json @@ -19,5 +19,5 @@ }, "panic-strategy": "abort", "relocation-model": "static", - "target-pointer-width": "32" + "target-pointer-width": 32 } diff --git a/src/tools/miri/tests/x86_64-unknown-kernel.json b/src/tools/miri/tests/x86_64-unknown-kernel.json index a5eaceb4f68..0f8032c39d5 100644 --- a/src/tools/miri/tests/x86_64-unknown-kernel.json +++ b/src/tools/miri/tests/x86_64-unknown-kernel.json @@ -1,7 +1,7 @@ { "llvm-target": "x86_64-unknown-none", "target-endian": "little", - "target-pointer-width": "64", + "target-pointer-width": 64, "target-c-int-width": 32, "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", "arch": "x86_64", diff --git a/tests/ui/check-cfg/my-awesome-platform.json b/tests/ui/check-cfg/my-awesome-platform.json index 4c16d06c7b7..3a1f6b1a54c 100644 --- a/tests/ui/check-cfg/my-awesome-platform.json +++ b/tests/ui/check-cfg/my-awesome-platform.json @@ -3,7 +3,7 @@ "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", "arch": "x86_64", "target-endian": "little", - "target-pointer-width": "64", + "target-pointer-width": 64, "os": "ericos", "linker-flavor": "ld.lld", "linker": "rust-lld", diff --git a/tests/ui/codegen/mismatched-data-layout.json b/tests/ui/codegen/mismatched-data-layout.json index f8c510c1863..a1b222010ab 100644 --- a/tests/ui/codegen/mismatched-data-layout.json +++ b/tests/ui/codegen/mismatched-data-layout.json @@ -3,7 +3,7 @@ "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", "arch": "x86_64", "target-endian": "little", - "target-pointer-width": "64", + "target-pointer-width": 64, "os": "none", "linker-flavor": "ld.lld", "linker": "rust-lld", -- cgit 1.4.1-3-g733a5 From 2d8cb59784711f503170011461c23385042a974d Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 21 Aug 2025 20:18:00 +0200 Subject: CI: rfl: support Rust >= 1.91.0 target spec To unblock the Rust CI in PR [1], use a temporary commit from Rust for Linux that supports the future target spec format. Link: https://github.com/rust-lang/rust/pull/144443 [1] Signed-off-by: Miguel Ojeda --- src/ci/docker/scripts/rfl-build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index 8acc5040a2f..70ff5d0d2c7 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,7 +2,8 @@ set -euo pipefail -LINUX_VERSION=v6.16-rc1 +# https://github.com/rust-lang/rust/pull/144443 +LINUX_VERSION=7770d51bce622b13195b2d3c85407282fc9c27e5 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt -- cgit 1.4.1-3-g733a5 From 60734115899e5658c63965edecab8ec4df570767 Mon Sep 17 00:00:00 2001 From: no92 Date: Thu, 28 Aug 2025 23:15:54 +0200 Subject: bootstrap: bump cc-rs to 1.2.28 --- src/bootstrap/Cargo.lock | 4 ++-- src/bootstrap/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index be29e77e572..1535d087033 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.23" +version = "1.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c" dependencies = [ "shlex", ] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index cd5a60187e5..c7175584465 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -32,7 +32,7 @@ test = false # Most of the time updating these dependencies requires modifications to the # bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565); # otherwise, some targets will fail. That's why these dependencies are explicitly pinned. -cc = "=1.2.23" +cc = "=1.2.28" cmake = "=0.1.54" build_helper = { path = "../build_helper" } -- cgit 1.4.1-3-g733a5 From 6577a0ffdbe20f0c50537c34aa3214e026fe1904 Mon Sep 17 00:00:00 2001 From: no92 Date: Thu, 28 Aug 2025 23:15:55 +0200 Subject: compiler: Add `{x86_64,aarch64,riscv64gc}-unknown-managarm-mlibc` targets Co-authored-by: Dennis Bonke --- .../rustc_target/src/spec/base/managarm_mlibc.rs | 17 +++++++++++++++ compiler/rustc_target/src/spec/base/mod.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 4 ++++ .../spec/targets/aarch64_unknown_managarm_mlibc.rs | 22 ++++++++++++++++++++ .../targets/riscv64gc_unknown_managarm_mlibc.rs | 24 ++++++++++++++++++++++ .../spec/targets/x86_64_unknown_managarm_mlibc.rs | 24 ++++++++++++++++++++++ src/tools/build-manifest/src/main.rs | 3 +++ tests/assembly-llvm/targets/targets-elf.rs | 9 ++++++++ .../auxiliary/used_pre_main_constructor.rs | 1 + tests/ui/check-cfg/cfg-crate-features.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 6 +++--- 11 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 compiler/rustc_target/src/spec/base/managarm_mlibc.rs create mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs create mode 100644 compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs (limited to 'src') diff --git a/compiler/rustc_target/src/spec/base/managarm_mlibc.rs b/compiler/rustc_target/src/spec/base/managarm_mlibc.rs new file mode 100644 index 00000000000..da3856b212d --- /dev/null +++ b/compiler/rustc_target/src/spec/base/managarm_mlibc.rs @@ -0,0 +1,17 @@ +use crate::spec::{RelroLevel, TargetOptions, cvs}; + +pub(crate) fn opts() -> TargetOptions { + TargetOptions { + os: "managarm".into(), + env: "mlibc".into(), + dynamic_linking: true, + executables: true, + families: cvs!["unix"], + has_rpath: true, + position_independent_executables: true, + relro_level: RelroLevel::Full, + has_thread_local: true, + crt_static_respected: true, + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index b368d93f007..be15da7329d 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -20,6 +20,7 @@ pub(crate) mod linux_ohos; pub(crate) mod linux_uclibc; pub(crate) mod linux_wasm; pub(crate) mod lynxos178; +pub(crate) mod managarm_mlibc; pub(crate) mod msvc; pub(crate) mod netbsd; pub(crate) mod nto_qnx; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c53d92bee9d..e97a9b9c776 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2032,6 +2032,10 @@ supported_targets! { ("i586-unknown-redox", i586_unknown_redox), ("x86_64-unknown-redox", x86_64_unknown_redox), + ("x86_64-unknown-managarm-mlibc", x86_64_unknown_managarm_mlibc), + ("aarch64-unknown-managarm-mlibc", aarch64_unknown_managarm_mlibc), + ("riscv64gc-unknown-managarm-mlibc", riscv64gc_unknown_managarm_mlibc), + ("i386-apple-ios", i386_apple_ios), ("x86_64-apple-ios", x86_64_apple_ios), ("aarch64-apple-ios", aarch64_apple_ios), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs new file mode 100644 index 00000000000..1fa9d7131c5 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_managarm_mlibc.rs @@ -0,0 +1,22 @@ +use crate::spec::{StackProbeType, Target, base}; + +pub(crate) fn target() -> Target { + let mut base = base::managarm_mlibc::opts(); + base.max_atomic_width = Some(128); + base.stack_probes = StackProbeType::Inline; + base.features = "+v8a".into(); + + Target { + llvm_target: "aarch64-unknown-managarm-mlibc".into(), + metadata: crate::spec::TargetMetadata { + description: Some("managarm/aarch64".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 64, + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + arch: "aarch64".into(), + options: base + } +} diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs new file mode 100644 index 00000000000..abf28310634 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_managarm_mlibc.rs @@ -0,0 +1,24 @@ +use crate::spec::{CodeModel, Target, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "riscv64-unknown-managarm-mlibc".into(), + metadata: crate::spec::TargetMetadata { + description: Some("managarm/riscv64".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 64, + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), + arch: "riscv64".into(), + options: TargetOptions { + code_model: Some(CodeModel::Medium), + cpu: "generic-rv64".into(), + features: "+m,+a,+f,+d,+c".into(), + llvm_abiname: "lp64d".into(), + max_atomic_width: Some(64), + ..base::managarm_mlibc::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs new file mode 100644 index 00000000000..359e38cb800 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_managarm_mlibc.rs @@ -0,0 +1,24 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; + +pub(crate) fn target() -> Target { + let mut base = base::managarm_mlibc::opts(); + base.cpu = "x86-64".into(); + base.max_atomic_width = Some(64); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.stack_probes = StackProbeType::Inline; + + Target { + llvm_target: "x86_64-unknown-managarm-mlibc".into(), + metadata: crate::spec::TargetMetadata { + description: Some("managarm/amd64".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 64, + data_layout: + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + options: base, + } +} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8f88ab10bf7..2890d26d3f4 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -71,6 +71,7 @@ static TARGETS: &[&str] = &[ "aarch64-unknown-none-softfloat", "aarch64-unknown-redox", "aarch64-unknown-uefi", + "aarch64-unknown-managarm-mlibc", "amdgcn-amd-amdhsa", "arm64e-apple-darwin", "arm64e-apple-ios", @@ -155,6 +156,7 @@ static TARGETS: &[&str] = &[ "riscv64gc-unknown-none-elf", "riscv64gc-unknown-linux-gnu", "riscv64gc-unknown-linux-musl", + "riscv64gc-unknown-managarm-mlibc", "s390x-unknown-linux-gnu", "sparc64-unknown-linux-gnu", "sparcv9-sun-solaris", @@ -194,6 +196,7 @@ static TARGETS: &[&str] = &[ "x86_64-unknown-redox", "x86_64-unknown-hermit", "x86_64-unknown-uefi", + "x86_64-unknown-managarm-mlibc", ]; /// This allows the manifest to contain rust-docs for hosts that don't build diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index c935a75a690..b5c116cdfef 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -52,6 +52,9 @@ //@ revisions: aarch64_unknown_linux_ohos //@ [aarch64_unknown_linux_ohos] compile-flags: --target aarch64-unknown-linux-ohos //@ [aarch64_unknown_linux_ohos] needs-llvm-components: aarch64 +//@ revisions: aarch64_unknown_managarm_mlibc +//@ [aarch64_unknown_managarm_mlibc] compile-flags: --target aarch64-unknown-managarm-mlibc +//@ [aarch64_unknown_managarm_mlibc] needs-llvm-components: aarch64 //@ revisions: aarch64_unknown_netbsd //@ [aarch64_unknown_netbsd] compile-flags: --target aarch64-unknown-netbsd //@ [aarch64_unknown_netbsd] needs-llvm-components: aarch64 @@ -490,6 +493,9 @@ //@ revisions: riscv64gc_unknown_linux_musl //@ [riscv64gc_unknown_linux_musl] compile-flags: --target riscv64gc-unknown-linux-musl //@ [riscv64gc_unknown_linux_musl] needs-llvm-components: riscv +//@ revisions: riscv64gc_unknown_managarm_mlibc +//@ [riscv64gc_unknown_managarm_mlibc] compile-flags: --target riscv64gc-unknown-managarm-mlibc +//@ [riscv64gc_unknown_managarm_mlibc] needs-llvm-components: riscv //@ revisions: riscv64gc_unknown_netbsd //@ [riscv64gc_unknown_netbsd] compile-flags: --target riscv64gc-unknown-netbsd //@ [riscv64gc_unknown_netbsd] needs-llvm-components: riscv @@ -649,6 +655,9 @@ //@ revisions: x86_64_unknown_linux_none //@ [x86_64_unknown_linux_none] compile-flags: --target x86_64-unknown-linux-none //@ [x86_64_unknown_linux_none] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_managarm_mlibc +//@ [x86_64_unknown_managarm_mlibc] compile-flags: --target x86_64-unknown-managarm-mlibc +//@ [x86_64_unknown_managarm_mlibc] needs-llvm-components: x86 //@ revisions: x86_64_unknown_netbsd //@ [x86_64_unknown_netbsd] compile-flags: --target x86_64-unknown-netbsd //@ [x86_64_unknown_netbsd] needs-llvm-components: x86 diff --git a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs index 8ea7a9cb4b5..f93a2aae5a1 100644 --- a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs +++ b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs @@ -20,6 +20,7 @@ target_os = "nto", target_os = "openbsd", target_os = "fuchsia", + target_os = "managarm", ), link_section = ".init_array" )] diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr index d69a24f3f64..6b2e628e12e 100644 --- a/tests/ui/check-cfg/cfg-crate-features.stderr +++ b/tests/ui/check-cfg/cfg-crate-features.stderr @@ -24,7 +24,7 @@ warning: unexpected `cfg` condition value: `does_not_exist` LL | #![cfg(not(target(os = "does_not_exist")))] | ^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, and `uefi` and 10 more + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, and `tvos` and 11 more = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 18e038a442e..6490fc63fd7 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` + = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 28 warnings emitted -- cgit 1.4.1-3-g733a5 From 8434d3810b938b2236180a67886cf79ee5d9efe4 Mon Sep 17 00:00:00 2001 From: no92 Date: Thu, 28 Aug 2025 23:15:55 +0200 Subject: doc: Add `*-unknown-managarm-mlibc` documentation --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 3 ++ src/doc/rustc/src/platform-support/managarm.md | 53 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/doc/rustc/src/platform-support/managarm.md (limited to 'src') diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index e0d637a2a67..8e378e53e51 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -116,6 +116,7 @@ - [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) - [\*-unknown-hermit](platform-support/hermit.md) - [\*-unknown-freebsd](platform-support/freebsd.md) + - [\*-unknown-managarm-mlibc](platform-support/managarm.md) - [\*-unknown-netbsd\*](platform-support/netbsd.md) - [\*-unknown-openbsd](platform-support/openbsd.md) - [\*-unknown-redox](platform-support/redox.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index edfc2db7d6f..dfe193e6e8a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -258,6 +258,7 @@ target | std | host | notes [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit [`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) +[`aarch64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | ARM64 Managarm [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | @@ -388,6 +389,7 @@ target | std | host | notes `riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia [`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit +[`riscv64gc-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | RISC-V Managarm [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD [`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 @@ -428,6 +430,7 @@ target | std | host | notes [`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd `x86_64-unknown-l4re-uclibc` | ? | | [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc +[`x86_64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | x86_64 Managarm [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD [`x86_64-unknown-trusty`](platform-support/trusty.md) | ✓ | | `x86_64-uwp-windows-gnu` | ✓ | | diff --git a/src/doc/rustc/src/platform-support/managarm.md b/src/doc/rustc/src/platform-support/managarm.md new file mode 100644 index 00000000000..aa2d5a7ac23 --- /dev/null +++ b/src/doc/rustc/src/platform-support/managarm.md @@ -0,0 +1,53 @@ +# `*-unknown-managarm-mlibc` + +**Tier: 3** + +## Target Maintainers + +- [@no92](https://github.com/no92) +- [@64](https://github.com/64) +- [@Dennisbonke](https://github.com/Dennisbonke) + +## Requirements + +This target is cross-compiled. There is currently no support for `std` yet. It generates binaries in the ELF format. Currently, we support the `x86_64`, `aarch64` and `riscv64gc` architectures. The examples below `$ARCH` should be substituted for one of the supported architectures. + +## Building the target + +Managarm has upstream support in LLVM since the release of 21.1.0. + +Set up your `bootstrap.toml` like this: + +```toml +change-id = 142379 + +[llvm] +targets = "X86;AArch64;RISCV" +download-ci-llvm = false + +[build] +target = ["$ARCH-unknown-managarm-mlibc", "x86_64-unknown-linux-gnu"] + +[target.x86_64-unknown-linux-gnu] +llvm-config = "/path/to/your/llvm/bin/llvm-config" + +[target.$ARCH-unknown-managarm-mlibc] +llvm-config = "/path/to/your/llvm/bin/llvm-config" +``` + +## Building Rust programs + +Build a `$ARCH-managarm-gcc` using our [gcc fork](https://github.com/managarm/gcc). + +```toml +[build] +rustc = "/path/to/the/rust-prefix/bin/rustc" +target = "$ARCH-unknown-managarm-mlibc" + +[target.$ARCH-unknown-managarm-mlibc] +linker = "/path/to/the/managarm-gcc/bin/$ARCH-managarm-gcc" +``` + +## Testing + +This target does not support running the Rust testsuite yet. -- cgit 1.4.1-3-g733a5 From a3ef8178d29b2cb61a3033e83fbba2b2a66d6716 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Fri, 8 Aug 2025 11:53:25 +0200 Subject: Add snapshot test for `tier-check` --- src/bootstrap/src/core/builder/tests.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b079117c5a7..d16ab530c1e 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2116,6 +2116,19 @@ mod snapshot { "); } + #[test] + fn test_tier_check() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .path("tier-check") + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + "); + } + #[test] fn doc_all() { let ctx = TestCtx::new(); -- cgit 1.4.1-3-g733a5 From 65b7cde18ca7c331e323ace7b5f4f78b8cca4c33 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Fri, 8 Aug 2025 11:55:07 +0200 Subject: Fixup `x test tier-check` --- src/bootstrap/src/core/build_steps/test.rs | 40 +++++++++++++++--------------- src/bootstrap/src/core/builder/tests.rs | 2 +- src/bootstrap/src/lib.rs | 19 ++++++++++++++ 3 files changed, 40 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 26b4aaa8b5b..a8002cd293b 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3248,9 +3248,15 @@ impl Step for Bootstrap { } } +fn get_compiler_to_test(builder: &Builder<'_>, target: TargetSelection) -> Compiler { + builder.compiler(builder.top_stage, target) +} + +/// Tests the Platform Support page in the rustc book. +/// `test_compiler` is used to query the actual targets that are checked. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TierCheck { - pub compiler: Compiler, + test_compiler: Compiler, } impl Step for TierCheck { @@ -3263,42 +3269,36 @@ impl Step for TierCheck { } fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler_for( - run.builder.top_stage, - run.builder.build.host_target, - run.target, - ); - run.builder.ensure(TierCheck { compiler }); + run.builder + .ensure(TierCheck { test_compiler: get_compiler_to_test(run.builder, run.target) }); } - /// Tests the Platform Support page in the rustc book. fn run(self, builder: &Builder<'_>) { - builder.std(self.compiler, self.compiler.host); + let tool_build_compiler = builder.compiler(0, builder.host_target); + let mut cargo = tool::prepare_tool_cargo( builder, - self.compiler, - Mode::ToolStd, - self.compiler.host, + tool_build_compiler, + Mode::ToolBootstrap, + tool_build_compiler.host, Kind::Run, "src/tools/tier-check", SourceType::InTree, &[], ); cargo.arg(builder.src.join("src/doc/rustc/src/platform-support.md")); - cargo.arg(builder.rustc(self.compiler)); + cargo.arg(builder.rustc(self.test_compiler)); if builder.is_verbose() { cargo.arg("--verbose"); } - let _guard = builder.msg( - Kind::Test, - "platform support check", - None, - self.compiler, - self.compiler.host, - ); + let _guard = builder.msg_test("platform support check", self.test_compiler); BootstrapCommand::from(cargo).delay_failure().run(builder); } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("tier-check", self.test_compiler.host)) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index d16ab530c1e..e5fff459a23 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2125,7 +2125,7 @@ mod snapshot { .render_steps(), @r" [build] llvm [build] rustc 0 -> rustc 1 - [build] rustc 1 -> std 1 + [test] rustc 0 -> tier-check 1 "); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index b8ee83b20e4..1beeb16b44f 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1159,6 +1159,25 @@ impl Build { self.group(&msg) } + /// Return a `Group` guard for a [`Step`] that tests `what` with the given `stage` and `target` + /// (determined by `host_and_stage`). + /// Use this instead of [`Builder::msg`] when there is no clear `build_compiler` to be + /// determined. + /// + /// [`Step`]: crate::core::builder::Step + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] + fn msg_test( + &self, + what: impl Display, + host_and_stage: impl Into, + ) -> Option { + let HostAndStage { host, stage } = host_and_stage.into(); + let action = Kind::Test.description(); + let msg = format!("{action} stage{stage} {what} ({host})"); + self.group(&msg) + } + /// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`. /// /// [`Step`]: crate::core::builder::Step -- cgit 1.4.1-3-g733a5 From 542e750e5159ea85e0b7b9bf1cb743011cf286cf Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 13:46:21 +0200 Subject: Forbid running tests on stage 0 unless `build.compiletest-allow-stage0` is enabled --- src/bootstrap/src/core/config/config.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a8eb563015f..450f325f1a9 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1002,12 +1002,18 @@ impl Config { (0, Subcommand::Install) => { check_stage0("install"); } + (0, Subcommand::Test { .. }) if build_compiletest_allow_stage0 != Some(true) => { + eprintln!( + "ERROR: cannot test anything on stage 0. Use at least stage 1. If you want to run compiletest with an external stage0 toolchain, enable `build.compiletest-allow-stage0`." + ); + exit!(1); + } _ => {} } if flags_compile_time_deps && !matches!(flags_cmd, Subcommand::Check { .. }) { eprintln!( - "WARNING: Can't use --compile-time-deps with any subcommand other than check." + "ERROR: Can't use --compile-time-deps with any subcommand other than check." ); exit!(1); } -- cgit 1.4.1-3-g733a5 From f0d15d33247c9f63671e0801f700ec6f2f73d7ed Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 13:58:12 +0200 Subject: Add snapshot test for `x test` --- src/bootstrap/src/core/builder/tests.rs | 72 ++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index e5fff459a23..851e043a1c8 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2037,6 +2037,76 @@ mod snapshot { .render_steps(), @"[check] rustc 0 -> RunMakeSupport 1 "); } + #[test] + fn test_all() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .render_steps(), @r" + [build] rustc 0 -> Tidy 1 + [test] tidy <> + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 0 -> Compiletest 1 + [test] Ui + [test] Crashes + [build] rustc 0 -> CoverageDump 1 + [build] rustc 1 -> std 1 + [test] CodegenLlvm + [test] CodegenUnits + [test] AssemblyLlvm + [test] Incremental + [test] Debuginfo + [test] UiFullDeps + [build] rustdoc 1 + [test] Rustdoc + [test] CoverageRunRustdoc + [test] Pretty + [build] rustc 1 -> std 1 + [test] CrateLibrustc + [build] rustc 1 -> rustc 2 + [build] rustdoc 0 + [build] rustc 0 -> UnstableBookGen 1 + [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [doc] rustc 0 -> standalone 1 + [doc] rustc 1 -> std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [build] rustc 0 -> error-index 1 + [doc] rustc 0 -> error-index 1 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) + [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 0 -> releases 1 + [build] rustc 0 -> Linkchecker 1 + [test] tier-check + [doc] rustc (book) + [doc] rustc 1 -> std 1 crates=[] + [build] rustc 0 -> RustdocTheme 1 + [test] RustdocUi + [build] rustc 0 -> JsonDocCk 1 + [build] rustc 0 -> JsonDocLint 1 + [test] RustdocJson + [doc] rustc 0 -> rustc 1 + [build] rustc 0 -> HtmlChecker 1 + [build] rustc 0 -> RunMakeSupport 1 + [build] rustc 1 -> cargo 2 + [test] RunMake + "); + } + #[test] fn test_exclude() { let ctx = TestCtx::new(); @@ -2125,7 +2195,7 @@ mod snapshot { .render_steps(), @r" [build] llvm [build] rustc 0 -> rustc 1 - [test] rustc 0 -> tier-check 1 + [test] tier-check "); } -- cgit 1.4.1-3-g733a5 From a347f8dcb6bb783e8b509284ad3bd18ff639da37 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 14:12:16 +0200 Subject: Fix staging of `TestFloatParse` The tool wasn't useful for anything, it was only built as a part of the test, but we can just use `cargo test` and `cargo run` in the test, no need to (pre-)build the tool itself. --- src/bootstrap/src/core/build_steps/check.rs | 6 +- src/bootstrap/src/core/build_steps/test.rs | 92 ++++++++++++++++++----------- src/bootstrap/src/core/build_steps/tool.rs | 37 +----------- 3 files changed, 61 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index bebae893ee7..a604e7c0585 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -8,8 +8,8 @@ use crate::core::build_steps::compile::{ }; use crate::core::build_steps::tool; use crate::core::build_steps::tool::{ - COMPILETEST_ALLOW_FEATURES, SourceType, ToolTargetBuildMode, get_tool_target_compiler, - prepare_tool_cargo, + COMPILETEST_ALLOW_FEATURES, SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, ToolTargetBuildMode, + get_tool_target_compiler, prepare_tool_cargo, }; use crate::core::builder::{ self, Alias, Builder, Cargo, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description, @@ -791,7 +791,7 @@ tool_check_step!(MiroptTestTools { tool_check_step!(TestFloatParse { path: "src/tools/test-float-parse", mode: |_builder| Mode::ToolStd, - allow_features: tool::TestFloatParse::ALLOW_FEATURES + allow_features: TEST_FLOAT_PARSE_ALLOW_FEATURES }); tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump", diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a8002cd293b..8d07874bbc5 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -18,8 +18,8 @@ use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::run::get_completion_paths; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; use crate::core::build_steps::tool::{ - self, COMPILETEST_ALLOW_FEATURES, RustcPrivateCompilers, SourceType, Tool, ToolTargetBuildMode, - get_tool_target_compiler, + self, COMPILETEST_ALLOW_FEATURES, RustcPrivateCompilers, SourceType, + TEST_FLOAT_PARSE_ALLOW_FEATURES, Tool, ToolTargetBuildMode, get_tool_target_compiler, }; use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, dist, llvm}; @@ -2886,6 +2886,7 @@ impl Step for Crate { } } +/// Run cargo tests for the rustdoc crate. /// Rustdoc is special in various ways, which is why this step is different from `Crate`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateRustdoc { @@ -2981,7 +2982,8 @@ impl Step for CrateRustdoc { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateRustdocJsonTypes { - host: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl Step for CrateRustdocJsonTypes { @@ -2996,23 +2998,22 @@ impl Step for CrateRustdocJsonTypes { fn make_run(run: RunConfig<'_>) { let builder = run.builder; - builder.ensure(CrateRustdocJsonTypes { host: run.target }); + builder.ensure(CrateRustdocJsonTypes { + build_compiler: get_tool_target_compiler( + builder, + ToolTargetBuildMode::Build(run.target), + ), + target: run.target, + }); } fn run(self, builder: &Builder<'_>) { - let target = self.host; - - // Use the previous stage compiler to reuse the artifacts that are - // created when running compiletest for tests/rustdoc. If this used - // `compiler`, then it would cause rustdoc to be built *again*, which - // isn't really necessary. - let compiler = builder.compiler_for(builder.top_stage, target, target); - builder.ensure(compile::Rustc::new(compiler, target)); + let target = self.target; let cargo = tool::prepare_tool_cargo( builder, - compiler, - Mode::ToolRustc, + self.build_compiler, + Mode::ToolTarget, target, builder.kind, "src/rustdoc-json-types", @@ -3021,7 +3022,7 @@ impl Step for CrateRustdocJsonTypes { ); // FIXME: this looks very wrong, libtest doesn't accept `-C` arguments and the quotes are fishy. - let libtest_args = if self.host.contains("musl") { + let libtest_args = if target.contains("musl") { ["'-Ctarget-feature=-crt-static'"].as_slice() } else { &[] @@ -3705,14 +3706,35 @@ impl Step for CodegenGCC { } } +/// Get a build compiler that can be used to test the standard library (i.e. its stage will +/// correspond to the stage that we want to test). +fn get_test_build_compiler_for_std(builder: &Builder<'_>) -> Compiler { + if builder.top_stage == 0 { + eprintln!( + "ERROR: cannot run tests on stage 0. `build.compiletest-allow-stage0` only works for compiletest test suites." + ); + exit!(1); + } + builder.compiler(builder.top_stage, builder.host_target) +} + /// Test step that does two things: /// - Runs `cargo test` for the `src/tools/test-float-parse` tool. /// - Invokes the `test-float-parse` tool to test the standard library's /// float parsing routines. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TestFloatParse { - path: PathBuf, - host: TargetSelection, + /// The build compiler which will build and run unit tests of `test-float-parse`, and which will + /// build the `test-float-parse` tool itself. + /// + /// Note that the staging is a bit funny here, because this step essentially tests std, but it + /// also needs to build the tool. So if we test stage1 std, we build: + /// 1) stage1 rustc + /// 2) Use that to build stage1 libstd + /// 3) Use that to build and run *stage2* test-float-parse + build_compiler: Compiler, + /// Target for which we build std and test that std. + target: TargetSelection, } impl Step for TestFloatParse { @@ -3725,47 +3747,47 @@ impl Step for TestFloatParse { } fn make_run(run: RunConfig<'_>) { - for path in run.paths { - let path = path.assert_single_path().path.clone(); - run.builder.ensure(Self { path, host: run.target }); - } + run.builder.ensure(Self { + build_compiler: get_test_build_compiler_for_std(run.builder), + target: run.target, + }); } fn run(self, builder: &Builder<'_>) { - let bootstrap_host = builder.config.host_target; - let compiler = builder.compiler(builder.top_stage, bootstrap_host); - let path = self.path.to_str().unwrap(); - let crate_name = self.path.iter().next_back().unwrap().to_str().unwrap(); + let build_compiler = self.build_compiler; + let target = self.target; - builder.ensure(tool::TestFloatParse { host: self.host }); + // Build the standard library that will be tested, and a stdlib for host code + builder.std(build_compiler, target); + builder.std(build_compiler, builder.host_target); // Run any unit tests in the crate let mut cargo_test = tool::prepare_tool_cargo( builder, - compiler, + build_compiler, Mode::ToolStd, - bootstrap_host, + target, Kind::Test, - path, + "src/tools/test-float-parse", SourceType::InTree, &[], ); - cargo_test.allow_features(tool::TestFloatParse::ALLOW_FEATURES); + cargo_test.allow_features(TEST_FLOAT_PARSE_ALLOW_FEATURES); - run_cargo_test(cargo_test, &[], &[], crate_name, bootstrap_host, builder); + run_cargo_test(cargo_test, &[], &[], "test-float-parse", target, builder); // Run the actual parse tests. let mut cargo_run = tool::prepare_tool_cargo( builder, - compiler, + build_compiler, Mode::ToolStd, - bootstrap_host, + target, Kind::Run, - path, + "src/tools/test-float-parse", SourceType::InTree, &[], ); - cargo_run.allow_features(tool::TestFloatParse::ALLOW_FEATURES); + cargo_run.allow_features(TEST_FLOAT_PARSE_ALLOW_FEATURES); if !matches!(env::var("FLOAT_PARSE_TESTS_NO_SKIP_HUGE").as_deref(), Ok("1") | Ok("true")) { cargo_run.args(["--", "--skip-huge"]); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index b62c9a906b7..e15b570a5a7 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1539,42 +1539,7 @@ tool_rustc_extended!(Rustfmt { add_bins_to_sysroot: ["rustfmt"] }); -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TestFloatParse { - pub host: TargetSelection, -} - -impl TestFloatParse { - pub const ALLOW_FEATURES: &'static str = "f16,cfg_target_has_reliable_f16_f128"; -} - -impl Step for TestFloatParse { - type Output = ToolBuildResult; - const IS_HOST: bool = true; - const DEFAULT: bool = false; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/test-float-parse") - } - - fn run(self, builder: &Builder<'_>) -> ToolBuildResult { - let bootstrap_host = builder.config.host_target; - let compiler = builder.compiler(builder.top_stage, bootstrap_host); - - builder.ensure(ToolBuild { - build_compiler: compiler, - target: bootstrap_host, - tool: "test-float-parse", - mode: Mode::ToolStd, - path: "src/tools/test-float-parse", - source_type: SourceType::InTree, - extra_features: Vec::new(), - allow_features: Self::ALLOW_FEATURES, - cargo_args: Vec::new(), - artifact_kind: ToolArtifactKind::Binary, - }) - } -} +pub const TEST_FLOAT_PARSE_ALLOW_FEATURES: &'static str = "f16,cfg_target_has_reliable_f16_f128"; impl Builder<'_> { /// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for -- cgit 1.4.1-3-g733a5 From 42fb65b5a9bb1ce5e176cdced3c09ce62b37d750 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 14:34:56 +0200 Subject: Remove `compiler_for` from `test::CodegenGCC` --- src/bootstrap/src/core/build_steps/test.rs | 82 +++++++++++------------------- 1 file changed, 31 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 8d07874bbc5..f6b9b6f70ef 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3578,7 +3578,7 @@ impl Step for CodegenCranelift { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CodegenGCC { - compiler: Compiler, + compilers: RustcPrivateCompilers, target: TargetSelection, } @@ -3594,7 +3594,7 @@ impl Step for CodegenGCC { fn make_run(run: RunConfig<'_>) { let builder = run.builder; let host = run.build_triple(); - let compiler = run.builder.compiler_for(run.builder.top_stage, host, host); + let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, host); if builder.doc_tests == DocTests::Only { return; @@ -3623,68 +3623,41 @@ impl Step for CodegenGCC { return; } - builder.ensure(CodegenGCC { compiler, target: run.target }); + builder.ensure(CodegenGCC { compilers, target: run.target }); } fn run(self, builder: &Builder<'_>) { - let compiler = self.compiler; + let compilers = self.compilers; let target = self.target; let gcc = builder.ensure(Gcc { target }); builder.ensure( - compile::Std::new(compiler, target) + compile::Std::new(compilers.build_compiler(), target) .extra_rust_args(&["-Csymbol-mangling-version=v0", "-Cpanic=abort"]), ); - // If we're not doing a full bootstrap but we're testing a stage2 - // version of libstd, then what we're actually testing is the libstd - // produced in stage1. Reflect that here by updating the compiler that - // we're working with automatically. - let compiler = builder.compiler_for(compiler.stage, compiler.host, target); - - let build_cargo = || { - let mut cargo = builder::Cargo::new( - builder, - compiler, - Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works - SourceType::InTree, - target, - Kind::Run, - ); - - cargo.current_dir(&builder.src.join("compiler/rustc_codegen_gcc")); - cargo - .arg("--manifest-path") - .arg(builder.src.join("compiler/rustc_codegen_gcc/build_system/Cargo.toml")); - compile::rustc_cargo_env(builder, &mut cargo, target); - add_cg_gcc_cargo_flags(&mut cargo, &gcc); + let _msg = builder.msg_test("rustc_codegen_gcc", compilers.build_compiler()); - // Avoid incremental cache issues when changing rustc - cargo.env("CARGO_BUILD_INCREMENTAL", "false"); - cargo.rustflag("-Cpanic=abort"); - - cargo - }; - - builder.info(&format!( - "{} GCC stage{} ({} -> {})", - Kind::Test.description(), - compiler.stage, - &compiler.host, - target - )); - let _time = helpers::timeit(builder); + let mut cargo = builder::Cargo::new( + builder, + compilers.build_compiler(), + Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works + SourceType::InTree, + target, + Kind::Run, + ); - // FIXME: Uncomment the `prepare` command below once vendoring is implemented. - /* - let mut prepare_cargo = build_cargo(); - prepare_cargo.arg("--").arg("prepare"); - #[expect(deprecated)] - builder.config.try_run(&mut prepare_cargo.into()).unwrap(); - */ + cargo.current_dir(&builder.src.join("compiler/rustc_codegen_gcc")); + cargo + .arg("--manifest-path") + .arg(builder.src.join("compiler/rustc_codegen_gcc/build_system/Cargo.toml")); + compile::rustc_cargo_env(builder, &mut cargo, target); + add_cg_gcc_cargo_flags(&mut cargo, &gcc); - let mut cargo = build_cargo(); + // Avoid incremental cache issues when changing rustc + cargo.env("CARGO_BUILD_INCREMENTAL", "false"); + cargo.rustflag("-Cpanic=abort"); cargo // cg_gcc's build system ignores RUSTFLAGS. pass some flags through CG_RUSTFLAGS instead. @@ -3696,7 +3669,7 @@ impl Step for CodegenGCC { .arg("--gcc-path") .arg(gcc.libgccjit.parent().unwrap()) .arg("--out-dir") - .arg(builder.stage_out(compiler, Mode::ToolRustc).join("cg_gcc")) + .arg(builder.stage_out(compilers.build_compiler(), Mode::Codegen).join("cg_gcc")) .arg("--release") .arg("--mini-tests") .arg("--std-tests"); @@ -3704,6 +3677,13 @@ impl Step for CodegenGCC { cargo.into_cmd().run(builder); } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("rustc_codegen_gcc", self.target) + .built_by(self.compilers.build_compiler()), + ) + } } /// Get a build compiler that can be used to test the standard library (i.e. its stage will -- cgit 1.4.1-3-g733a5 From 2ca5cb8c1683ad5c8d36e4464b2cfc56537b7bc2 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 14:59:34 +0200 Subject: Remove `compiler_for` from `test::CodegenCranelift` --- src/bootstrap/src/core/build_steps/test.rs | 84 +++++++++++++----------------- 1 file changed, 35 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index f6b9b6f70ef..e53638c81bd 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3450,7 +3450,7 @@ impl Step for TestHelpers { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CodegenCranelift { - compiler: Compiler, + compilers: RustcPrivateCompilers, target: TargetSelection, } @@ -3466,7 +3466,7 @@ impl Step for CodegenCranelift { fn make_run(run: RunConfig<'_>) { let builder = run.builder; let host = run.build_triple(); - let compiler = run.builder.compiler_for(run.builder.top_stage, host, host); + let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, host); if builder.doc_tests == DocTests::Only { return; @@ -3496,71 +3496,50 @@ impl Step for CodegenCranelift { return; } - builder.ensure(CodegenCranelift { compiler, target: run.target }); + builder.ensure(CodegenCranelift { compilers, target: run.target }); } fn run(self, builder: &Builder<'_>) { - let compiler = self.compiler; - let target = self.target; - - builder.std(compiler, target); + let compilers = self.compilers; + let build_compiler = compilers.build_compiler(); - // If we're not doing a full bootstrap but we're testing a stage2 - // version of libstd, then what we're actually testing is the libstd - // produced in stage1. Reflect that here by updating the compiler that - // we're working with automatically. - let compiler = builder.compiler_for(compiler.stage, compiler.host, target); + // We need to run the cranelift tests with the compiler against cranelift links to, not with + // the build compiler. + let target_compiler = compilers.target_compiler(); + let target = self.target; - let build_cargo = || { - let mut cargo = builder::Cargo::new( - builder, - compiler, - Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works - SourceType::InTree, - target, - Kind::Run, - ); + builder.std(target_compiler, target); - cargo.current_dir(&builder.src.join("compiler/rustc_codegen_cranelift")); - cargo - .arg("--manifest-path") - .arg(builder.src.join("compiler/rustc_codegen_cranelift/build_system/Cargo.toml")); - compile::rustc_cargo_env(builder, &mut cargo, target); + let mut cargo = builder::Cargo::new( + builder, + target_compiler, + Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works + SourceType::InTree, + target, + Kind::Run, + ); - // Avoid incremental cache issues when changing rustc - cargo.env("CARGO_BUILD_INCREMENTAL", "false"); + cargo.current_dir(&builder.src.join("compiler/rustc_codegen_cranelift")); + cargo + .arg("--manifest-path") + .arg(builder.src.join("compiler/rustc_codegen_cranelift/build_system/Cargo.toml")); + compile::rustc_cargo_env(builder, &mut cargo, target); - cargo - }; + // Avoid incremental cache issues when changing rustc + cargo.env("CARGO_BUILD_INCREMENTAL", "false"); - builder.info(&format!( - "{} cranelift stage{} ({} -> {})", - Kind::Test.description(), - compiler.stage, - &compiler.host, - target - )); - let _time = helpers::timeit(builder); + let _guard = builder.msg_test("rustc_codegen_cranelift", target_compiler); // FIXME handle vendoring for source tarballs before removing the --skip-test below let download_dir = builder.out.join("cg_clif_download"); - // FIXME: Uncomment the `prepare` command below once vendoring is implemented. - /* - let mut prepare_cargo = build_cargo(); - prepare_cargo.arg("--").arg("prepare").arg("--download-dir").arg(&download_dir); - #[expect(deprecated)] - builder.config.try_run(&mut prepare_cargo.into()).unwrap(); - */ - - let mut cargo = build_cargo(); cargo .arg("--") .arg("test") .arg("--download-dir") .arg(&download_dir) .arg("--out-dir") - .arg(builder.stage_out(compiler, Mode::ToolRustc).join("cg_clif")) + .arg(builder.stage_out(build_compiler, Mode::Codegen).join("cg_clif")) .arg("--no-unstable-features") .arg("--use-backend") .arg("cranelift") @@ -3574,6 +3553,13 @@ impl Step for CodegenCranelift { cargo.into_cmd().run(builder); } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("rustc_codegen_cranelift", self.target) + .built_by(self.compilers.build_compiler()), + ) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3637,7 +3623,7 @@ impl Step for CodegenGCC { .extra_rust_args(&["-Csymbol-mangling-version=v0", "-Cpanic=abort"]), ); - let _msg = builder.msg_test("rustc_codegen_gcc", compilers.build_compiler()); + let _guard = builder.msg_test("rustc_codegen_gcc", compilers.build_compiler()); let mut cargo = builder::Cargo::new( builder, -- cgit 1.4.1-3-g733a5 From e759b97838f10b52163834315bf486d6972df3de Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 15:04:47 +0200 Subject: Refactor `test::LintDocs` --- src/bootstrap/src/core/build_steps/doc.rs | 6 +++++- src/bootstrap/src/core/build_steps/test.rs | 31 ++++++++++++++++++++++++------ src/bootstrap/src/core/builder/tests.rs | 1 + 3 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 9ef1fee1fec..678fe127879 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -791,7 +791,11 @@ fn doc_std( } /// Prepare a compiler that will be able to document something for `target` at `stage`. -fn prepare_doc_compiler(builder: &Builder<'_>, target: TargetSelection, stage: u32) -> Compiler { +pub 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); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index e53638c81bd..7c4256e9836 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -12,7 +12,7 @@ use std::{env, fs, iter}; use build_helper::exit; use crate::core::build_steps::compile::{Std, run_cargo}; -use crate::core::build_steps::doc::DocumentationFormat; +use crate::core::build_steps::doc::{DocumentationFormat, prepare_doc_compiler}; use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags}; use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::run::get_completion_paths; @@ -3304,8 +3304,8 @@ impl Step for TierCheck { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct LintDocs { - pub compiler: Compiler, - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl Step for LintDocs { @@ -3318,8 +3318,21 @@ impl Step for LintDocs { } 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 test` 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(LintDocs { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: prepare_doc_compiler( + run.builder, + run.builder.config.host_target, + stage, + ), target: run.target, }); } @@ -3327,8 +3340,14 @@ 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::validate(self.compiler, self.target)); + builder.ensure(crate::core::build_steps::doc::RustcBook::validate( + self.build_compiler, + self.target, + )); + } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("lint-docs", self.target).built_by(self.build_compiler)) } } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 851e043a1c8..ba6dfdff17a 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2093,6 +2093,7 @@ mod snapshot { [build] rustc 0 -> Linkchecker 1 [test] tier-check [doc] rustc (book) + [test] rustc 1 -> lint-docs 2 [doc] rustc 1 -> std 1 crates=[] [build] rustc 0 -> RustdocTheme 1 [test] RustdocUi -- cgit 1.4.1-3-g733a5 From 0f2fc03068ae60eed918fab13ccd89ff120dd403 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 15:21:59 +0200 Subject: Remove stage0 checking --- src/bootstrap/src/core/build_steps/test.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7c4256e9836..9b27f006392 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3691,18 +3691,6 @@ impl Step for CodegenGCC { } } -/// Get a build compiler that can be used to test the standard library (i.e. its stage will -/// correspond to the stage that we want to test). -fn get_test_build_compiler_for_std(builder: &Builder<'_>) -> Compiler { - if builder.top_stage == 0 { - eprintln!( - "ERROR: cannot run tests on stage 0. `build.compiletest-allow-stage0` only works for compiletest test suites." - ); - exit!(1); - } - builder.compiler(builder.top_stage, builder.host_target) -} - /// Test step that does two things: /// - Runs `cargo test` for the `src/tools/test-float-parse` tool. /// - Invokes the `test-float-parse` tool to test the standard library's @@ -3732,10 +3720,8 @@ impl Step for TestFloatParse { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Self { - build_compiler: get_test_build_compiler_for_std(run.builder), - target: run.target, - }); + run.builder + .ensure(Self { build_compiler: get_compiler_to_test(run.builder), target: run.target }); } fn run(self, builder: &Builder<'_>) { -- cgit 1.4.1-3-g733a5 From 1d96ef8dc09ecc0dc6c531b0ba970cd6c4dd7f5b Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 16:30:02 +0200 Subject: Small refactoring around `RemoteCopyLibs` --- src/bootstrap/src/core/build_steps/test.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 9b27f006392..46dafc79253 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1741,7 +1741,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the builder.std(compiler, target); } - builder.ensure(RemoteCopyLibs { compiler, target }); + builder.ensure(RemoteCopyLibs { build_compiler: compiler, target }); // compiletest currently has... a lot of arguments, so let's just pass all // of them! @@ -2842,7 +2842,7 @@ impl Step for Crate { // Also prepare a sysroot for the target. if !builder.config.is_host_target(target) { builder.ensure(compile::Std::new(compiler, target).force_recompile(true)); - builder.ensure(RemoteCopyLibs { compiler, target }); + builder.ensure(RemoteCopyLibs { build_compiler: compiler, target }); } // Build `cargo test` command @@ -3050,7 +3050,7 @@ impl Step for CrateRustdocJsonTypes { /// the build target (us) and the server is built for the target. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RemoteCopyLibs { - compiler: Compiler, + build_compiler: Compiler, target: TargetSelection, } @@ -3062,18 +3062,17 @@ impl Step for RemoteCopyLibs { } fn run(self, builder: &Builder<'_>) { - let compiler = self.compiler; + let build_compiler = self.build_compiler; let target = self.target; if !builder.remote_tested(target) { return; } - builder.std(compiler, target); + builder.std(build_compiler, target); builder.info(&format!("REMOTE copy libs to emulator ({target})")); - let remote_test_server = - builder.ensure(tool::RemoteTestServer { build_compiler: compiler, target }); + let remote_test_server = builder.ensure(tool::RemoteTestServer { build_compiler, target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); @@ -3088,7 +3087,7 @@ impl Step for RemoteCopyLibs { cmd.run(builder); // Push all our dylibs to the emulator - for f in t!(builder.sysroot_target_libdir(compiler, target).read_dir()) { + for f in t!(builder.sysroot_target_libdir(build_compiler, target).read_dir()) { let f = t!(f); if helpers::is_dylib(&f.path()) { command(&tool).arg("push").arg(f.path()).run(builder); @@ -3134,6 +3133,9 @@ impl Step for Distcheck { .map(|args| args.split(" ").map(|s| s.to_string()).collect::>()) .unwrap_or_default(); + // FIXME: unpack the source tarballs into a directory outside the source checkout, to + // ensure that it cannot access any local state + // Also ensure that it doesn't use download-ci-llvm command("tar") .arg("-xf") .arg(plain_src_tarball.tarball()) @@ -3720,8 +3722,10 @@ impl Step for TestFloatParse { } fn make_run(run: RunConfig<'_>) { - run.builder - .ensure(Self { build_compiler: get_compiler_to_test(run.builder), target: run.target }); + run.builder.ensure(Self { + build_compiler: get_compiler_to_test(run.builder, run.target), + target: run.target, + }); } fn run(self, builder: &Builder<'_>) { -- cgit 1.4.1-3-g733a5 From 384a044f55f72341aaf472a490f8eb21cfaea5a6 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 16:48:02 +0200 Subject: Add metadata to a bunch of steps, rename variables and add comments --- src/bootstrap/src/core/build_steps/test.rs | 119 ++++++++++++++++++++++------- src/bootstrap/src/core/builder/tests.rs | 11 +++ 2 files changed, 102 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 46dafc79253..8cc13ce7566 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -98,6 +98,13 @@ impl Step for CrateBootstrap { let crate_name = path.rsplit_once('/').unwrap().1; run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder); } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("crate-bootstrap", self.host) + .with_metadata(self.path.as_path().to_string_lossy().to_string()), + ) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -173,6 +180,10 @@ You can skip linkcheck with --skip src/tools/linkchecker" fn make_run(run: RunConfig<'_>) { run.builder.ensure(Linkcheck { host: run.target }); } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("link-check", self.host)) + } } fn check_if_tidy_is_installed(builder: &Builder<'_>) -> bool { @@ -221,6 +232,10 @@ impl Step for HtmlCheck { .arg(builder.doc_out(self.target)) .run(builder); } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("html-check", self.target)) + } } /// Builds cargo and then runs the `src/tools/cargotest` tool, which checks out @@ -399,6 +414,10 @@ impl Step for Cargo { let _time = helpers::timeit(builder); add_flags_and_try_run_tests(builder, &mut cargo); } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("cargo", self.host).built_by(self.build_compiler)) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -457,6 +476,13 @@ impl Step for RustAnalyzer { cargo.add_rustc_lib_path(builder); run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder); } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("rust-analyzer", self.compilers.target()) + .built_by(self.compilers.build_compiler()), + ) + } } /// Runs `cargo test` for rustfmt. @@ -508,6 +534,13 @@ impl Step for Rustfmt { run_cargo_test(cargo, &[], &[], "rustfmt", target, builder); } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("rustfmt", self.compilers.target()) + .built_by(self.compilers.build_compiler()), + ) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -887,6 +920,13 @@ impl Step for Clippy { crate::exit!(1); } } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("clippy", self.compilers.target()) + .built_by(self.compilers.build_compiler()), + ) + } } fn bin_path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { @@ -895,9 +935,11 @@ fn bin_path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") } +/// Run the rustdoc-themes tool to test a given compiler. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustdocTheme { - pub compiler: Compiler, + /// The compiler (more accurately, its rustdoc) that we test. + test_compiler: Compiler, } impl Step for RustdocTheme { @@ -910,9 +952,9 @@ impl Step for RustdocTheme { } fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.target); + let test_compiler = run.builder.compiler(run.builder.top_stage, run.target); - run.builder.ensure(RustdocTheme { compiler }); + run.builder.ensure(RustdocTheme { test_compiler }); } fn run(self, builder: &Builder<'_>) { @@ -920,21 +962,34 @@ impl Step for RustdocTheme { let mut cmd = builder.tool_cmd(Tool::RustdocTheme); cmd.arg(rustdoc.to_str().unwrap()) .arg(builder.src.join("src/librustdoc/html/static/css/rustdoc.css").to_str().unwrap()) - .env("RUSTC_STAGE", self.compiler.stage.to_string()) - .env("RUSTC_SYSROOT", builder.sysroot(self.compiler)) - .env("RUSTDOC_LIBDIR", builder.sysroot_target_libdir(self.compiler, self.compiler.host)) + .env("RUSTC_STAGE", self.test_compiler.stage.to_string()) + .env("RUSTC_SYSROOT", builder.sysroot(self.test_compiler)) + .env( + "RUSTDOC_LIBDIR", + builder.sysroot_target_libdir(self.test_compiler, self.test_compiler.host), + ) .env("CFG_RELEASE_CHANNEL", &builder.config.channel) - .env("RUSTDOC_REAL", builder.rustdoc_for_compiler(self.compiler)) + .env("RUSTDOC_REAL", builder.rustdoc_for_compiler(self.test_compiler)) .env("RUSTC_BOOTSTRAP", "1"); - cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); + cmd.args(linker_args(builder, self.test_compiler.host, LldThreads::No)); cmd.delay_failure().run(builder); } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test("rustdoc-theme", self.test_compiler.host) + .stage(self.test_compiler.stage), + ) + } } +/// Test rustdoc JS for the standard library. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustdocJSStd { - pub target: TargetSelection, + /// Compiler that will build the standary library. + build_compiler: Compiler, + target: TargetSelection, } impl Step for RustdocJSStd { @@ -948,7 +1003,10 @@ impl Step for RustdocJSStd { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(RustdocJSStd { target: run.target }); + run.builder.ensure(RustdocJSStd { + build_compiler: run.builder.compiler(run.builder.top_stage, run.builder.host_target), + target: run.target, + }); } fn run(self, builder: &Builder<'_>) { @@ -976,19 +1034,18 @@ impl Step for RustdocJSStd { } } builder.ensure(crate::core::build_steps::doc::Std::from_build_compiler( - builder.compiler(builder.top_stage, builder.host_target), + self.build_compiler, self.target, DocumentationFormat::Html, )); - let _guard = builder.msg( - Kind::Test, - "rustdoc-js-std", - None, - (builder.config.host_target, builder.top_stage), - self.target, - ); + let _guard = + builder.msg(Kind::Test, "rustdoc-js-std", None, self.build_compiler, self.target); command.run(builder); } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("rustdoc-js-std", self.target).stage(self.build_compiler.stage)) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -1046,10 +1103,12 @@ fn get_browser_ui_test_version(builder: &Builder<'_>, npm: &Path) -> Option) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - run.builder.ensure(RustdocGUI { target: run.target, compiler }); + let test_compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); + run.builder.ensure(RustdocGUI { test_compiler, target: run.target }); } fn run(self, builder: &Builder<'_>) { - builder.std(self.compiler, self.target); + builder.std(self.test_compiler, self.target); let mut cmd = builder.tool_cmd(Tool::RustdocGUITest); @@ -1086,7 +1145,7 @@ impl Step for RustdocGUI { build_stamp::clear_if_dirty( builder, &out_dir, - &builder.rustdoc_for_compiler(self.compiler), + &builder.rustdoc_for_compiler(self.test_compiler), ); if let Some(src) = builder.config.src.to_str() { @@ -1103,10 +1162,10 @@ impl Step for RustdocGUI { cmd.arg("--jobs").arg(builder.jobs().to_string()); - cmd.env("RUSTDOC", builder.rustdoc_for_compiler(self.compiler)) - .env("RUSTC", builder.rustc(self.compiler)); + cmd.env("RUSTDOC", builder.rustdoc_for_compiler(self.test_compiler)) + .env("RUSTC", builder.rustc(self.test_compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args(&mut cmd, builder, self.test_compiler.host, LldThreads::No); for path in &builder.paths { if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) { @@ -1133,9 +1192,13 @@ impl Step for RustdocGUI { } let _time = helpers::timeit(builder); - let _guard = builder.msg(Kind::Test, "rustdoc-gui", None, self.compiler, self.target); + let _guard = builder.msg_test("rustdoc-gui", (self.target, self.test_compiler.stage)); try_run_tests(builder, &mut cmd, true); } + + fn metadata(&self) -> Option { + Some(StepMetadata::test("rustdoc-gui", self.target).stage(self.test_compiler.stage)) + } } /// Runs `src/tools/tidy` and `cargo fmt --check` to detect various style diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index ba6dfdff17a..921c4016654 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2067,6 +2067,10 @@ mod snapshot { [test] CrateLibrustc [build] rustc 1 -> rustc 2 [build] rustdoc 0 + [test] crate-bootstrap src/tools/coverage-dump + [test] crate-bootstrap src/tools/jsondoclint + [test] crate-bootstrap src/tools/replace-version-placeholder + [test] crate-bootstrap tidyselftest [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 [doc] unstable-book (book) @@ -2091,17 +2095,22 @@ mod snapshot { [doc] style-guide (book) [doc] rustc 0 -> releases 1 [build] rustc 0 -> Linkchecker 1 + [test] link-check [test] tier-check + [test] rustc 0 -> rust-analyzer 1 [doc] rustc (book) [test] rustc 1 -> lint-docs 2 [doc] rustc 1 -> std 1 crates=[] + [test] rustc 1 -> rustdoc-js-std 2 [build] rustc 0 -> RustdocTheme 1 + [test] rustdoc-theme 1 [test] RustdocUi [build] rustc 0 -> JsonDocCk 1 [build] rustc 0 -> JsonDocLint 1 [test] RustdocJson [doc] rustc 0 -> rustc 1 [build] rustc 0 -> HtmlChecker 1 + [test] html-check [build] rustc 0 -> RunMakeSupport 1 [build] rustc 1 -> cargo 2 [test] RunMake @@ -2148,6 +2157,7 @@ mod snapshot { [build] rustc 1 -> std 1 [build] rustdoc 1 [build] rustdoc 0 + [test] rustc 0 -> cargo 1 "); } @@ -2167,6 +2177,7 @@ mod snapshot { [build] rustc 2 -> std 2 [build] rustdoc 2 [build] rustdoc 1 + [test] rustc 1 -> cargo 2 "); } -- cgit 1.4.1-3-g733a5 From 6651686949d5cb2d85be57e1563e24f31ecbd813 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 16:48:49 +0200 Subject: Move the `test!` macro closer to its usages --- src/bootstrap/src/core/build_steps/test.rs | 140 ++++++++++++++--------------- 1 file changed, 70 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 8cc13ce7566..878a649207b 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1316,76 +1316,6 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to } } -fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { - builder.out.join(host).join("test") -} - -/// Declares a test step that invokes compiletest on a particular test suite. -macro_rules! test { - ( - $( #[$attr:meta] )* // allow docstrings and attributes - $name:ident { - path: $path:expr, - mode: $mode:expr, - suite: $suite:expr, - default: $default:expr - $( , IS_HOST: $IS_HOST:expr )? // default: false - $( , compare_mode: $compare_mode:expr )? // default: None - $( , )? // optional trailing comma - } - ) => { - $( #[$attr] )* - #[derive(Debug, Clone, PartialEq, Eq, Hash)] - pub struct $name { - pub compiler: Compiler, - pub target: TargetSelection, - } - - impl Step for $name { - type Output = (); - const DEFAULT: bool = $default; - const IS_HOST: bool = (const { - #[allow(unused_assignments, unused_mut)] - let mut value = false; - $( value = $IS_HOST; )? - value - }); - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.suite_path($path) - } - - fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - - run.builder.ensure($name { compiler, target: run.target }); - } - - fn run(self, builder: &Builder<'_>) { - builder.ensure(Compiletest { - compiler: self.compiler, - target: self.target, - mode: $mode, - suite: $suite, - path: $path, - compare_mode: (const { - #[allow(unused_assignments, unused_mut)] - let mut value = None; - $( value = $compare_mode; )? - value - }), - }) - } - - fn metadata(&self) -> Option { - Some( - StepMetadata::test(stringify!($name), self.target) - ) - } - } - }; -} - /// Runs `cargo test` on the `src/tools/run-make-support` crate. /// That crate is used by run-make tests. #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -1462,6 +1392,76 @@ impl Step for CrateBuildHelper { } } +fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { + builder.out.join(host).join("test") +} + +/// Declares a test step that invokes compiletest on a particular test suite. +macro_rules! test { + ( + $( #[$attr:meta] )* // allow docstrings and attributes + $name:ident { + path: $path:expr, + mode: $mode:expr, + suite: $suite:expr, + default: $default:expr + $( , IS_HOST: $IS_HOST:expr )? // default: false + $( , compare_mode: $compare_mode:expr )? // default: None + $( , )? // optional trailing comma + } + ) => { + $( #[$attr] )* + #[derive(Debug, Clone, PartialEq, Eq, Hash)] + pub struct $name { + pub compiler: Compiler, + pub target: TargetSelection, + } + + impl Step for $name { + type Output = (); + const DEFAULT: bool = $default; + const IS_HOST: bool = (const { + #[allow(unused_assignments, unused_mut)] + let mut value = false; + $( value = $IS_HOST; )? + value + }); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.suite_path($path) + } + + fn make_run(run: RunConfig<'_>) { + let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); + + run.builder.ensure($name { compiler, target: run.target }); + } + + fn run(self, builder: &Builder<'_>) { + builder.ensure(Compiletest { + compiler: self.compiler, + target: self.target, + mode: $mode, + suite: $suite, + path: $path, + compare_mode: (const { + #[allow(unused_assignments, unused_mut)] + let mut value = None; + $( value = $compare_mode; )? + value + }), + }) + } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test(stringify!($name), self.target) + ) + } + } + }; +} + test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true }); test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true }); -- cgit 1.4.1-3-g733a5 From 0b3a13c9c05d09b93e6c82163e14108485d6c609 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 17:04:58 +0200 Subject: Fix staging for compiler/std crate tests --- src/bootstrap/src/core/build_steps/test.rs | 162 +++++++++++++++++++---------- 1 file changed, 106 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 878a649207b..ad17a557658 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -96,7 +96,7 @@ impl Step for CrateBootstrap { ); let crate_name = path.rsplit_once('/').unwrap().1; - run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder); + run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder, Mode::ToolBootstrap); } fn metadata(&self) -> Option { @@ -153,7 +153,15 @@ You can skip linkcheck with --skip src/tools/linkchecker" SourceType::InTree, &[], ); - run_cargo_test(cargo, &[], &[], "linkchecker self tests", bootstrap_host, builder); + run_cargo_test( + cargo, + &[], + &[], + "linkchecker self tests", + bootstrap_host, + builder, + Mode::ToolBootstrap, + ); if builder.doc_tests == DocTests::No { return; @@ -474,7 +482,7 @@ impl Step for RustAnalyzer { cargo.env("SKIP_SLOW_TESTS", "1"); cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder); + run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder, Mode::ToolRustc); } fn metadata(&self) -> Option { @@ -532,7 +540,7 @@ impl Step for Rustfmt { cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rustfmt", target, builder); + run_cargo_test(cargo, &[], &[], "rustfmt", target, builder, Mode::ToolRustc); } fn metadata(&self) -> Option { @@ -825,7 +833,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cargo.env("TEST_RUSTC", builder.rustc(compiler)); cargo.allow_features(COMPILETEST_ALLOW_FEATURES); - run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder); + run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder, Mode::ToolStd); } } @@ -1351,7 +1359,15 @@ impl Step for CrateRunMakeSupport { &[], ); cargo.allow_features("test"); - run_cargo_test(cargo, &[], &[], "run-make-support self test", host, builder); + run_cargo_test( + cargo, + &[], + &[], + "run-make-support self test", + host, + builder, + Mode::ToolBootstrap, + ); } } @@ -1388,7 +1404,15 @@ impl Step for CrateBuildHelper { &[], ); cargo.allow_features("test"); - run_cargo_test(cargo, &[], &[], "build_helper self test", host, builder); + run_cargo_test( + cargo, + &[], + &[], + "build_helper self test", + host, + builder, + Mode::ToolBootstrap, + ); } } @@ -2340,9 +2364,10 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} } } +/// Runs the documentation tests for a book in `src/doc` using the `rustdoc` of `test_compiler`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] struct BookTest { - compiler: Compiler, + test_compiler: Compiler, path: PathBuf, name: &'static str, is_ext_doc: bool, @@ -2357,9 +2382,6 @@ impl Step for BookTest { run.never() } - /// Runs the documentation tests for a book in `src/doc`. - /// - /// This uses the `rustdoc` that sits next to `compiler`. fn run(self, builder: &Builder<'_>) { // External docs are different from local because: // - Some books need pre-processing by mdbook before being tested. @@ -2382,13 +2404,13 @@ impl BookTest { /// This runs the equivalent of `mdbook test` (via the rustbook wrapper) /// which in turn runs `rustdoc --test` on each file in the book. fn run_ext_doc(self, builder: &Builder<'_>) { - let compiler = self.compiler; + let test_compiler = self.test_compiler; - builder.std(compiler, compiler.host); + builder.std(test_compiler, test_compiler.host); // mdbook just executes a binary named "rustdoc", so we need to update // PATH so that it points to our rustdoc. - let mut rustdoc_path = builder.rustdoc_for_compiler(compiler); + let mut rustdoc_path = builder.rustdoc_for_compiler(test_compiler); rustdoc_path.pop(); let old_path = env::var_os("PATH").unwrap_or_default(); let new_path = env::join_paths(iter::once(rustdoc_path).chain(env::split_paths(&old_path))) @@ -2411,7 +2433,7 @@ impl BookTest { let target = builder.config.host_target; let cargo = tool::prepare_tool_cargo( builder, - compiler, + test_compiler, mode, target, Kind::Build, @@ -2420,7 +2442,7 @@ impl BookTest { &[], ); - let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, target)) + let stamp = BuildStamp::new(&builder.cargo_out(test_compiler, mode, target)) .with_prefix(PathBuf::from(dep).file_name().and_then(|v| v.to_str()).unwrap()); let output_paths = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); @@ -2453,8 +2475,8 @@ impl BookTest { Kind::Test, format_args!("mdbook {}", self.path.display()), None, - compiler, - compiler.host, + test_compiler, + test_compiler.host, ); let _time = helpers::timeit(builder); let toolstate = if rustbook_cmd.delay_failure().run(builder) { @@ -2467,12 +2489,18 @@ impl BookTest { /// This runs `rustdoc --test` on all `.md` files in the path. fn run_local_doc(self, builder: &Builder<'_>) { - let compiler = self.compiler; - let host = self.compiler.host; + let test_compiler = self.test_compiler; + let host = self.test_compiler.host; - builder.std(compiler, host); + builder.std(test_compiler, host); - let _guard = builder.msg(Kind::Test, format!("book {}", self.name), None, compiler, host); + let _guard = builder.msg( + Kind::Test, + format!("book {}", self.name), + None, + (test_compiler.host, test_compiler.stage - 1), + host, + ); // Do a breadth-first traversal of the `src/doc` directory and just run // tests for all files that end in `*.md` @@ -2495,7 +2523,7 @@ impl BookTest { files.sort(); for file in files { - markdown_test(builder, compiler, &file); + markdown_test(builder, test_compiler, &file); } } } @@ -2511,7 +2539,7 @@ macro_rules! test_book { $( #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { - compiler: Compiler, + test_compiler: Compiler, } impl Step for $name { @@ -2525,7 +2553,7 @@ macro_rules! test_book { fn make_run(run: RunConfig<'_>) { run.builder.ensure($name { - compiler: run.builder.compiler(run.builder.top_stage, run.target), + test_compiler: run.builder.compiler(run.builder.top_stage, run.target), }); } @@ -2545,7 +2573,7 @@ macro_rules! test_book { )? builder.ensure(BookTest { - compiler: self.compiler, + test_compiler: self.test_compiler, path: PathBuf::from($path), name: $book_name, is_ext_doc: !$default, @@ -2665,7 +2693,8 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> /// which have their own separate test steps.) #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateLibrustc { - compiler: Compiler, + /// The compiler that will *build* rustc in test mode. + build_compiler: Compiler, target: TargetSelection, crates: Vec, } @@ -2682,18 +2711,18 @@ impl Step for CrateLibrustc { fn make_run(run: RunConfig<'_>) { let builder = run.builder; let host = run.build_triple(); - let compiler = builder.compiler_for(builder.top_stage, host, host); + let build_compiler = builder.compiler(builder.top_stage - 1, host); let crates = run.make_run_crates(Alias::Compiler); - builder.ensure(CrateLibrustc { compiler, target: run.target, crates }); + builder.ensure(CrateLibrustc { build_compiler, target: run.target, crates }); } fn run(self, builder: &Builder<'_>) { - builder.std(self.compiler, self.target); + builder.std(self.build_compiler, self.target); // To actually run the tests, delegate to a copy of the `Crate` step. builder.ensure(Crate { - compiler: self.compiler, + build_compiler: self.build_compiler, target: self.target, mode: Mode::Rustc, crates: self.crates, @@ -2715,12 +2744,14 @@ fn run_cargo_test<'a>( description: impl Into>, target: TargetSelection, builder: &Builder<'_>, + mode: impl Into>, ) -> bool { + let mode = mode.into(); let compiler = cargo.compiler(); let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder); let _time = helpers::timeit(builder); let _group = - description.into().and_then(|what| builder.msg(Kind::Test, what, None, compiler, target)); + description.into().and_then(|what| builder.msg(Kind::Test, what, mode, compiler, target)); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( @@ -2818,10 +2849,11 @@ fn prepare_cargo_test( /// library crates and compiler crates. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Crate { - pub compiler: Compiler, - pub target: TargetSelection, - pub mode: Mode, - pub crates: Vec, + /// The compiler that will *build* libstd or rustc in test mode. + build_compiler: Compiler, + target: TargetSelection, + mode: Mode, + crates: Vec, } impl Step for Crate { @@ -2835,14 +2867,14 @@ impl Step for Crate { fn make_run(run: RunConfig<'_>) { let builder = run.builder; let host = run.build_triple(); - let compiler = builder.compiler_for(builder.top_stage, host, host); + let build_compiler = builder.compiler(builder.top_stage, host); let crates = run .paths .iter() .map(|p| builder.crate_paths[&p.assert_single_path().path].clone()) .collect(); - builder.ensure(Crate { compiler, target: run.target, mode: Mode::Std, crates }); + builder.ensure(Crate { build_compiler, target: run.target, mode: Mode::Std, crates }); } /// Runs all unit tests plus documentation tests for a given crate defined @@ -2854,19 +2886,13 @@ impl Step for Crate { /// Currently this runs all tests for a DAG by passing a bunch of `-p foo` /// arguments, and those arguments are discovered from `cargo metadata`. fn run(self, builder: &Builder<'_>) { - let compiler = self.compiler; + let build_compiler = self.build_compiler; let target = self.target; let mode = self.mode; // Prepare sysroot // See [field@compile::Std::force_recompile]. - builder.ensure(Std::new(compiler, compiler.host).force_recompile(true)); - - // If we're not doing a full bootstrap but we're testing a stage2 - // version of libstd, then what we're actually testing is the libstd - // produced in stage1. Reflect that here by updating the compiler that - // we're working with automatically. - let compiler = builder.compiler_for(compiler.stage, compiler.host, target); + builder.ensure(Std::new(build_compiler, build_compiler.host).force_recompile(true)); let mut cargo = if builder.kind == Kind::Miri { if builder.top_stage == 0 { @@ -2878,7 +2904,7 @@ impl Step for Crate { // (Implicitly prepares target sysroot) let mut cargo = builder::Cargo::new( builder, - compiler, + build_compiler, mode, SourceType::InTree, target, @@ -2904,12 +2930,19 @@ impl Step for Crate { } else { // Also prepare a sysroot for the target. if !builder.config.is_host_target(target) { - builder.ensure(compile::Std::new(compiler, target).force_recompile(true)); - builder.ensure(RemoteCopyLibs { build_compiler: compiler, target }); + builder.ensure(compile::Std::new(build_compiler, target).force_recompile(true)); + builder.ensure(RemoteCopyLibs { build_compiler, target }); } // Build `cargo test` command - builder::Cargo::new(builder, compiler, mode, SourceType::InTree, target, builder.kind) + builder::Cargo::new( + builder, + build_compiler, + mode, + SourceType::InTree, + target, + builder.kind, + ) }; match mode { @@ -2928,7 +2961,7 @@ impl Step for Crate { } } Mode::Rustc => { - compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); + compile::rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates); } _ => panic!("can only test libraries"), }; @@ -2945,7 +2978,15 @@ impl Step for Crate { crates.push("alloctests".to_owned()); } - run_cargo_test(cargo, &[], &crates, &*crate_description(&self.crates), target, builder); + run_cargo_test( + cargo, + &[], + &crates, + &*crate_description(&self.crates), + target, + builder, + mode, + ); } } @@ -3039,7 +3080,15 @@ impl Step for CrateRustdoc { dylib_path.insert(0, PathBuf::from(&*libdir)); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); - run_cargo_test(cargo, &[], &["rustdoc:0.0.0".to_string()], "rustdoc", target, builder); + run_cargo_test( + cargo, + &[], + &["rustdoc:0.0.0".to_string()], + "rustdoc", + target, + builder, + Mode::ToolRustc, + ); } } @@ -3098,6 +3147,7 @@ impl Step for CrateRustdocJsonTypes { "rustdoc-json-types", target, builder, + Mode::ToolTarget, ); } } @@ -3298,7 +3348,7 @@ impl Step for Bootstrap { // bootstrap tests are racy on directory creation so just run them one at a time. // Since there's not many this shouldn't be a problem. - run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder); + run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder, Mode::ToolBootstrap); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -3441,7 +3491,7 @@ impl Step for RustInstaller { let _guard = builder.msg(Kind::Test, "rust-installer", None, build_compiler, bootstrap_host); - run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder); + run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder, Mode::ToolBootstrap); // We currently don't support running the test.sh script outside linux(?) environments. // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a @@ -3812,7 +3862,7 @@ impl Step for TestFloatParse { ); cargo_test.allow_features(TEST_FLOAT_PARSE_ALLOW_FEATURES); - run_cargo_test(cargo_test, &[], &[], "test-float-parse", target, builder); + run_cargo_test(cargo_test, &[], &[], "test-float-parse", target, builder, Mode::ToolStd); // Run the actual parse tests. let mut cargo_run = tool::prepare_tool_cargo( -- cgit 1.4.1-3-g733a5 From ef569d3ce36d18bbca01a42087f070da0cc58271 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 17:09:02 +0200 Subject: Fix spacing when testing individual crates --- src/bootstrap/src/core/builder/mod.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 5 +++-- src/bootstrap/src/lib.rs | 10 +++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index b224a7e7322..627085df812 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -295,7 +295,7 @@ pub fn crate_description(crates: &[impl AsRef]) -> String { return "".into(); } - let mut descr = String::from(" {"); + let mut descr = String::from("{"); descr.push_str(crates[0].as_ref()); for krate in &crates[1..] { descr.push_str(", "); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 921c4016654..687c2fdd7ba 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2064,9 +2064,10 @@ mod snapshot { [test] CoverageRunRustdoc [test] Pretty [build] rustc 1 -> std 1 + [build] rustc 0 -> std 0 + [build] rustdoc 0 [test] CrateLibrustc [build] rustc 1 -> rustc 2 - [build] rustdoc 0 [test] crate-bootstrap src/tools/coverage-dump [test] crate-bootstrap src/tools/jsondoclint [test] crate-bootstrap src/tools/replace-version-placeholder @@ -2101,7 +2102,7 @@ mod snapshot { [doc] rustc (book) [test] rustc 1 -> lint-docs 2 [doc] rustc 1 -> std 1 crates=[] - [test] rustc 1 -> rustdoc-js-std 2 + [test] rustdoc-js-std 1 [build] rustc 0 -> RustdocTheme 1 [test] rustdoc-theme 1 [test] RustdocUi diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 1beeb16b44f..29d0eac670a 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1144,14 +1144,18 @@ impl Build { }; let action = action.into().description(); - let msg = |fmt| format!("{action} stage{actual_stage} {what}{fmt}"); + let what = what.to_string(); + let msg = |fmt| { + let space = if !what.is_empty() { " " } else { "" }; + format!("{action} stage{actual_stage} {what}{space}{fmt}") + }; let msg = if let Some(target) = target.into() { let build_stage = host_and_stage.stage; let host = host_and_stage.host; if host == target { - msg(format_args!(" (stage{build_stage} -> stage{actual_stage}, {target})")) + msg(format_args!("(stage{build_stage} -> stage{actual_stage}, {target})")) } else { - msg(format_args!(" (stage{build_stage}:{host} -> stage{actual_stage}:{target})")) + msg(format_args!("(stage{build_stage}:{host} -> stage{actual_stage}:{target})")) } } else { msg(format_args!("")) -- cgit 1.4.1-3-g733a5 From dda8e1ddc167264ef5b0cdff0c4a3e6c7fcdca43 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 17:30:30 +0200 Subject: Do not run tests on CI in stage 0 --- src/ci/docker/host-x86_64/tidy/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ci/docker/host-x86_64/tidy/Dockerfile b/src/ci/docker/host-x86_64/tidy/Dockerfile index c8558689d3b..2dda51b155e 100644 --- a/src/ci/docker/host-x86_64/tidy/Dockerfile +++ b/src/ci/docker/host-x86_64/tidy/Dockerfile @@ -44,5 +44,5 @@ RUN bash -c 'npm install -g eslint@$(cat /tmp/eslint.version)' # NOTE: intentionally uses python2 for x.py so we can test it still works. # validate-toolstate only runs in our CI, so it's ok for it to only support python3. -ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 \ +ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \ src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck -- cgit 1.4.1-3-g733a5 From b53d532a3874517354afc3fd0bcf596b1e00fa71 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 17:18:19 +0200 Subject: Add change tracker entry --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 606d88d3db4..2cc2fb486fa 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -531,4 +531,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "It is now possible to `check/build/dist` the standard stage 0 library if you use a stage0 rustc built from in-tree sources. This is useful for quickly cross-compiling the standard library. You have to enable build.local-rebuild for this to work.", }, + ChangeInfo { + change_id: 145663, + severity: ChangeSeverity::Warning, + summary: "It is no longer possible to `x test` with stage 0, except for running compiletest and opting into `build.compiletest-allow-stage0`.", + }, ]; -- cgit 1.4.1-3-g733a5 From 425c66ecdc7f37db3f4c4d134fd01105bc9c8a3f Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 18:05:22 +0200 Subject: Skip bootstrap tests on CI --- src/bootstrap/src/core/build_steps/tool.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index e15b570a5a7..65c4c499086 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1539,7 +1539,7 @@ tool_rustc_extended!(Rustfmt { add_bins_to_sysroot: ["rustfmt"] }); -pub const TEST_FLOAT_PARSE_ALLOW_FEATURES: &'static str = "f16,cfg_target_has_reliable_f16_f128"; +pub const TEST_FLOAT_PARSE_ALLOW_FEATURES: &str = "f16,cfg_target_has_reliable_f16_f128"; impl Builder<'_> { /// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 687c2fdd7ba..11cbf9d38dd 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2042,6 +2042,10 @@ mod snapshot { let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("test") + // Skip bootstrap tests, as for some reason the recursive nature of running + // bootstrap tests under bootstrap tests causes non-deterministic snapshot diffs + // on CI. + .args(&["--skip", "bootstrap"]) .render_steps(), @r" [build] rustc 0 -> Tidy 1 [test] tidy <> -- cgit 1.4.1-3-g733a5 From 1591901e2f2cae2c1b79f330e9d392b594db4cc1 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 19:37:45 +0200 Subject: Fix doclink --- src/bootstrap/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 29d0eac670a..0584c53f549 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1165,7 +1165,7 @@ impl Build { /// Return a `Group` guard for a [`Step`] that tests `what` with the given `stage` and `target` /// (determined by `host_and_stage`). - /// Use this instead of [`Builder::msg`] when there is no clear `build_compiler` to be + /// Use this instead of [`builder::Builder::msg`] when there is no clear `build_compiler` to be /// determined. /// /// [`Step`]: crate::core::builder::Step -- cgit 1.4.1-3-g733a5 From 1c1d630c8c3a74837d30846a8280da0e14ca87e9 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 19:53:24 +0200 Subject: Fake nodejs in snapshot test --- src/bootstrap/src/core/builder/tests.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 11cbf9d38dd..67e89c1fb02 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2046,6 +2046,8 @@ mod snapshot { // bootstrap tests under bootstrap tests causes non-deterministic snapshot diffs // on CI. .args(&["--skip", "bootstrap"]) + // rustdoc-js-std requires nodejs to be present + .args(&["--set", "build.nodejs=/bin/nodejs"]) .render_steps(), @r" [build] rustc 0 -> Tidy 1 [test] tidy <> -- cgit 1.4.1-3-g733a5 From daaf0c9eb5b98aba6317980782259c17416bdaf5 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 21:01:31 +0200 Subject: Fix tests and doclink --- src/bootstrap/src/core/builder/tests.rs | 18 +++++++++--------- src/bootstrap/src/lib.rs | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 67e89c1fb02..b3c13f22814 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2042,15 +2042,18 @@ mod snapshot { let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("test") - // Skip bootstrap tests, as for some reason the recursive nature of running - // bootstrap tests under bootstrap tests causes non-deterministic snapshot diffs - // on CI. - .args(&["--skip", "bootstrap"]) - // rustdoc-js-std requires nodejs to be present - .args(&["--set", "build.nodejs=/bin/nodejs"]) + // Bootstrap only run by default on CI, so we have to emulate that also locally. + .args(&["--ci", "true"]) + // These rustdoc tests requires nodejs to be present. + // We can't easily opt out of it, so if it is present on the local PC, the test + // would have different result on CI, where nodejs might be missing. + .args(&["--skip", "rustdoc-js-std"]) + .args(&["--skip", "rustdoc-js"]) + .args(&["--skip", "rustdoc-gui"]) .render_steps(), @r" [build] rustc 0 -> Tidy 1 [test] tidy <> + [build] rustdoc 0 [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 @@ -2071,7 +2074,6 @@ mod snapshot { [test] Pretty [build] rustc 1 -> std 1 [build] rustc 0 -> std 0 - [build] rustdoc 0 [test] CrateLibrustc [build] rustc 1 -> rustc 2 [test] crate-bootstrap src/tools/coverage-dump @@ -2107,8 +2109,6 @@ mod snapshot { [test] rustc 0 -> rust-analyzer 1 [doc] rustc (book) [test] rustc 1 -> lint-docs 2 - [doc] rustc 1 -> std 1 crates=[] - [test] rustdoc-js-std 1 [build] rustc 0 -> RustdocTheme 1 [test] rustdoc-theme 1 [test] RustdocUi diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 0584c53f549..9a882eae08e 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1165,7 +1165,7 @@ impl Build { /// Return a `Group` guard for a [`Step`] that tests `what` with the given `stage` and `target` /// (determined by `host_and_stage`). - /// Use this instead of [`builder::Builder::msg`] when there is no clear `build_compiler` to be + /// Use this instead of [`Build::msg`] when there is no clear `build_compiler` to be /// determined. /// /// [`Step`]: crate::core::builder::Step -- cgit 1.4.1-3-g733a5 From d2195c483c2c0593b1b6cde7a9f4097ec9c17c10 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 27 Aug 2025 11:35:10 +0200 Subject: Add test stage 2 snapshot tests --- src/bootstrap/src/core/builder/tests.rs | 107 +++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b3c13f22814..31f863f240f 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2037,19 +2037,23 @@ mod snapshot { .render_steps(), @"[check] rustc 0 -> RunMakeSupport 1 "); } + fn prepare_test_config(ctx: &TestCtx) -> ConfigBuilder { + ctx.config("test") + // Bootstrap only runs by default on CI, so we have to emulate that also locally. + .args(&["--ci", "true"]) + // These rustdoc tests requires nodejs to be present. + // We can't easily opt out of it, so if it is present on the local PC, the test + // would have different result on CI, where nodejs might be missing. + .args(&["--skip", "rustdoc-js-std"]) + .args(&["--skip", "rustdoc-js"]) + .args(&["--skip", "rustdoc-gui"]) + } + #[test] - fn test_all() { + fn test_all_stage_1() { let ctx = TestCtx::new(); insta::assert_snapshot!( - ctx.config("test") - // Bootstrap only run by default on CI, so we have to emulate that also locally. - .args(&["--ci", "true"]) - // These rustdoc tests requires nodejs to be present. - // We can't easily opt out of it, so if it is present on the local PC, the test - // would have different result on CI, where nodejs might be missing. - .args(&["--skip", "rustdoc-js-std"]) - .args(&["--skip", "rustdoc-js"]) - .args(&["--skip", "rustdoc-gui"]) + prepare_test_config(&ctx) .render_steps(), @r" [build] rustc 0 -> Tidy 1 [test] tidy <> @@ -2124,6 +2128,89 @@ mod snapshot { "); } + #[test] + fn test_all_stage_2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + prepare_test_config(&ctx) + .stage(2) + .render_steps(), @r" + [build] rustc 0 -> Tidy 1 + [test] tidy <> + [build] rustdoc 0 + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 2 -> std 2 + [build] rustc 0 -> Compiletest 1 + [test] Ui + [test] Crashes + [build] rustc 0 -> CoverageDump 1 + [build] rustc 2 -> std 2 + [test] CodegenLlvm + [test] CodegenUnits + [test] AssemblyLlvm + [test] Incremental + [test] Debuginfo + [build] rustc 2 -> rustc 3 + [test] UiFullDeps + [build] rustdoc 2 + [test] Rustdoc + [test] CoverageRunRustdoc + [test] Pretty + [build] rustc 2 -> std 2 + [build] rustc 1 -> std 1 + [build] rustdoc 1 + [test] rustc 1 -> CrateLibrustc 2 + [test] crate-bootstrap src/tools/coverage-dump + [test] crate-bootstrap src/tools/jsondoclint + [test] crate-bootstrap src/tools/replace-version-placeholder + [test] crate-bootstrap tidyselftest + [build] rustc 0 -> UnstableBookGen 1 + [build] rustc 0 -> Rustbook 1 + [doc] unstable-book (book) + [doc] book (book) + [doc] book/first-edition (book) + [doc] book/second-edition (book) + [doc] book/2018-edition (book) + [doc] rustc 1 -> standalone 2 + [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [build] rustc 1 -> error-index 2 + [doc] rustc 1 -> error-index 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) + [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 + [build] rustc 0 -> Linkchecker 1 + [test] link-check + [test] tier-check + [test] rustc 1 -> rust-analyzer 2 + [doc] rustc (book) + [test] rustc 1 -> lint-docs 2 + [build] rustc 0 -> RustdocTheme 1 + [test] rustdoc-theme 2 + [test] RustdocUi + [build] rustc 0 -> JsonDocCk 1 + [build] rustc 0 -> JsonDocLint 1 + [test] RustdocJson + [doc] rustc 1 -> rustc 2 + [build] rustc 0 -> HtmlChecker 1 + [test] html-check + [build] rustc 0 -> RunMakeSupport 1 + [build] rustc 2 -> cargo 3 + [test] RunMake + "); + } + #[test] fn test_exclude() { let ctx = TestCtx::new(); -- cgit 1.4.1-3-g733a5 From 9de09ac101f5e46b7eda48261a6757dc78b25bd8 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Mon, 25 Aug 2025 17:40:01 +0200 Subject: Fix stage 1 compiler tests --- compiler/rustc_lint_defs/src/builtin.rs | 11 +++++--- src/bootstrap/src/core/build_steps/doc.rs | 2 ++ src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 42 +++++++++++++++++++++++++++--- src/bootstrap/src/core/config/config.rs | 4 +-- src/tools/lint-docs/src/lib.rs | 42 ++++++++++++++++++++++++------ src/tools/lint-docs/src/main.rs | 13 +++++++++ 7 files changed, 97 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 97aa1065967..ce92263babd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2309,10 +2309,10 @@ declare_lint! { /// ### Example /// /// ```rust - /// #![feature(sanitize)] + /// #![cfg_attr(not(bootstrap), feature(sanitize))] /// /// #[inline(always)] - /// #[sanitize(address = "off")] + /// #[cfg_attr(not(bootstrap), sanitize(address = "off"))] /// fn x() {} /// /// fn main() { @@ -4832,13 +4832,16 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail + #[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")] + #[cfg_attr(bootstrap, doc = "```rust")] /// #![doc = in_root!()] /// /// macro_rules! in_root { () => { "" } } /// /// fn main() {} - /// ``` + #[cfg_attr(not(bootstrap), doc = "```")] + #[cfg_attr(bootstrap, doc = "```")] + // ^ Needed to avoid tidy warning about odd number of backticks /// /// {{produces}} /// diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 678fe127879..0789eefa894 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1293,6 +1293,8 @@ impl Step for RustcBook { // functional sysroot. builder.std(self.build_compiler, self.target); let mut cmd = builder.tool_cmd(Tool::LintDocs); + cmd.arg("--build-rustc-stage"); + cmd.arg(self.build_compiler.stage.to_string()); cmd.arg("--src"); cmd.arg(builder.src.join("compiler")); cmd.arg("--out"); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index ad17a557658..1786e8d17b6 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2730,7 +2730,7 @@ impl Step for CrateLibrustc { } fn metadata(&self) -> Option { - Some(StepMetadata::test("CrateLibrustc", self.target)) + Some(StepMetadata::test("CrateLibrustc", self.target).built_by(self.build_compiler)) } } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 31f863f240f..f14c897cab4 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2078,7 +2078,7 @@ mod snapshot { [test] Pretty [build] rustc 1 -> std 1 [build] rustc 0 -> std 0 - [test] CrateLibrustc + [test] rustc 0 -> CrateLibrustc 1 [build] rustc 1 -> rustc 2 [test] crate-bootstrap src/tools/coverage-dump [test] crate-bootstrap src/tools/jsondoclint @@ -2211,6 +2211,40 @@ mod snapshot { "); } + #[test] + fn test_compiler_stage_1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .path("compiler") + .stage(1) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 0 -> std 0 + [build] rustdoc 0 + [test] rustc 0 -> CrateLibrustc 1 + "); + } + + #[test] + fn test_compiler_stage_2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .path("compiler") + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 1 -> std 1 + [build] rustdoc 1 + [test] rustc 1 -> CrateLibrustc 2 + "); + } + #[test] fn test_exclude() { let ctx = TestCtx::new(); @@ -2228,13 +2262,15 @@ mod snapshot { let get_steps = |args: &[&str]| ctx.config("test").args(args).get_steps(); + let rustc_metadata = + || StepMetadata::test("CrateLibrustc", host).built_by(Compiler::new(0, host)); // Ensure our test is valid, and `test::Rustc` would be run without the exclude. - get_steps(&[]).assert_contains(StepMetadata::test("CrateLibrustc", host)); + get_steps(&[]).assert_contains(rustc_metadata()); let steps = get_steps(&["--skip", "compiler/rustc_data_structures"]); // Ensure tests for rustc are not skipped. - steps.assert_contains(StepMetadata::test("CrateLibrustc", host)); + steps.assert_contains(rustc_metadata()); steps.assert_contains_fuzzy(StepMetadata::build("rustc", host)); } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 450f325f1a9..d12cc962187 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1012,9 +1012,7 @@ impl Config { } if flags_compile_time_deps && !matches!(flags_cmd, Subcommand::Check { .. }) { - eprintln!( - "ERROR: Can't use --compile-time-deps with any subcommand other than check." - ); + eprintln!("ERROR: Can't use --compile-time-deps with any subcommand other than check."); exit!(1); } diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index b33344ca5dd..bc38e931fe5 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -59,6 +59,8 @@ pub struct LintExtractor<'a> { pub rustc_target: &'a str, /// The target linker overriding `rustc`'s default pub rustc_linker: Option<&'a str>, + /// Stage of the compiler that builds the docs (the stage of `rustc_path`). + pub build_rustc_stage: u32, /// Verbose output. pub verbose: bool, /// Validate the style and the code example. @@ -216,14 +218,7 @@ impl<'a> LintExtractor<'a> { if let Some(text) = line.strip_prefix("/// ") { doc_lines.push(text.to_string()); } else if let Some(text) = line.strip_prefix("#[doc = \"") { - let escaped = text.strip_suffix("\"]").unwrap(); - let mut buf = String::new(); - unescape_str(escaped, |_, res| match res { - Ok(c) => buf.push(c), - Err(err) => { - assert!(!err.is_fatal(), "failed to unescape string literal") - } - }); + let buf = parse_doc_string(text); doc_lines.push(buf); } else if line == "///" { doc_lines.push("".to_string()); @@ -234,6 +229,20 @@ impl<'a> LintExtractor<'a> { // Ignore allow of lints (useful for // invalid_rust_codeblocks). continue; + } else if let Some(text) = + line.strip_prefix("#[cfg_attr(not(bootstrap), doc = \"") + { + if self.build_rustc_stage >= 1 { + let buf = parse_doc_string(text); + doc_lines.push(buf); + } + } else if let Some(text) = + line.strip_prefix("#[cfg_attr(bootstrap, doc = \"") + { + if self.build_rustc_stage == 0 { + let buf = parse_doc_string(text); + doc_lines.push(buf); + } } else { let name = lint_name(line).map_err(|e| { format!( @@ -580,6 +589,23 @@ impl<'a> LintExtractor<'a> { } } +/// Parses a doc string that follows `#[doc = "`. +fn parse_doc_string(text: &str) -> String { + let escaped = text.strip_suffix("]").unwrap_or(text); + let escaped = escaped.strip_suffix(")").unwrap_or(escaped).strip_suffix("\""); + let Some(escaped) = escaped else { + panic!("Cannot extract docstring content from {text}"); + }; + let mut buf = String::new(); + unescape_str(escaped, |_, res| match res { + Ok(c) => buf.push(c), + Err(err) => { + assert!(!err.is_fatal(), "failed to unescape string literal") + } + }); + buf +} + /// Adds `Lint`s that have been renamed. fn add_renamed_lints(lints: &mut Vec) { for (level, names) in RENAMES { diff --git a/src/tools/lint-docs/src/main.rs b/src/tools/lint-docs/src/main.rs index e377283b1a4..1933ce4d2f1 100644 --- a/src/tools/lint-docs/src/main.rs +++ b/src/tools/lint-docs/src/main.rs @@ -25,6 +25,7 @@ fn doit() -> Result<(), Box> { let mut args = std::env::args().skip(1); let mut src_path = None; let mut out_path = None; + let mut build_rustc_stage = None; let mut rustc_path = None; let mut rustc_target = None; let mut rustc_linker = None; @@ -32,6 +33,14 @@ fn doit() -> Result<(), Box> { let mut validate = false; while let Some(arg) = args.next() { match arg.as_str() { + "--build-rustc-stage" => { + build_rustc_stage = match args.next() { + Some(s) => { + Some(s.parse::().expect("build rustc stage has to be an integer")) + } + None => return Err("--build-rustc-stage requires a value".into()), + }; + } "--src" => { src_path = match args.next() { Some(s) => Some(PathBuf::from(s)), @@ -67,6 +76,9 @@ fn doit() -> Result<(), Box> { s => return Err(format!("unexpected argument `{}`", s).into()), } } + if build_rustc_stage.is_none() { + return Err("--build-rustc-stage must be specified to the stage of the compiler that generates the docs".into()); + } if src_path.is_none() { return Err("--src must be specified to the directory with the compiler source".into()); } @@ -85,6 +97,7 @@ fn doit() -> Result<(), Box> { rustc_path: &rustc_path.unwrap(), rustc_target: &rustc_target.unwrap(), rustc_linker: rustc_linker.as_deref(), + build_rustc_stage: build_rustc_stage.unwrap(), verbose, validate, }; -- cgit 1.4.1-3-g733a5 From 5bc9308471ce452003bfebd97db401ae145bffda Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 27 Aug 2025 11:38:39 +0200 Subject: Do not run `lint-docs` tests in stage 1 `x test` by default --- src/bootstrap/src/core/build_steps/test.rs | 20 +++++++++----------- src/bootstrap/src/core/builder/tests.rs | 4 +--- 2 files changed, 10 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1786e8d17b6..95be5360b0b 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2693,7 +2693,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> /// which have their own separate test steps.) #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateLibrustc { - /// The compiler that will *build* rustc in test mode. + /// The compiler that will run unit tests and doctests on the in-tree rustc source. build_compiler: Compiler, target: TargetSelection, crates: Vec, @@ -3429,24 +3429,22 @@ impl Step for LintDocs { const IS_HOST: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/lint-docs") + let stage = run.builder.top_stage; + // Lint docs tests might not work with stage 1, so do not run this test by default in + // `x test` below stage 2. + run.path("src/tools/lint-docs").default_condition(stage > 1) } 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 test` 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 - }; + if run.builder.top_stage < 2 { + eprintln!("WARNING: lint-docs tests might not work below stage 2"); + } run.builder.ensure(LintDocs { build_compiler: prepare_doc_compiler( run.builder, run.builder.config.host_target, - stage, + run.builder.top_stage, ), target: run.target, }); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index f14c897cab4..43e67756e74 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2111,8 +2111,6 @@ mod snapshot { [test] link-check [test] tier-check [test] rustc 0 -> rust-analyzer 1 - [doc] rustc (book) - [test] rustc 1 -> lint-docs 2 [build] rustc 0 -> RustdocTheme 1 [test] rustdoc-theme 1 [test] RustdocUi @@ -2175,7 +2173,7 @@ mod snapshot { [doc] book/second-edition (book) [doc] book/2018-edition (book) [doc] rustc 1 -> standalone 2 - [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] + [doc] rustc 1 -> std 1 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 [doc] rustc 1 -> error-index 2 [doc] nomicon (book) -- cgit 1.4.1-3-g733a5 From 2dc57526c276c12de478194dfef0f5af5fbe30cb Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 30 Aug 2025 13:11:21 -0400 Subject: Use move_file for rename in tracing This avoids panicking when the source and destinations are on different filesystems. --- src/bootstrap/src/utils/tracing.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/src/utils/tracing.rs b/src/bootstrap/src/utils/tracing.rs index 472781ffa73..b1226ed7de7 100644 --- a/src/bootstrap/src/utils/tracing.rs +++ b/src/bootstrap/src/utils/tracing.rs @@ -168,7 +168,11 @@ mod inner { impl TracingGuard { pub fn copy_to_dir(self, dir: &std::path::Path) { drop(self.guard); - std::fs::rename(&self.chrome_tracing_path, dir.join("chrome-trace.json")).unwrap(); + crate::utils::helpers::move_file( + &self.chrome_tracing_path, + dir.join("chrome-trace.json"), + ) + .unwrap(); } } -- cgit 1.4.1-3-g733a5 From 0becce400b73dc54754d005e1e4513811043466b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 30 Aug 2025 11:11:37 -0700 Subject: rustdoc-search: split function inverted index by input/output With a patch applied to count the number of unifications, and running the query `Option, (T -> U) -> Option` before: performed unifyFunctionType on 17484 functions after: performed unifyFunctionType on 3055 functions --- src/librustdoc/html/render/search_index.rs | 255 ++++++++++++++++++++++++----- src/librustdoc/html/static/js/rustdoc.d.ts | 5 +- src/librustdoc/html/static/js/search.js | 63 ++++--- 3 files changed, 256 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index dddc087d124..2984f3ab50e 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -289,8 +289,26 @@ impl SerializedSearchIndex { (Some(self_type_data), None) => Some(self_type_data), (None, Some(other_type_data)) => Some(TypeData { search_unbox: other_type_data.search_unbox, - inverted_function_signature_index: other_type_data - .inverted_function_signature_index + inverted_function_inputs_index: other_type_data + .inverted_function_inputs_index + .iter() + .cloned() + .map(|mut list: Vec| { + for fnid in &mut list { + assert!( + other.function_data + [usize::try_from(*fnid).unwrap()] + .is_some(), + ); + // this is valid because we call `self.push()` once, exactly, for every entry, + // even if we're just pushing a tombstone + *fnid += u32::try_from(other_entryid_offset).unwrap(); + } + list + }) + .collect(), + inverted_function_output_index: other_type_data + .inverted_function_output_index .iter() .cloned() .map(|mut list: Vec| { @@ -310,18 +328,42 @@ impl SerializedSearchIndex { }), (Some(mut self_type_data), Some(other_type_data)) => { for (size, other_list) in other_type_data - .inverted_function_signature_index + .inverted_function_inputs_index + .iter() + .enumerate() + { + while self_type_data.inverted_function_inputs_index.len() + <= size + { + self_type_data + .inverted_function_inputs_index + .push(Vec::new()); + } + self_type_data.inverted_function_inputs_index[size].extend( + other_list.iter().copied().map(|fnid| { + assert!( + other.function_data[usize::try_from(fnid).unwrap()] + .is_some(), + ); + // this is valid because we call `self.push()` once, exactly, for every entry, + // even if we're just pushing a tombstone + fnid + u32::try_from(other_entryid_offset).unwrap() + }), + ) + } + for (size, other_list) in other_type_data + .inverted_function_output_index .iter() .enumerate() { - while self_type_data.inverted_function_signature_index.len() + while self_type_data.inverted_function_output_index.len() <= size { self_type_data - .inverted_function_signature_index + .inverted_function_output_index .push(Vec::new()); } - self_type_data.inverted_function_signature_index[size].extend( + self_type_data.inverted_function_output_index[size].extend( other_list.iter().copied().map(|fnid| { assert!( other.function_data[usize::try_from(fnid).unwrap()] @@ -443,8 +485,25 @@ impl SerializedSearchIndex { param_names: function_data.param_names.clone(), }), other.type_data[other_entryid].as_ref().map(|type_data| TypeData { - inverted_function_signature_index: type_data - .inverted_function_signature_index + inverted_function_inputs_index: type_data + .inverted_function_inputs_index + .iter() + .cloned() + .map(|mut list| { + for fnid in &mut list { + assert!( + other.function_data[usize::try_from(*fnid).unwrap()] + .is_some(), + ); + // this is valid because we call `self.push()` once, exactly, for every entry, + // even if we're just pushing a tombstone + *fnid += u32::try_from(other_entryid_offset).unwrap(); + } + list + }) + .collect(), + inverted_function_output_index: type_data + .inverted_function_output_index .iter() .cloned() .map(|mut list| { @@ -599,9 +658,13 @@ impl SerializedSearchIndex { }, ), self.type_data[id].as_ref().map( - |TypeData { search_unbox, inverted_function_signature_index }| { - let inverted_function_signature_index: Vec> = - inverted_function_signature_index + |TypeData { + search_unbox, + inverted_function_inputs_index, + inverted_function_output_index, + }| { + let inverted_function_inputs_index: Vec> = + inverted_function_inputs_index .iter() .cloned() .map(|mut list| { @@ -615,7 +678,26 @@ impl SerializedSearchIndex { list }) .collect(); - TypeData { search_unbox: *search_unbox, inverted_function_signature_index } + let inverted_function_output_index: Vec> = + inverted_function_output_index + .iter() + .cloned() + .map(|mut list| { + for id in &mut list { + *id = u32::try_from( + *map.get(&usize::try_from(*id).unwrap()).unwrap(), + ) + .unwrap(); + } + list.sort(); + list + }) + .collect(); + TypeData { + search_unbox: *search_unbox, + inverted_function_inputs_index, + inverted_function_output_index, + } }, ), self.alias_pointers[id].and_then(|alias| map.get(&alias).copied()), @@ -934,18 +1016,20 @@ struct TypeData { /// | `Unboxable` | yes | no | no | /// | `Inner` | no | no | yes | search_unbox: bool, - /// List of functions that mention this type in their type signature. + /// List of functions that mention this type in their type signature, + /// on the left side of the `->` arrow. /// - /// - The outermost list has one entry per alpha-normalized generic. - /// - /// - The second layer is sorted by number of types that appear in the + /// - The outer layer is sorted by number of types that appear in the /// type signature. The search engine iterates over these in order from /// smallest to largest. Functions with less stuff in their type /// signature are more likely to be what the user wants, because we never /// show functions that are *missing* parts of the query, so removing.. /// - /// - The final layer is the list of functions. - inverted_function_signature_index: Vec>, + /// - The inner layer is the list of functions. + inverted_function_inputs_index: Vec>, + /// List of functions that mention this type in their type signature, + /// on the right side of the `->` arrow. + inverted_function_output_index: Vec>, } impl Serialize for TypeData { @@ -953,15 +1037,21 @@ impl Serialize for TypeData { where S: Serializer, { - if self.search_unbox || !self.inverted_function_signature_index.is_empty() { + if self.search_unbox + || !self.inverted_function_inputs_index.is_empty() + || !self.inverted_function_output_index.is_empty() + { let mut seq = serializer.serialize_seq(None)?; - if !self.inverted_function_signature_index.is_empty() { - let mut buf = Vec::new(); - encode::write_postings_to_string(&self.inverted_function_signature_index, &mut buf); - let mut serialized_result = Vec::new(); - stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); - seq.serialize_element(&String::from_utf8(serialized_result).unwrap())?; - } + let mut buf = Vec::new(); + encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf); + let mut serialized_result = Vec::new(); + stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); + seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; + buf.clear(); + serialized_result.clear(); + encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf); + stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result); + seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?; if self.search_unbox { seq.serialize_element(&1)?; } @@ -984,21 +1074,39 @@ impl<'de> Deserialize<'de> for TypeData { write!(formatter, "type data") } fn visit_none(self) -> Result { - Ok(TypeData { inverted_function_signature_index: vec![], search_unbox: false }) + Ok(TypeData { + inverted_function_inputs_index: vec![], + inverted_function_output_index: vec![], + search_unbox: false, + }) } fn visit_seq>(self, mut v: A) -> Result { - let inverted_function_signature_index: String = + let inverted_function_inputs_index: String = + v.next_element()?.unwrap_or(String::new()); + let inverted_function_output_index: String = v.next_element()?.unwrap_or(String::new()); let search_unbox: u32 = v.next_element()?.unwrap_or(0); let mut idx: Vec = Vec::new(); stringdex_internals::decode::read_base64_from_bytes( - inverted_function_signature_index.as_bytes(), + inverted_function_inputs_index.as_bytes(), &mut idx, ) .unwrap(); - let mut inverted_function_signature_index = Vec::new(); - encode::read_postings_from_string(&mut inverted_function_signature_index, &idx); - Ok(TypeData { inverted_function_signature_index, search_unbox: search_unbox == 1 }) + let mut inverted_function_inputs_index = Vec::new(); + encode::read_postings_from_string(&mut inverted_function_inputs_index, &idx); + idx.clear(); + stringdex_internals::decode::read_base64_from_bytes( + inverted_function_output_index.as_bytes(), + &mut idx, + ) + .unwrap(); + let mut inverted_function_output_index = Vec::new(); + encode::read_postings_from_string(&mut inverted_function_output_index, &idx); + Ok(TypeData { + inverted_function_inputs_index, + inverted_function_output_index, + search_unbox: search_unbox == 1, + }) } } deserializer.deserialize_any(TypeDataVisitor) @@ -1222,8 +1330,16 @@ pub(crate) fn build_index( let index = *index.get(); serialized_index.descs[index] = crate_doc; for type_data in serialized_index.type_data.iter_mut() { - if let Some(TypeData { inverted_function_signature_index, .. }) = type_data { - for list in &mut inverted_function_signature_index[..] { + if let Some(TypeData { + inverted_function_inputs_index, + inverted_function_output_index, + .. + }) = type_data + { + for list in inverted_function_inputs_index + .iter_mut() + .chain(inverted_function_output_index.iter_mut()) + { list.retain(|fnid| { serialized_index.entry_data[usize::try_from(*fnid).unwrap()] .as_ref() @@ -1449,7 +1565,8 @@ pub(crate) fn build_index( if serialized_index.type_data[id].as_mut().is_none() { serialized_index.type_data[id] = Some(TypeData { search_unbox, - inverted_function_signature_index: Vec::new(), + inverted_function_inputs_index: Vec::new(), + inverted_function_output_index: Vec::new(), }); } else if search_unbox { serialized_index.type_data[id].as_mut().unwrap().search_unbox = true; @@ -1473,7 +1590,11 @@ pub(crate) fn build_index( None }, }, - TypeData { search_unbox, inverted_function_signature_index: Vec::new() }, + TypeData { + inverted_function_inputs_index: Vec::new(), + inverted_function_output_index: Vec::new(), + search_unbox, + }, ); pathid } @@ -1695,13 +1816,14 @@ pub(crate) fn build_index( } } if let Some(search_type) = &mut item.search_type { - let mut used_in_function_signature = BTreeSet::new(); + let mut used_in_function_inputs = BTreeSet::new(); + let mut used_in_function_output = BTreeSet::new(); for item in &mut search_type.inputs { convert_render_type( item, cache, &mut serialized_index, - &mut used_in_function_signature, + &mut used_in_function_inputs, tcx, ); } @@ -1710,20 +1832,44 @@ pub(crate) fn build_index( item, cache, &mut serialized_index, - &mut used_in_function_signature, + &mut used_in_function_output, tcx, ); } + let mut used_in_constraints = Vec::new(); for constraint in &mut search_type.where_clause { + let mut used_in_constraint = BTreeSet::new(); for trait_ in &mut constraint[..] { convert_render_type( trait_, cache, &mut serialized_index, - &mut used_in_function_signature, + &mut used_in_constraint, tcx, ); } + used_in_constraints.push(used_in_constraint); + } + loop { + let mut inserted_any = false; + for (i, used_in_constraint) in used_in_constraints.iter().enumerate() { + let id = !(i as isize); + if used_in_function_inputs.contains(&id) + && !used_in_function_inputs.is_superset(&used_in_constraint) + { + used_in_function_inputs.extend(used_in_constraint.iter().copied()); + inserted_any = true; + } + if used_in_function_output.contains(&id) + && !used_in_function_output.is_superset(&used_in_constraint) + { + used_in_function_output.extend(used_in_constraint.iter().copied()); + inserted_any = true; + } + } + if !inserted_any { + break; + } } let search_type_size = search_type.size() + // Artificially give struct fields a size of 8 instead of their real @@ -1746,13 +1892,34 @@ pub(crate) fn build_index( .map(|sym| sym.map(|sym| sym.to_string()).unwrap_or(String::new())) .collect::>(), }); - for index in used_in_function_signature { + for index in used_in_function_inputs { + let postings = if index >= 0 { + assert!(serialized_index.path_data[index as usize].is_some()); + &mut serialized_index.type_data[index as usize] + .as_mut() + .unwrap() + .inverted_function_inputs_index + } else { + let generic_id = usize::try_from(-index).unwrap() - 1; + for _ in serialized_index.generic_inverted_index.len()..=generic_id { + serialized_index.generic_inverted_index.push(Vec::new()); + } + &mut serialized_index.generic_inverted_index[generic_id] + }; + while postings.len() <= search_type_size { + postings.push(Vec::new()); + } + if postings[search_type_size].last() != Some(&(new_entry_id as u32)) { + postings[search_type_size].push(new_entry_id as u32); + } + } + for index in used_in_function_output { let postings = if index >= 0 { assert!(serialized_index.path_data[index as usize].is_some()); &mut serialized_index.type_data[index as usize] .as_mut() .unwrap() - .inverted_function_signature_index + .inverted_function_output_index } else { let generic_id = usize::try_from(-index).unwrap() - 1; for _ in serialized_index.generic_inverted_index.len()..=generic_id { @@ -1763,7 +1930,9 @@ pub(crate) fn build_index( while postings.len() <= search_type_size { postings.push(Vec::new()); } - postings[search_type_size].push(new_entry_id as u32); + if postings[search_type_size].last() != Some(&(new_entry_id as u32)) { + postings[search_type_size].push(new_entry_id as u32); + } } } } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 3ac10742e41..74f646008eb 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -270,9 +270,12 @@ declare namespace rustdoc { */ interface TypeData { searchUnbox: boolean, - invertedFunctionSignatureIndex: RoaringBitmap[], + invertedFunctionInputsIndex: RoaringBitmap[], + invertedFunctionOutputIndex: RoaringBitmap[], } + type TypeInvertedIndexPolarity = "invertedFunctionInputsIndex" | "invertedFunctionOutputIndex"; + /** * A search entry of some sort. */ diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index b003bcc7bf9..2854f65b599 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1696,7 +1696,7 @@ class DocSearch { } /** * function_signature, param_names - * @type {[string, number] | [number] | [string] | [] | null} + * @type {[string, string, number] | [string, string] | [] | null} */ const raw = JSON.parse(encoded); @@ -1705,32 +1705,46 @@ class DocSearch { } let searchUnbox = false; - const invertedFunctionSignatureIndex = []; + const invertedFunctionInputsIndex = []; + const invertedFunctionOutputIndex = []; if (typeof raw[0] === "string") { - if (raw[1]) { + if (raw[2]) { searchUnbox = true; } // the inverted function signature index is a list of bitmaps, // by number of types that appear in the function let i = 0; - const pb = makeUint8ArrayFromBase64(raw[0]); - const l = pb.length; + let pb = makeUint8ArrayFromBase64(raw[0]); + let l = pb.length; + while (i < l) { + if (pb[i] === 0) { + invertedFunctionInputsIndex.push(RoaringBitmap.empty()); + i += 1; + } else { + const bitmap = new RoaringBitmap(pb, i); + i += bitmap.consumed_len_bytes; + invertedFunctionInputsIndex.push(bitmap); + } + } + i = 0; + pb = makeUint8ArrayFromBase64(raw[1]); + l = pb.length; while (i < l) { if (pb[i] === 0) { - invertedFunctionSignatureIndex.push(RoaringBitmap.empty()); + invertedFunctionOutputIndex.push(RoaringBitmap.empty()); i += 1; } else { const bitmap = new RoaringBitmap(pb, i); i += bitmap.consumed_len_bytes; - invertedFunctionSignatureIndex.push(bitmap); + invertedFunctionOutputIndex.push(bitmap); } } } else if (raw[0]) { searchUnbox = true; } - return { searchUnbox, invertedFunctionSignatureIndex }; + return { searchUnbox, invertedFunctionInputsIndex, invertedFunctionOutputIndex }; } /** @@ -4009,9 +4023,10 @@ class DocSearch { * or anything else. This function returns all possible permutations. * * @param {rustdoc.ParserQueryElement|null} elem + * @param {rustdoc.TypeInvertedIndexPolarity} polarity * @returns {Promise[]>} */ - const unpackPostingsList = async elem => { + const unpackPostingsList = async(elem, polarity) => { if (!elem) { return empty_postings_list; } @@ -4039,7 +4054,7 @@ class DocSearch { const types = (await Promise.all(typePromises)) .filter(([_id, name, ty, path]) => name !== null && name.toLowerCase() === elem.pathLast && - ty && !ty.invertedFunctionSignatureIndex.every(bitmap => { + ty && !ty[polarity].every(bitmap => { return bitmap.isEmpty(); }) && path && path.ty !== TY_ASSOCTYPE && @@ -4078,7 +4093,7 @@ class DocSearch { this.getPathData(id), ]); if (name !== null && ty !== null && path !== null && - !ty.invertedFunctionSignatureIndex.every(bitmap => { + !ty[polarity].every(bitmap => { return bitmap.isEmpty(); }) && path.ty !== TY_ASSOCTYPE @@ -4176,18 +4191,18 @@ class DocSearch { /** @type {PostingsList[]} */ const results = []; for (const [id, _name, typeData] of types) { - if (!typeData || typeData.invertedFunctionSignatureIndex.every(bitmap => { + if (!typeData || typeData[polarity].every(bitmap => { return bitmap.isEmpty(); })) { continue; } - const upla = await unpackPostingsListAll(elem.generics); - const uplb = await unpackPostingsListBindings(elem.bindings); + const upla = await unpackPostingsListAll(elem.generics, polarity); + const uplb = await unpackPostingsListBindings(elem.bindings, polarity); for (const {invertedIndex: genericsIdx, queryElem: generics} of upla) { for (const {invertedIndex: bindingsIdx, queryElem: bindings} of uplb) { results.push({ invertedIndex: intersectInvertedIndexes( - typeData.invertedFunctionSignatureIndex, + typeData[polarity], genericsIdx, bindingsIdx, ), @@ -4219,15 +4234,16 @@ class DocSearch { * take the intersection of this bitmap. * * @param {(rustdoc.ParserQueryElement|null)[]|null} elems + * @param {rustdoc.TypeInvertedIndexPolarity} polarity * @returns {Promise[]>} */ - const unpackPostingsListAll = async elems => { + const unpackPostingsListAll = async(elems, polarity) => { if (!elems || elems.length === 0) { return nested_everything_postings_list; } const [firstPostingsList, remainingAll] = await Promise.all([ - unpackPostingsList(elems[0]), - unpackPostingsListAll(elems.slice(1)), + unpackPostingsList(elems[0], polarity), + unpackPostingsListAll(elems.slice(1), polarity), ]); /** @type {PostingsList[]} */ const results = []; @@ -4261,11 +4277,12 @@ class DocSearch { * Before passing an actual parser item to it, make sure to clone the map. * * @param {Map} elems + * @param {rustdoc.TypeInvertedIndexPolarity} polarity * @returns {Promise, * >[]>} */ - const unpackPostingsListBindings = async elems => { + const unpackPostingsListBindings = async(elems, polarity) => { if (!elems) { return [{ invertedIndex: everything_inverted_index, @@ -4296,8 +4313,8 @@ class DocSearch { } elems.delete(firstKey); const [firstPostingsList, remainingAll] = await Promise.all([ - unpackPostingsListAll(firstList), - unpackPostingsListBindings(elems), + unpackPostingsListAll(firstList, polarity), + unpackPostingsListBindings(elems, polarity), ]); /** @type {PostingsList>[]} */ const results = []; @@ -4335,8 +4352,8 @@ class DocSearch { // finally, we can do the actual unification loop const [allInputs, allOutput] = await Promise.all([ - unpackPostingsListAll(inputs), - unpackPostingsListAll(output), + unpackPostingsListAll(inputs, "invertedFunctionInputsIndex"), + unpackPostingsListAll(output, "invertedFunctionOutputIndex"), ]); let checkCounter = 0; /** -- cgit 1.4.1-3-g733a5 From 199d2d4615ffb207ba6a5a4664800e63e6076f21 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 30 Aug 2025 14:06:06 -0400 Subject: Use absolute path to llvm-bolt, merge-fdata rather than PATH This unconditionally uses the provided LLVM toolchain's BOLT. I'm not sure that makes sense, but since we don't build BOLT as part of Rust's build of LLVM today, it's probably the right option for now. This avoids breaking the build on not being able to find the llvm-bolt executable. --- src/tools/opt-dist/src/bolt.rs | 5 +++-- src/tools/opt-dist/src/environment.rs | 8 ++++++++ src/tools/opt-dist/src/main.rs | 4 ++-- src/tools/opt-dist/src/training.rs | 3 ++- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/tools/opt-dist/src/bolt.rs b/src/tools/opt-dist/src/bolt.rs index a06e59fcc41..3ee9912b8c2 100644 --- a/src/tools/opt-dist/src/bolt.rs +++ b/src/tools/opt-dist/src/bolt.rs @@ -9,6 +9,7 @@ use crate::utils::io::copy_file; /// Instruments an artifact at the given `path` (in-place) with BOLT and then calls `func`. /// After this function finishes, the original file will be restored. pub fn with_bolt_instrumented anyhow::Result, R>( + env: &Environment, path: &Utf8Path, func: F, ) -> anyhow::Result { @@ -26,7 +27,7 @@ pub fn with_bolt_instrumented anyhow::Result, R>( let profile_prefix = Utf8Path::from_path(&profile_prefix).unwrap(); // Instrument the original file with BOLT, saving the result into `instrumented_path` - cmd(&["llvm-bolt"]) + cmd(&[env.llvm_bolt().as_str()]) .arg("-instrument") .arg(path) .arg(&format!("--instrumentation-file={profile_prefix}")) @@ -61,7 +62,7 @@ pub fn bolt_optimize( let split_strategy = if env.host_tuple().starts_with("aarch64") { "profile2" } else { "cdsplit" }; - cmd(&["llvm-bolt"]) + cmd(&[env.llvm_bolt().as_str()]) .arg(temp_path.display()) .arg("-data") .arg(&profile.0) diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs index 2cae0785f33..7cc51901a83 100644 --- a/src/tools/opt-dist/src/environment.rs +++ b/src/tools/opt-dist/src/environment.rs @@ -116,6 +116,14 @@ impl Environment { pub fn stage0(&self) -> Utf8PathBuf { self.stage0_root.clone().unwrap_or_else(|| self.build_artifacts().join("stage0")) } + + pub fn llvm_bolt(&self) -> Utf8PathBuf { + self.host_llvm_dir().join(format!("bin/llvm-bolt{}", executable_extension())) + } + + pub fn merge_fdata(&self) -> Utf8PathBuf { + self.host_llvm_dir().join(format!("bin/merge-fdata{}", executable_extension())) + } } /// What is the extension of binary executables on this platform? diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 339c25552ad..48b25f235dd 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -329,7 +329,7 @@ fn execute_pipeline( // FIXME(kobzol): try gather profiles together, at once for LLVM and rustc // Instrument the libraries and gather profiles - let llvm_profile = with_bolt_instrumented(&llvm_lib, |llvm_profile_dir| { + let llvm_profile = with_bolt_instrumented(env, &llvm_lib, |llvm_profile_dir| { stage.section("Gather profiles", |_| { gather_bolt_profiles(env, "LLVM", llvm_benchmarks(env), llvm_profile_dir) }) @@ -354,7 +354,7 @@ fn execute_pipeline( log::info!("Optimizing {rustc_lib} with BOLT"); // Instrument it and gather profiles - let rustc_profile = with_bolt_instrumented(&rustc_lib, |rustc_profile_dir| { + let rustc_profile = with_bolt_instrumented(env, &rustc_lib, |rustc_profile_dir| { stage.section("Gather profiles", |_| { gather_bolt_profiles(env, "rustc", rustc_benchmarks(env), rustc_profile_dir) }) diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs index ae062d5c60c..4f9352d11b1 100644 --- a/src/tools/opt-dist/src/training.rs +++ b/src/tools/opt-dist/src/training.rs @@ -195,7 +195,8 @@ pub fn gather_bolt_profiles( let profiles: Vec<_> = glob::glob(&format!("{profile_prefix}*"))?.collect::, _>>()?; - let mut merge_args = vec!["merge-fdata"]; + let fdata = env.merge_fdata(); + let mut merge_args = vec![fdata.as_str()]; merge_args.extend(profiles.iter().map(|p| p.to_str().unwrap())); with_log_group("Merging BOLT profiles", || { -- cgit 1.4.1-3-g733a5 From 6ef0bfdb5cd874502aeaa7339fbe059b91ed35c3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 30 Aug 2025 12:30:02 -0700 Subject: rustdoc-search: improve concurrency at type search --- src/librustdoc/html/static/js/search.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 2854f65b599..fa812a2b67b 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -4031,7 +4031,11 @@ class DocSearch { return empty_postings_list; } const typeFilter = itemTypeFromName(elem.typeFilter); - const searchResults = await index.search(elem.normalizedPathLast); + const [searchResults, upla, uplb] = await Promise.all([ + index.search(elem.normalizedPathLast), + unpackPostingsListAll(elem.generics, polarity), + unpackPostingsListBindings(elem.bindings, polarity), + ]); /** * @type {Promise<[ * number, @@ -4196,8 +4200,6 @@ class DocSearch { })) { continue; } - const upla = await unpackPostingsListAll(elem.generics, polarity); - const uplb = await unpackPostingsListBindings(elem.bindings, polarity); for (const {invertedIndex: genericsIdx, queryElem: generics} of upla) { for (const {invertedIndex: bindingsIdx, queryElem: bindings} of uplb) { results.push({ @@ -4303,19 +4305,23 @@ class DocSearch { queryElem: new Map(), }]; } - const firstKeyIds = await index.search(firstKey); + // HEADS UP! + // We must put this map back the way we found it before returning, + // otherwise things break. + elems.delete(firstKey); + const [firstKeyIds, firstPostingsList, remainingAll] = await Promise.all([ + index.search(firstKey), + unpackPostingsListAll(firstList, polarity), + unpackPostingsListBindings(elems, polarity), + ]); if (!firstKeyIds) { + elems.set(firstKey, firstList); // User specified a non-existent key. return [{ invertedIndex: empty_inverted_index, queryElem: new Map(), }]; } - elems.delete(firstKey); - const [firstPostingsList, remainingAll] = await Promise.all([ - unpackPostingsListAll(firstList, polarity), - unpackPostingsListBindings(elems, polarity), - ]); /** @type {PostingsList>[]} */ const results = []; for (const keyId of firstKeyIds.matches().entries()) { -- cgit 1.4.1-3-g733a5 From 99583d1aeca1bdc8630e75e2cf6475b8386c711d Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 16:30:02 +0200 Subject: Remove outdated comment --- src/bootstrap/src/core/build_steps/test.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 95be5360b0b..f6a912f3190 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3246,9 +3246,6 @@ impl Step for Distcheck { .map(|args| args.split(" ").map(|s| s.to_string()).collect::>()) .unwrap_or_default(); - // FIXME: unpack the source tarballs into a directory outside the source checkout, to - // ensure that it cannot access any local state - // Also ensure that it doesn't use download-ci-llvm command("tar") .arg("-xf") .arg(plain_src_tarball.tarball()) -- cgit 1.4.1-3-g733a5 From 2bfff320bd7e0714fd70a7d8e4c2081a697180d5 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 20:46:54 +0200 Subject: Add some compiletest suites snapshot tests --- src/bootstrap/src/core/build_steps/test.rs | 13 +-- src/bootstrap/src/core/builder/tests.rs | 155 +++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index f6a912f3190..e61be236c02 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1476,12 +1476,6 @@ macro_rules! test { }), }) } - - fn metadata(&self) -> Option { - Some( - StepMetadata::test(stringify!($name), self.target) - ) - } } }; } @@ -2362,6 +2356,13 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} try_run_tests(builder, &mut cmd, false); } } + + fn metadata(&self) -> Option { + Some( + StepMetadata::test(&format!("compiletest-{}", self.suite), self.target) + .stage(self.compiler.stage), + ) + } } /// Runs the documentation tests for a book in `src/doc` using the `rustdoc` of `test_compiler`. diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 43e67756e74..e6cf34ed499 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2062,20 +2062,23 @@ mod snapshot { [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 [build] rustc 0 -> Compiletest 1 - [test] Ui - [test] Crashes + [test] compiletest-ui 1 + [test] compiletest-crashes 1 [build] rustc 0 -> CoverageDump 1 + [test] compiletest-coverage 1 + [test] compiletest-coverage 1 [build] rustc 1 -> std 1 - [test] CodegenLlvm - [test] CodegenUnits - [test] AssemblyLlvm - [test] Incremental - [test] Debuginfo - [test] UiFullDeps + [test] compiletest-mir-opt 1 + [test] compiletest-codegen-llvm 1 + [test] compiletest-codegen-units 1 + [test] compiletest-assembly-llvm 1 + [test] compiletest-incremental 1 + [test] compiletest-debuginfo 1 + [test] compiletest-ui-fulldeps 1 [build] rustdoc 1 - [test] Rustdoc - [test] CoverageRunRustdoc - [test] Pretty + [test] compiletest-rustdoc 1 + [test] compiletest-coverage-run-rustdoc 1 + [test] compiletest-pretty 1 [build] rustc 1 -> std 1 [build] rustc 0 -> std 0 [test] rustc 0 -> CrateLibrustc 1 @@ -2113,16 +2116,107 @@ mod snapshot { [test] rustc 0 -> rust-analyzer 1 [build] rustc 0 -> RustdocTheme 1 [test] rustdoc-theme 1 - [test] RustdocUi + [test] compiletest-rustdoc-ui 1 [build] rustc 0 -> JsonDocCk 1 [build] rustc 0 -> JsonDocLint 1 - [test] RustdocJson + [test] compiletest-rustdoc-json 1 [doc] rustc 0 -> rustc 1 [build] rustc 0 -> HtmlChecker 1 [test] html-check [build] rustc 0 -> RunMakeSupport 1 [build] rustc 1 -> cargo 2 - [test] RunMake + [test] compiletest-run-make 1 + "); + } + + #[test] + fn test_compiletest_suites_stage1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .args(&["ui", "ui-fulldeps", "run-make", "rustdoc", "rustdoc-gui", "incremental"]) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 0 -> Compiletest 1 + [test] compiletest-ui 1 + [test] compiletest-ui-fulldeps 1 + [build] rustc 0 -> RunMakeSupport 1 + [build] rustc 1 -> cargo 2 + [build] rustdoc 1 + [test] compiletest-run-make 1 + [test] compiletest-rustdoc 1 + [build] rustc 0 -> RustdocGUITest 1 + [test] rustdoc-gui 1 + [test] compiletest-incremental 1 + [build] rustc 1 -> rustc 2 + "); + } + + #[test] + fn test_compiletest_suites_stage2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .args(&["ui", "ui-fulldeps", "run-make", "rustdoc", "rustdoc-gui", "incremental"]) + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 2 -> std 2 + [build] rustc 0 -> Compiletest 1 + [test] compiletest-ui 2 + [build] rustc 2 -> rustc 3 + [test] compiletest-ui-fulldeps 2 + [build] rustc 0 -> RunMakeSupport 1 + [build] rustc 2 -> cargo 3 + [build] rustdoc 2 + [test] compiletest-run-make 2 + [test] compiletest-rustdoc 2 + [build] rustc 0 -> RustdocGUITest 1 + [test] rustdoc-gui 2 + [test] compiletest-incremental 2 + [build] rustdoc 1 + "); + } + + #[test] + fn test_compiletest_suites_stage2_cross() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("test") + .hosts(&[TEST_TRIPLE_1]) + .targets(&[TEST_TRIPLE_1]) + .args(&["ui", "ui-fulldeps", "run-make", "rustdoc", "rustdoc-gui", "incremental"]) + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 2 -> std 2 + [build] rustc 0 -> Compiletest 1 + [build] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [test] compiletest-ui 2 + [build] llvm + [build] rustc 2 -> rustc 3 + [test] compiletest-ui-fulldeps 2 + [build] rustc 0 -> RunMakeSupport 1 + [build] rustc 2 -> cargo 3 + [build] rustdoc 2 + [test] compiletest-run-make 2 + [test] compiletest-rustdoc 2 + [build] rustc 0 -> RustdocGUITest 1 + [test] rustdoc-gui 2 + [test] compiletest-incremental 2 + [build] rustc 1 -> rustc 2 + [build] rustdoc 1 + [build] rustc 2 -> std 2 + [build] rustdoc 2 "); } @@ -2142,21 +2236,24 @@ mod snapshot { [build] rustc 1 -> rustc 2 [build] rustc 2 -> std 2 [build] rustc 0 -> Compiletest 1 - [test] Ui - [test] Crashes + [test] compiletest-ui 2 + [test] compiletest-crashes 2 [build] rustc 0 -> CoverageDump 1 + [test] compiletest-coverage 2 + [test] compiletest-coverage 2 [build] rustc 2 -> std 2 - [test] CodegenLlvm - [test] CodegenUnits - [test] AssemblyLlvm - [test] Incremental - [test] Debuginfo + [test] compiletest-mir-opt 2 + [test] compiletest-codegen-llvm 2 + [test] compiletest-codegen-units 2 + [test] compiletest-assembly-llvm 2 + [test] compiletest-incremental 2 + [test] compiletest-debuginfo 2 [build] rustc 2 -> rustc 3 - [test] UiFullDeps + [test] compiletest-ui-fulldeps 2 [build] rustdoc 2 - [test] Rustdoc - [test] CoverageRunRustdoc - [test] Pretty + [test] compiletest-rustdoc 2 + [test] compiletest-coverage-run-rustdoc 2 + [test] compiletest-pretty 2 [build] rustc 2 -> std 2 [build] rustc 1 -> std 1 [build] rustdoc 1 @@ -2196,16 +2293,16 @@ mod snapshot { [test] rustc 1 -> lint-docs 2 [build] rustc 0 -> RustdocTheme 1 [test] rustdoc-theme 2 - [test] RustdocUi + [test] compiletest-rustdoc-ui 2 [build] rustc 0 -> JsonDocCk 1 [build] rustc 0 -> JsonDocLint 1 - [test] RustdocJson + [test] compiletest-rustdoc-json 2 [doc] rustc 1 -> rustc 2 [build] rustc 0 -> HtmlChecker 1 [test] html-check [build] rustc 0 -> RunMakeSupport 1 [build] rustc 2 -> cargo 3 - [test] RunMake + [test] compiletest-run-make 2 "); } @@ -2249,7 +2346,7 @@ mod snapshot { let steps = ctx.config("test").args(&["--skip", "src/tools/tidy"]).get_steps(); let host = TargetSelection::from_user(&host_target()); - steps.assert_contains(StepMetadata::test("RustdocUi", host)); + steps.assert_contains(StepMetadata::test("compiletest-rustdoc-ui", host).stage(1)); steps.assert_not_contains(test::Tidy); } -- cgit 1.4.1-3-g733a5 From 72167b726c49776b01cd84552ed90761a839ee7b Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 20:39:08 +0200 Subject: Rename `compiler` to `test_compiler` --- src/bootstrap/src/core/build_steps/test.rs | 101 +++++++++++++++-------------- 1 file changed, 54 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index e61be236c02..295ebfc3638 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1079,7 +1079,7 @@ impl Step for RustdocJSNotStd { fn run(self, builder: &Builder<'_>) { builder.ensure(Compiletest { - compiler: self.compiler, + test_compiler: self.compiler, target: self.target, mode: "rustdoc-js", suite: "rustdoc-js", @@ -1437,8 +1437,8 @@ macro_rules! test { $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { - pub compiler: Compiler, - pub target: TargetSelection, + test_compiler: Compiler, + target: TargetSelection, } impl Step for $name { @@ -1456,14 +1456,14 @@ macro_rules! test { } fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); + let test_compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - run.builder.ensure($name { compiler, target: run.target }); + run.builder.ensure($name { test_compiler, target: run.target }); } fn run(self, builder: &Builder<'_>) { builder.ensure(Compiletest { - compiler: self.compiler, + test_compiler: self.test_compiler, target: self.target, mode: $mode, suite: $suite, @@ -1644,7 +1644,7 @@ impl Step for Coverage { // Like other compiletest suite test steps, delegate to an internal // compiletest task to actually run the tests. builder.ensure(Compiletest { - compiler, + test_compiler: compiler, target, mode, suite: Self::SUITE, @@ -1685,7 +1685,7 @@ impl Step for MirOpt { fn run(self, builder: &Builder<'_>) { let run = |target| { builder.ensure(Compiletest { - compiler: self.compiler, + test_compiler: self.compiler, target, mode: "mir-opt", suite: "mir-opt", @@ -1720,9 +1720,15 @@ impl Step for MirOpt { } } +/// Executes the `compiletest` tool to run a suite of tests. +/// +/// Compiles all tests with `test_compiler` for `target` with the specified +/// compiletest `mode` and `suite` arguments. For example `mode` can be +/// "run-pass" or `suite` can be something like `debuginfo`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] struct Compiletest { - compiler: Compiler, + /// The compiler that we're testing. + test_compiler: Compiler, target: TargetSelection, mode: &'static str, suite: &'static str, @@ -1737,11 +1743,6 @@ impl Step for Compiletest { run.never() } - /// Executes the `compiletest` tool to run a suite of tests. - /// - /// Compiles all tests with `compiler` for `target` with the specified - /// compiletest `mode` and `suite` arguments. For example `mode` can be - /// "run-pass" or `suite` can be something like `debuginfo`. fn run(self, builder: &Builder<'_>) { if builder.doc_tests == DocTests::Only { return; @@ -1756,7 +1757,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the crate::exit!(1); } - let mut compiler = self.compiler; + let mut test_compiler = self.test_compiler; let target = self.target; let mode = self.mode; let suite = self.suite; @@ -1776,30 +1777,30 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the // running compiler in stage 2 when plugins run. let query_compiler; - let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 { + let (stage, stage_id) = if suite == "ui-fulldeps" && test_compiler.stage == 1 { // Even when using the stage 0 compiler, we also need to provide the stage 1 compiler // so that compiletest can query it for target information. - query_compiler = Some(compiler); + query_compiler = Some(test_compiler); // At stage 0 (stage - 1) we are using the stage0 compiler. Using `self.target` can lead // finding an incorrect compiler path on cross-targets, as the stage 0 is always equal to // `build.build` in the configuration. let build = builder.build.host_target; - compiler = builder.compiler(compiler.stage - 1, build); - let test_stage = compiler.stage + 1; + test_compiler = builder.compiler(test_compiler.stage - 1, build); + let test_stage = test_compiler.stage + 1; (test_stage, format!("stage{test_stage}-{build}")) } else { query_compiler = None; - let stage = compiler.stage; + let stage = test_compiler.stage; (stage, format!("stage{stage}-{target}")) }; if suite.ends_with("fulldeps") { - builder.ensure(compile::Rustc::new(compiler, target)); + builder.ensure(compile::Rustc::new(test_compiler, target)); } if suite == "debuginfo" { builder.ensure(dist::DebuggerScripts { - sysroot: builder.sysroot(compiler).to_path_buf(), + sysroot: builder.sysroot(test_compiler).to_path_buf(), target, }); } @@ -1809,20 +1810,22 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // ensure that `libproc_macro` is available on the host. if suite == "mir-opt" { - builder.ensure(compile::Std::new(compiler, compiler.host).is_for_mir_opt_tests(true)); + builder.ensure( + compile::Std::new(test_compiler, test_compiler.host).is_for_mir_opt_tests(true), + ); } else { - builder.std(compiler, compiler.host); + builder.std(test_compiler, test_compiler.host); } let mut cmd = builder.tool_cmd(Tool::Compiletest); if suite == "mir-opt" { - builder.ensure(compile::Std::new(compiler, target).is_for_mir_opt_tests(true)); + builder.ensure(compile::Std::new(test_compiler, target).is_for_mir_opt_tests(true)); } else { - builder.std(compiler, target); + builder.std(test_compiler, target); } - builder.ensure(RemoteCopyLibs { build_compiler: compiler, target }); + builder.ensure(RemoteCopyLibs { build_compiler: test_compiler, target }); // compiletest currently has... a lot of arguments, so let's just pass all // of them! @@ -1830,9 +1833,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--stage").arg(stage.to_string()); cmd.arg("--stage-id").arg(stage_id); - cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler)); - cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(compiler, target)); - cmd.arg("--rustc-path").arg(builder.rustc(compiler)); + cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(test_compiler)); + cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(test_compiler, target)); + cmd.arg("--rustc-path").arg(builder.rustc(test_compiler)); if let Some(query_compiler) = query_compiler { cmd.arg("--query-rustc-path").arg(builder.rustc(query_compiler)); } @@ -1849,14 +1852,16 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // If we're using `--stage 0`, we should provide the bootstrap cargo. builder.initial_cargo.clone() } else { - builder.ensure(tool::Cargo::from_build_compiler(compiler, compiler.host)).tool_path + builder + .ensure(tool::Cargo::from_build_compiler(test_compiler, test_compiler.host)) + .tool_path }; cmd.arg("--cargo-path").arg(cargo_path); // We need to pass the compiler that was used to compile run-make-support, // because we have to use the same compiler to compile rmake.rs recipes. - let stage0_rustc_path = builder.compiler(0, compiler.host); + let stage0_rustc_path = builder.compiler(0, test_compiler.host); cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path)); } @@ -1868,7 +1873,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the || mode == "rustdoc-json" || suite == "coverage-run-rustdoc" { - cmd.arg("--rustdoc-path").arg(builder.rustdoc_for_compiler(compiler)); + cmd.arg("--rustdoc-path").arg(builder.rustdoc_for_compiler(test_compiler)); } if mode == "rustdoc-json" { @@ -1893,14 +1898,14 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // directory immediately under the root build directory, and the test-suite-specific build // directory. cmd.arg("--build-root").arg(&builder.out); - cmd.arg("--build-test-suite-root").arg(testdir(builder, compiler.host).join(suite)); + cmd.arg("--build-test-suite-root").arg(testdir(builder, test_compiler.host).join(suite)); // When top stage is 0, that means that we're testing an externally provided compiler. // In that case we need to use its specific sysroot for tests to pass. let sysroot = if builder.top_stage == 0 { builder.initial_sysroot.clone() } else { - builder.sysroot(compiler) + builder.sysroot(test_compiler) }; cmd.arg("--sysroot-base").arg(sysroot); @@ -1908,11 +1913,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--suite").arg(suite); cmd.arg("--mode").arg(mode); cmd.arg("--target").arg(target.rustc_target_arg()); - cmd.arg("--host").arg(&*compiler.host.triple); + cmd.arg("--host").arg(&*test_compiler.host.triple); cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target)); if let Some(codegen_backend) = builder.config.cmd.test_codegen_backend() { - if !builder.config.enabled_codegen_backends(compiler.host).contains(codegen_backend) { + if !builder.config.enabled_codegen_backends(test_compiler.host).contains(codegen_backend) { eprintln!( "\ ERROR: No configured backend named `{name}` @@ -1931,7 +1936,7 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} // Tells compiletest which codegen backend to use. // It is used to e.g. ignore tests that don't support that codegen backend. cmd.arg("--default-codegen-backend") - .arg(builder.config.default_codegen_backend(compiler.host).name()); + .arg(builder.config.default_codegen_backend(test_compiler.host).name()); } if builder.build.config.llvm_enzyme { @@ -2011,7 +2016,7 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} if let Some(linker) = builder.linker(target) { cmd.arg("--target-linker").arg(linker); } - if let Some(linker) = builder.linker(compiler.host) { + if let Some(linker) = builder.linker(test_compiler.host) { cmd.arg("--host-linker").arg(linker); } } @@ -2022,16 +2027,18 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} } let mut hostflags = flags.clone(); - hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No)); + hostflags.extend(linker_flags(builder, test_compiler.host, LldThreads::No)); let mut targetflags = flags; // Provide `rust_test_helpers` for both host and target. if suite == "ui" || suite == "incremental" { - builder.ensure(TestHelpers { target: compiler.host }); + builder.ensure(TestHelpers { target: test_compiler.host }); builder.ensure(TestHelpers { target }); - hostflags - .push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); + hostflags.push(format!( + "-Lnative={}", + builder.test_helpers_out(test_compiler.host).display() + )); targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); } @@ -2116,7 +2123,7 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} let mut llvm_components_passed = false; let mut copts_passed = false; - if builder.config.llvm_enabled(compiler.host) { + if builder.config.llvm_enabled(test_compiler.host) { let llvm::LlvmResult { host_llvm_config, .. } = builder.ensure(llvm::Llvm { target: builder.config.host_target }); if !builder.config.dry_run() { @@ -2327,7 +2334,7 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} format!("compiletest suite={suite} mode={mode}"), // FIXME: compiletest sometimes behaves as ToolStd, we could expose that difference here Mode::ToolBootstrap, - compiler, + test_compiler, target, ); try_run_tests(builder, &mut cmd, false); @@ -2350,7 +2357,7 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} builder.info(&format!( "Check compiletest suite={} mode={} compare_mode={} ({} -> {})", - suite, mode, compare_mode, &compiler.host, target + suite, mode, compare_mode, &test_compiler.host, target )); let _time = helpers::timeit(builder); try_run_tests(builder, &mut cmd, false); @@ -2360,7 +2367,7 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} fn metadata(&self) -> Option { Some( StepMetadata::test(&format!("compiletest-{}", self.suite), self.target) - .stage(self.compiler.stage), + .stage(self.test_compiler.stage), ) } } -- cgit 1.4.1-3-g733a5 From 8e97112ba83c97891bcaafa13f099bd22ccd29f8 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 20:39:15 +0200 Subject: Remove `Compiler::with_stage` --- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/lib.rs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 295ebfc3638..3938c640321 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1878,7 +1878,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the if mode == "rustdoc-json" { // Use the stage0 compiler for jsondocck - let json_compiler = compiler.with_stage(0); + let json_compiler = builder.compiler(0, builder.host_target); cmd.arg("--jsondocck-path") .arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target }).tool_path); cmd.arg("--jsondoclint-path").arg( diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 9a882eae08e..2108f3b8cf5 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -2109,11 +2109,6 @@ impl Compiler { self.forced_compiler = forced_compiler; } - pub fn with_stage(mut self, stage: u32) -> Compiler { - self.stage = stage; - self - } - /// Returns `true` if this is a snapshot compiler for `build`'s configuration pub fn is_snapshot(&self, build: &Build) -> bool { self.stage == 0 && self.host == build.host_target -- cgit 1.4.1-3-g733a5 From 6c3a86b73b6ce93f392768f5cdc9da9bd6283b32 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Wed, 20 Aug 2025 20:42:08 +0200 Subject: Do not run `lint-docs` tests in stage 1 `x test` by default --- src/bootstrap/src/core/build_steps/test.rs | 9 ++++++--- src/bootstrap/src/core/builder/tests.rs | 10 +++++----- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 3938c640321..97db9bf536f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1848,12 +1848,15 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let is_rustdoc = suite == "rustdoc-ui" || suite == "rustdoc-js"; if mode == "run-make" { - let cargo_path = if builder.top_stage == 0 { + let cargo_path = if test_compiler.stage == 0 { // If we're using `--stage 0`, we should provide the bootstrap cargo. builder.initial_cargo.clone() } else { builder - .ensure(tool::Cargo::from_build_compiler(test_compiler, test_compiler.host)) + .ensure(tool::Cargo::from_build_compiler( + builder.compiler(test_compiler.stage - 1, test_compiler.host), + test_compiler.host, + )) .tool_path }; @@ -1902,7 +1905,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // When top stage is 0, that means that we're testing an externally provided compiler. // In that case we need to use its specific sysroot for tests to pass. - let sysroot = if builder.top_stage == 0 { + let sysroot = if test_compiler.stage == 0 { builder.initial_sysroot.clone() } else { builder.sysroot(test_compiler) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index e6cf34ed499..ef01f14f5e9 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2124,7 +2124,7 @@ mod snapshot { [build] rustc 0 -> HtmlChecker 1 [test] html-check [build] rustc 0 -> RunMakeSupport 1 - [build] rustc 1 -> cargo 2 + [build] rustc 0 -> cargo 1 [test] compiletest-run-make 1 "); } @@ -2143,7 +2143,7 @@ mod snapshot { [test] compiletest-ui 1 [test] compiletest-ui-fulldeps 1 [build] rustc 0 -> RunMakeSupport 1 - [build] rustc 1 -> cargo 2 + [build] rustc 0 -> cargo 1 [build] rustdoc 1 [test] compiletest-run-make 1 [test] compiletest-rustdoc 1 @@ -2172,7 +2172,7 @@ mod snapshot { [build] rustc 2 -> rustc 3 [test] compiletest-ui-fulldeps 2 [build] rustc 0 -> RunMakeSupport 1 - [build] rustc 2 -> cargo 3 + [build] rustc 1 -> cargo 2 [build] rustdoc 2 [test] compiletest-run-make 2 [test] compiletest-rustdoc 2 @@ -2206,7 +2206,7 @@ mod snapshot { [build] rustc 2 -> rustc 3 [test] compiletest-ui-fulldeps 2 [build] rustc 0 -> RunMakeSupport 1 - [build] rustc 2 -> cargo 3 + [build] rustc 1 -> cargo 2 [build] rustdoc 2 [test] compiletest-run-make 2 [test] compiletest-rustdoc 2 @@ -2301,7 +2301,7 @@ mod snapshot { [build] rustc 0 -> HtmlChecker 1 [test] html-check [build] rustc 0 -> RunMakeSupport 1 - [build] rustc 2 -> cargo 3 + [build] rustc 1 -> cargo 2 [test] compiletest-run-make 2 "); } -- cgit 1.4.1-3-g733a5 From 6f5fc69c7ebca3e48073ba81fdd3c3ccfe1f2bf5 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Mon, 1 Sep 2025 09:14:27 +0200 Subject: Consolidate staging of test steps in message groups --- src/bootstrap/src/core/build_steps/test.rs | 163 ++++++++++------------------- src/bootstrap/src/lib.rs | 58 +++++----- 2 files changed, 88 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 97db9bf536f..cdcbe29795d 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -96,7 +96,7 @@ impl Step for CrateBootstrap { ); let crate_name = path.rsplit_once('/').unwrap().1; - run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder, Mode::ToolBootstrap); + run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder); } fn metadata(&self) -> Option { @@ -153,15 +153,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" SourceType::InTree, &[], ); - run_cargo_test( - cargo, - &[], - &[], - "linkchecker self tests", - bootstrap_host, - builder, - Mode::ToolBootstrap, - ); + run_cargo_test(cargo, &[], &[], "linkchecker self tests", bootstrap_host, builder); if builder.doc_tests == DocTests::No { return; @@ -174,7 +166,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" let linkchecker = builder.tool_cmd(Tool::Linkchecker); // Run the linkchecker. - let _guard = builder.msg(Kind::Test, "Linkcheck", None, compiler, bootstrap_host); + let _guard = builder.msg_test("Linkcheck", bootstrap_host, 1); let _time = helpers::timeit(builder); linkchecker.delay_failure().arg(builder.out.join(host).join("doc")).run(builder); } @@ -482,7 +474,7 @@ impl Step for RustAnalyzer { cargo.env("SKIP_SLOW_TESTS", "1"); cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder, Mode::ToolRustc); + run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder); } fn metadata(&self) -> Option { @@ -540,7 +532,7 @@ impl Step for Rustfmt { cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rustfmt", target, builder, Mode::ToolRustc); + run_cargo_test(cargo, &[], &[], "rustfmt", target, builder); } fn metadata(&self) -> Option { @@ -679,8 +671,7 @@ impl Step for Miri { cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg()); { - let _guard = - builder.msg(Kind::Test, "miri", Mode::ToolRustc, miri.build_compiler, target); + let _guard = builder.msg_test("miri", target, target_compiler.stage); let _time = helpers::timeit(builder); cargo.run(builder); } @@ -696,13 +687,8 @@ impl Step for Miri { cargo.args(["tests/pass", "tests/panic"]); { - let _guard = builder.msg( - Kind::Test, - "miri (mir-opt-level 4)", - Mode::ToolRustc, - miri.build_compiler, - target, - ); + let _guard = + builder.msg_test("miri (mir-opt-level 4)", target, target_compiler.stage); let _time = helpers::timeit(builder); cargo.run(builder); } @@ -772,8 +758,7 @@ impl Step for CargoMiri { // Finally, run everything. let mut cargo = BootstrapCommand::from(cargo); { - let _guard = - builder.msg(Kind::Test, "cargo-miri", Mode::ToolRustc, (host, stage), target); + let _guard = builder.msg_test("cargo-miri", target, stage); let _time = helpers::timeit(builder); cargo.run(builder); } @@ -833,7 +818,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cargo.env("TEST_RUSTC", builder.rustc(compiler)); cargo.allow_features(COMPILETEST_ALLOW_FEATURES); - run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder, Mode::ToolStd); + run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder); } } @@ -916,7 +901,7 @@ impl Step for Clippy { cargo.add_rustc_lib_path(builder); let cargo = prepare_cargo_test(cargo, &[], &[], target, builder); - let _guard = builder.msg(Kind::Test, "clippy", Mode::ToolRustc, build_compiler, target); + let _guard = builder.msg_test("clippy", target, target_compiler.stage); // Clippy reports errors if it blessed the outputs if cargo.allow_failure().run(builder) { @@ -1046,8 +1031,7 @@ impl Step for RustdocJSStd { self.target, DocumentationFormat::Html, )); - let _guard = - builder.msg(Kind::Test, "rustdoc-js-std", None, self.build_compiler, self.target); + let _guard = builder.msg_test("rustdoc-js-std", self.target, self.build_compiler.stage); command.run(builder); } @@ -1200,7 +1184,7 @@ impl Step for RustdocGUI { } let _time = helpers::timeit(builder); - let _guard = builder.msg_test("rustdoc-gui", (self.target, self.test_compiler.stage)); + let _guard = builder.msg_test("rustdoc-gui", self.target, self.test_compiler.stage); try_run_tests(builder, &mut cmd, true); } @@ -1359,15 +1343,7 @@ impl Step for CrateRunMakeSupport { &[], ); cargo.allow_features("test"); - run_cargo_test( - cargo, - &[], - &[], - "run-make-support self test", - host, - builder, - Mode::ToolBootstrap, - ); + run_cargo_test(cargo, &[], &[], "run-make-support self test", host, builder); } } @@ -1404,15 +1380,7 @@ impl Step for CrateBuildHelper { &[], ); cargo.allow_features("test"); - run_cargo_test( - cargo, - &[], - &[], - "build_helper self test", - host, - builder, - Mode::ToolBootstrap, - ); + run_cargo_test(cargo, &[], &[], "build_helper self test", host, builder); } } @@ -1724,7 +1692,7 @@ impl Step for MirOpt { /// /// Compiles all tests with `test_compiler` for `target` with the specified /// compiletest `mode` and `suite` arguments. For example `mode` can be -/// "run-pass" or `suite` can be something like `debuginfo`. +/// "mir-opt" and `suite` can be something like "debuginfo". #[derive(Debug, Clone, PartialEq, Eq, Hash)] struct Compiletest { /// The compiler that we're testing. @@ -1920,7 +1888,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target)); if let Some(codegen_backend) = builder.config.cmd.test_codegen_backend() { - if !builder.config.enabled_codegen_backends(test_compiler.host).contains(codegen_backend) { + if !builder + .config + .enabled_codegen_backends(test_compiler.host) + .contains(codegen_backend) + { eprintln!( "\ ERROR: No configured backend named `{name}` @@ -2326,19 +2298,16 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} mode: mode.into(), compare_mode: None, target: self.target.triple.to_string(), - host: self.compiler.host.triple.to_string(), - stage: self.compiler.stage, + host: self.test_compiler.host.triple.to_string(), + stage: self.test_compiler.stage, }, builder, ); - let _group = builder.msg( - Kind::Test, - format!("compiletest suite={suite} mode={mode}"), - // FIXME: compiletest sometimes behaves as ToolStd, we could expose that difference here - Mode::ToolBootstrap, - test_compiler, + let _group = builder.msg_test( + format!("with compiletest suite={suite} mode={mode}"), target, + test_compiler.stage, ); try_run_tests(builder, &mut cmd, false); @@ -2352,8 +2321,8 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?} mode: mode.into(), compare_mode: Some(compare_mode.into()), target: self.target.triple.to_string(), - host: self.compiler.host.triple.to_string(), - stage: self.compiler.stage, + host: self.test_compiler.host.triple.to_string(), + stage: self.test_compiler.stage, }, builder, ); @@ -2482,12 +2451,10 @@ impl BookTest { } builder.add_rust_test_threads(&mut rustbook_cmd); - let _guard = builder.msg( - Kind::Test, + let _guard = builder.msg_test( format_args!("mdbook {}", self.path.display()), - None, - test_compiler, test_compiler.host, + test_compiler.stage, ); let _time = helpers::timeit(builder); let toolstate = if rustbook_cmd.delay_failure().run(builder) { @@ -2505,12 +2472,10 @@ impl BookTest { builder.std(test_compiler, host); - let _guard = builder.msg( - Kind::Test, + let _guard = builder.msg_test( format!("book {}", self.name), - None, - (test_compiler.host, test_compiler.stage - 1), - host, + test_compiler.host, + test_compiler.stage, ); // Do a breadth-first traversal of the `src/doc` directory and just run @@ -2653,13 +2618,7 @@ impl Step for ErrorIndex { let mut tool = tool::ErrorIndex::command(builder, self.compilers); tool.arg("markdown").arg(&output); - let guard = builder.msg( - Kind::Test, - "error-index", - None, - self.compilers.build_compiler(), - target_compiler.host, - ); + let guard = builder.msg_test("error-index", target_compiler.host, target_compiler.stage); let _time = helpers::timeit(builder); tool.run_capture(builder); drop(guard); @@ -2755,14 +2714,12 @@ fn run_cargo_test<'a>( description: impl Into>, target: TargetSelection, builder: &Builder<'_>, - mode: impl Into>, ) -> bool { - let mode = mode.into(); let compiler = cargo.compiler(); let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder); let _time = helpers::timeit(builder); let _group = - description.into().and_then(|what| builder.msg(Kind::Test, what, mode, compiler, target)); + description.into().and_then(|what| builder.msg_test(what, target, compiler.stage + 1)); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( @@ -2989,15 +2946,7 @@ impl Step for Crate { crates.push("alloctests".to_owned()); } - run_cargo_test( - cargo, - &[], - &crates, - &*crate_description(&self.crates), - target, - builder, - mode, - ); + run_cargo_test(cargo, &[], &crates, &*crate_description(&self.crates), target, builder); } } @@ -3091,15 +3040,7 @@ impl Step for CrateRustdoc { dylib_path.insert(0, PathBuf::from(&*libdir)); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); - run_cargo_test( - cargo, - &[], - &["rustdoc:0.0.0".to_string()], - "rustdoc", - target, - builder, - Mode::ToolRustc, - ); + run_cargo_test(cargo, &[], &["rustdoc:0.0.0".to_string()], "rustdoc", target, builder); } } @@ -3158,7 +3099,6 @@ impl Step for CrateRustdocJsonTypes { "rustdoc-json-types", target, builder, - Mode::ToolTarget, ); } } @@ -3316,8 +3256,6 @@ impl Step for Bootstrap { fn run(self, builder: &Builder<'_>) { let host = builder.config.host_target; let build_compiler = builder.compiler(0, host); - let _guard = - builder.msg(Kind::Test, "bootstrap", Mode::ToolBootstrap, build_compiler, host); // Some tests require cargo submodule to be present. builder.build.require_submodule("src/tools/cargo", None); @@ -3356,7 +3294,7 @@ impl Step for Bootstrap { // bootstrap tests are racy on directory creation so just run them one at a time. // Since there's not many this shouldn't be a problem. - run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder, Mode::ToolBootstrap); + run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -3416,7 +3354,11 @@ impl Step for TierCheck { cargo.arg("--verbose"); } - let _guard = builder.msg_test("platform support check", self.test_compiler); + let _guard = builder.msg_test( + "platform support check", + self.test_compiler.host, + self.test_compiler.stage, + ); BootstrapCommand::from(cargo).delay_failure().run(builder); } @@ -3495,9 +3437,8 @@ impl Step for RustInstaller { &[], ); - let _guard = - builder.msg(Kind::Test, "rust-installer", None, build_compiler, bootstrap_host); - run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder, Mode::ToolBootstrap); + let _guard = builder.msg_test("rust-installer", bootstrap_host, 1); + run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder); // We currently don't support running the test.sh script outside linux(?) environments. // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a @@ -3668,7 +3609,11 @@ impl Step for CodegenCranelift { // Avoid incremental cache issues when changing rustc cargo.env("CARGO_BUILD_INCREMENTAL", "false"); - let _guard = builder.msg_test("rustc_codegen_cranelift", target_compiler); + let _guard = builder.msg_test( + "rustc_codegen_cranelift", + target_compiler.host, + target_compiler.stage, + ); // FIXME handle vendoring for source tarballs before removing the --skip-test below let download_dir = builder.out.join("cg_clif_download"); @@ -3763,7 +3708,11 @@ impl Step for CodegenGCC { .extra_rust_args(&["-Csymbol-mangling-version=v0", "-Cpanic=abort"]), ); - let _guard = builder.msg_test("rustc_codegen_gcc", compilers.build_compiler()); + let _guard = builder.msg_test( + "rustc_codegen_gcc", + compilers.target(), + compilers.target_compiler().stage, + ); let mut cargo = builder::Cargo::new( builder, @@ -3868,7 +3817,7 @@ impl Step for TestFloatParse { ); cargo_test.allow_features(TEST_FLOAT_PARSE_ALLOW_FEATURES); - run_cargo_test(cargo_test, &[], &[], "test-float-parse", target, builder, Mode::ToolStd); + run_cargo_test(cargo_test, &[], &[], "test-float-parse", target, builder); // Run the actual parse tests. let mut cargo_run = tool::prepare_tool_cargo( diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 2108f3b8cf5..59c0f9faaca 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -426,22 +426,22 @@ forward! { download_rustc() -> bool, } -/// A mostly temporary helper struct before we can migrate everything in bootstrap to use -/// the concept of a build compiler. -struct HostAndStage { - host: TargetSelection, +/// An alternative way of specifying what target and stage is involved in some bootstrap activity. +/// Ideally using a `Compiler` directly should be preferred. +struct TargetAndStage { + target: TargetSelection, stage: u32, } -impl From<(TargetSelection, u32)> for HostAndStage { - fn from((host, stage): (TargetSelection, u32)) -> Self { - Self { host, stage } +impl From<(TargetSelection, u32)> for TargetAndStage { + fn from((target, stage): (TargetSelection, u32)) -> Self { + Self { target, stage } } } -impl From for HostAndStage { +impl From for TargetAndStage { fn from(compiler: Compiler) -> Self { - Self { host: compiler.host, stage: compiler.stage } + Self { target: compiler.host, stage: compiler.stage } } } @@ -1109,11 +1109,12 @@ impl Build { /// Return a `Group` guard for a [`Step`] that: /// - Performs `action` + /// - If the action is `Kind::Test`, use [`Build::msg_test`] instead. /// - On `what` /// - Where `what` possibly corresponds to a `mode` - /// - `action` is performed using the given build compiler (`host_and_stage`). - /// - Since some steps do not use the concept of a build compiler yet, it is also possible - /// to pass the host and stage explicitly. + /// - `action` is performed with/on the given compiler (`target_and_stage`). + /// - Since for some steps it is not possible to pass a single compiler here, it is also + /// possible to pass the host and stage explicitly. /// - With a given `target`. /// /// [`Step`]: crate::core::builder::Step @@ -1124,13 +1125,19 @@ impl Build { action: impl Into, what: impl Display, mode: impl Into>, - host_and_stage: impl Into, + target_and_stage: impl Into, target: impl Into>, ) -> Option { - let host_and_stage = host_and_stage.into(); + let target_and_stage = target_and_stage.into(); + let action = action.into(); + assert!( + action != Kind::Test, + "Please use `Build::msg_test` instead of `Build::msg(Kind::Test)`" + ); + let actual_stage = match mode.into() { // Std has the same stage as the compiler that builds it - Some(Mode::Std) => host_and_stage.stage, + Some(Mode::Std) => target_and_stage.stage, // Other things have stage corresponding to their build compiler + 1 Some( Mode::Rustc @@ -1140,18 +1147,18 @@ impl Build { | Mode::ToolStd | Mode::ToolRustc, ) - | None => host_and_stage.stage + 1, + | None => target_and_stage.stage + 1, }; - let action = action.into().description(); + let action = action.description(); let what = what.to_string(); let msg = |fmt| { let space = if !what.is_empty() { " " } else { "" }; format!("{action} stage{actual_stage} {what}{space}{fmt}") }; let msg = if let Some(target) = target.into() { - let build_stage = host_and_stage.stage; - let host = host_and_stage.host; + let build_stage = target_and_stage.stage; + let host = target_and_stage.target; if host == target { msg(format_args!("(stage{build_stage} -> stage{actual_stage}, {target})")) } else { @@ -1163,10 +1170,9 @@ impl Build { self.group(&msg) } - /// Return a `Group` guard for a [`Step`] that tests `what` with the given `stage` and `target` - /// (determined by `host_and_stage`). - /// Use this instead of [`Build::msg`] when there is no clear `build_compiler` to be - /// determined. + /// Return a `Group` guard for a [`Step`] that tests `what` with the given `stage` and `target`. + /// Use this instead of [`Build::msg`] for test steps, because for them it is not always clear + /// what exactly is a build compiler. /// /// [`Step`]: crate::core::builder::Step #[must_use = "Groups should not be dropped until the Step finishes running"] @@ -1174,11 +1180,11 @@ impl Build { fn msg_test( &self, what: impl Display, - host_and_stage: impl Into, + target: TargetSelection, + stage: u32, ) -> Option { - let HostAndStage { host, stage } = host_and_stage.into(); let action = Kind::Test.description(); - let msg = format!("{action} stage{stage} {what} ({host})"); + let msg = format!("{action} stage{stage} {what} ({target})"); self.group(&msg) } -- cgit 1.4.1-3-g733a5 From af627f557ad4806e1de1b4800fd1a7e5a42420a8 Mon Sep 17 00:00:00 2001 From: Jakub Beránek Date: Mon, 1 Sep 2025 18:39:44 +0200 Subject: Fix ui-fulldeps --- src/bootstrap/src/core/build_steps/test.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index cdcbe29795d..ee2cbe9385e 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1873,7 +1873,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // When top stage is 0, that means that we're testing an externally provided compiler. // In that case we need to use its specific sysroot for tests to pass. - let sysroot = if test_compiler.stage == 0 { + // Note: DO NOT check if test_compiler.stage is 0, because the test compiler can be stage 0 + // even if the top stage is 1 (when we run the ui-fulldeps suite). + let sysroot = if builder.top_stage == 0 { builder.initial_sysroot.clone() } else { builder.sysroot(test_compiler) -- cgit 1.4.1-3-g733a5