Auto merge of #145663 - Kobzol:bootstrap-test, r=jieyouxu
Enforce in bootstrap that test must have stage at least 1 (except for compiletest) This PR cleans up a bunch of test steps and adds metadata to them. I didn't yet touch the most complicated step (`CompileTest`), I'm leaving that for another PR. Testing anything on stage 0 is only possible for compiletest and with `build.allow-compiletest-stage0`. Testing anything else on stage 0 will either produce a nice error or crash with a stage being subtracted below zero. r? `@jieyouxu` try-job: dist-x86_64-linux try-job: aarch64-gnu try-job: arm-android try-job: `x86_64-gnu-llvm-20*` try-job: `x86_64-msvc-*` try-job: aarch64-apple try-job: test-various
This commit is contained in:
commit
828e45ad11
13 changed files with 764 additions and 388 deletions
|
|
@ -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}}
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -1289,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");
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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: &str = "f16,cfg_target_has_reliable_f16_f128";
|
||||
|
||||
impl Builder<'_> {
|
||||
/// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ pub fn crate_description(crates: &[impl AsRef<str>]) -> 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(", ");
|
||||
|
|
|
|||
|
|
@ -2037,6 +2037,212 @@ mod snapshot {
|
|||
.render_steps(), @"[check] rustc 0 <host> -> RunMakeSupport 1 <host>");
|
||||
}
|
||||
|
||||
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_stage_1() {
|
||||
let ctx = TestCtx::new();
|
||||
insta::assert_snapshot!(
|
||||
prepare_test_config(&ctx)
|
||||
.render_steps(), @r"
|
||||
[build] rustc 0 <host> -> Tidy 1 <host>
|
||||
[test] tidy <>
|
||||
[build] rustdoc 0 <host>
|
||||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustc 0 <host> -> Compiletest 1 <host>
|
||||
[test] Ui <host>
|
||||
[test] Crashes <host>
|
||||
[build] rustc 0 <host> -> CoverageDump 1 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[test] CodegenLlvm <host>
|
||||
[test] CodegenUnits <host>
|
||||
[test] AssemblyLlvm <host>
|
||||
[test] Incremental <host>
|
||||
[test] Debuginfo <host>
|
||||
[test] UiFullDeps <host>
|
||||
[build] rustdoc 1 <host>
|
||||
[test] Rustdoc <host>
|
||||
[test] CoverageRunRustdoc <host>
|
||||
[test] Pretty <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustc 0 <host> -> std 0 <host>
|
||||
[test] rustc 0 <host> -> CrateLibrustc 1 <host>
|
||||
[build] rustc 1 <host> -> rustc 2 <host>
|
||||
[test] crate-bootstrap <host> src/tools/coverage-dump
|
||||
[test] crate-bootstrap <host> src/tools/jsondoclint
|
||||
[test] crate-bootstrap <host> src/tools/replace-version-placeholder
|
||||
[test] crate-bootstrap <host> tidyselftest
|
||||
[build] rustc 0 <host> -> UnstableBookGen 1 <host>
|
||||
[build] rustc 0 <host> -> Rustbook 1 <host>
|
||||
[doc] unstable-book (book) <host>
|
||||
[doc] book (book) <host>
|
||||
[doc] book/first-edition (book) <host>
|
||||
[doc] book/second-edition (book) <host>
|
||||
[doc] book/2018-edition (book) <host>
|
||||
[doc] rustc 0 <host> -> standalone 1 <host>
|
||||
[doc] rustc 1 <host> -> std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
|
||||
[build] rustc 0 <host> -> error-index 1 <host>
|
||||
[doc] rustc 0 <host> -> error-index 1 <host>
|
||||
[doc] nomicon (book) <host>
|
||||
[doc] rustc 1 <host> -> reference (book) 2 <host>
|
||||
[doc] rustdoc (book) <host>
|
||||
[doc] rust-by-example (book) <host>
|
||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||
[doc] rustc (book) <host>
|
||||
[doc] cargo (book) <host>
|
||||
[doc] clippy (book) <host>
|
||||
[doc] embedded-book (book) <host>
|
||||
[doc] edition-guide (book) <host>
|
||||
[doc] style-guide (book) <host>
|
||||
[doc] rustc 0 <host> -> releases 1 <host>
|
||||
[build] rustc 0 <host> -> Linkchecker 1 <host>
|
||||
[test] link-check <host>
|
||||
[test] tier-check <host>
|
||||
[test] rustc 0 <host> -> rust-analyzer 1 <host>
|
||||
[build] rustc 0 <host> -> RustdocTheme 1 <host>
|
||||
[test] rustdoc-theme 1 <host>
|
||||
[test] RustdocUi <host>
|
||||
[build] rustc 0 <host> -> JsonDocCk 1 <host>
|
||||
[build] rustc 0 <host> -> JsonDocLint 1 <host>
|
||||
[test] RustdocJson <host>
|
||||
[doc] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustc 0 <host> -> HtmlChecker 1 <host>
|
||||
[test] html-check <host>
|
||||
[build] rustc 0 <host> -> RunMakeSupport 1 <host>
|
||||
[build] rustc 1 <host> -> cargo 2 <host>
|
||||
[test] RunMake <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[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 <host> -> Tidy 1 <host>
|
||||
[test] tidy <>
|
||||
[build] rustdoc 0 <host>
|
||||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustc 1 <host> -> rustc 2 <host>
|
||||
[build] rustc 2 <host> -> std 2 <host>
|
||||
[build] rustc 0 <host> -> Compiletest 1 <host>
|
||||
[test] Ui <host>
|
||||
[test] Crashes <host>
|
||||
[build] rustc 0 <host> -> CoverageDump 1 <host>
|
||||
[build] rustc 2 <host> -> std 2 <host>
|
||||
[test] CodegenLlvm <host>
|
||||
[test] CodegenUnits <host>
|
||||
[test] AssemblyLlvm <host>
|
||||
[test] Incremental <host>
|
||||
[test] Debuginfo <host>
|
||||
[build] rustc 2 <host> -> rustc 3 <host>
|
||||
[test] UiFullDeps <host>
|
||||
[build] rustdoc 2 <host>
|
||||
[test] Rustdoc <host>
|
||||
[test] CoverageRunRustdoc <host>
|
||||
[test] Pretty <host>
|
||||
[build] rustc 2 <host> -> std 2 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustdoc 1 <host>
|
||||
[test] rustc 1 <host> -> CrateLibrustc 2 <host>
|
||||
[test] crate-bootstrap <host> src/tools/coverage-dump
|
||||
[test] crate-bootstrap <host> src/tools/jsondoclint
|
||||
[test] crate-bootstrap <host> src/tools/replace-version-placeholder
|
||||
[test] crate-bootstrap <host> tidyselftest
|
||||
[build] rustc 0 <host> -> UnstableBookGen 1 <host>
|
||||
[build] rustc 0 <host> -> Rustbook 1 <host>
|
||||
[doc] unstable-book (book) <host>
|
||||
[doc] book (book) <host>
|
||||
[doc] book/first-edition (book) <host>
|
||||
[doc] book/second-edition (book) <host>
|
||||
[doc] book/2018-edition (book) <host>
|
||||
[doc] rustc 1 <host> -> standalone 2 <host>
|
||||
[doc] rustc 1 <host> -> std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
|
||||
[build] rustc 1 <host> -> error-index 2 <host>
|
||||
[doc] rustc 1 <host> -> error-index 2 <host>
|
||||
[doc] nomicon (book) <host>
|
||||
[doc] rustc 1 <host> -> reference (book) 2 <host>
|
||||
[doc] rustdoc (book) <host>
|
||||
[doc] rust-by-example (book) <host>
|
||||
[build] rustc 0 <host> -> LintDocs 1 <host>
|
||||
[doc] rustc (book) <host>
|
||||
[doc] cargo (book) <host>
|
||||
[doc] clippy (book) <host>
|
||||
[doc] embedded-book (book) <host>
|
||||
[doc] edition-guide (book) <host>
|
||||
[doc] style-guide (book) <host>
|
||||
[doc] rustc 1 <host> -> releases 2 <host>
|
||||
[build] rustc 0 <host> -> Linkchecker 1 <host>
|
||||
[test] link-check <host>
|
||||
[test] tier-check <host>
|
||||
[test] rustc 1 <host> -> rust-analyzer 2 <host>
|
||||
[doc] rustc (book) <host>
|
||||
[test] rustc 1 <host> -> lint-docs 2 <host>
|
||||
[build] rustc 0 <host> -> RustdocTheme 1 <host>
|
||||
[test] rustdoc-theme 2 <host>
|
||||
[test] RustdocUi <host>
|
||||
[build] rustc 0 <host> -> JsonDocCk 1 <host>
|
||||
[build] rustc 0 <host> -> JsonDocLint 1 <host>
|
||||
[test] RustdocJson <host>
|
||||
[doc] rustc 1 <host> -> rustc 2 <host>
|
||||
[build] rustc 0 <host> -> HtmlChecker 1 <host>
|
||||
[test] html-check <host>
|
||||
[build] rustc 0 <host> -> RunMakeSupport 1 <host>
|
||||
[build] rustc 2 <host> -> cargo 3 <host>
|
||||
[test] RunMake <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[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 <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustc 0 <host> -> std 0 <host>
|
||||
[build] rustdoc 0 <host>
|
||||
[test] rustc 0 <host> -> CrateLibrustc 1 <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[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 <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustc 1 <host> -> rustc 2 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustdoc 1 <host>
|
||||
[test] rustc 1 <host> -> CrateLibrustc 2 <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exclude() {
|
||||
let ctx = TestCtx::new();
|
||||
|
|
@ -2054,13 +2260,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));
|
||||
}
|
||||
|
||||
|
|
@ -2077,6 +2285,7 @@ mod snapshot {
|
|||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[build] rustdoc 1 <host>
|
||||
[build] rustdoc 0 <host>
|
||||
[test] rustc 0 <host> -> cargo 1 <host>
|
||||
");
|
||||
}
|
||||
|
||||
|
|
@ -2096,6 +2305,7 @@ mod snapshot {
|
|||
[build] rustc 2 <host> -> std 2 <host>
|
||||
[build] rustdoc 2 <host>
|
||||
[build] rustdoc 1 <host>
|
||||
[test] rustc 1 <host> -> cargo 2 <host>
|
||||
");
|
||||
}
|
||||
|
||||
|
|
@ -2116,6 +2326,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 <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[test] tier-check <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_all() {
|
||||
let ctx = TestCtx::new();
|
||||
|
|
|
|||
|
|
@ -1002,13 +1002,17 @@ 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."
|
||||
);
|
||||
eprintln!("ERROR: Can't use --compile-time-deps with any subcommand other than check.");
|
||||
exit!(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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!(""))
|
||||
|
|
@ -1159,6 +1163,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 [`Build::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<HostAndStage>,
|
||||
) -> Option<gha::Group> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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`.",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<Lint>) {
|
||||
for (level, names) in RENAMES {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ fn doit() -> Result<(), Box<dyn Error>> {
|
|||
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<dyn Error>> {
|
|||
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::<u32>().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<dyn Error>> {
|
|||
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<dyn Error>> {
|
|||
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,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue