Manually optimize steps performed by x clippy ci

This commit is contained in:
Jakub Beránek 2025-08-11 20:00:29 +02:00
parent 92e1541f76
commit 0acfe86faa
No known key found for this signature in database
GPG key ID: 909CD0D26483516B
2 changed files with 32 additions and 25 deletions

View file

@ -12,6 +12,8 @@
//! to pass a prebuilt Clippy from the outside when running `cargo clippy`, but that would be
//! (as usual) a massive undertaking/refactoring.
use build_helper::exit;
use super::compile::{run_cargo, rustc_cargo, std_cargo};
use super::tool::{SourceType, prepare_tool_cargo};
use crate::builder::{Builder, ShouldRun};
@ -154,6 +156,15 @@ impl Std {
crates,
}
}
fn from_build_compiler(
build_compiler: Compiler,
target: TargetSelection,
config: LintConfig,
crates: Vec<String>,
) -> Self {
Self { build_compiler, target, config, crates }
}
}
impl Step for Std {
@ -479,6 +490,7 @@ lint_any!(
TestFloatParse, "src/tools/test-float-parse", "test-float-parse", Mode::ToolStd;
);
/// Runs Clippy on in-tree sources of selected projects using in-tree CLippy.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CI {
target: TargetSelection,
@ -499,7 +511,20 @@ impl Step for CI {
}
fn run(self, builder: &Builder<'_>) -> Self::Output {
if builder.top_stage != 2 {
eprintln!("ERROR: `x clippy ci` should always be executed with --stage 2");
exit!(1);
}
// We want to check in-tree source using in-tree clippy. However, if we naively did
// a stage 2 `x clippy ci`, it would *build* a stage 2 rustc, in order to lint stage 2
// std, which is wasteful.
// So we want to lint stage 2 [bootstrap/rustc/...], but only stage 1 std rustc_codegen_gcc.
// We thus construct the compilers in this step manually, to optimize the number of
// steps that get built.
builder.ensure(Bootstrap {
// This will be the stage 1 compiler
build_compiler: prepare_compiler_for_check(builder, self.target, Mode::ToolTarget),
target: self.target,
config: self.config.merge(&LintConfig {
@ -509,6 +534,7 @@ impl Step for CI {
forbid: vec![],
}),
});
let library_clippy_cfg = LintConfig {
allow: vec!["clippy::all".into()],
warn: vec![],
@ -526,8 +552,9 @@ impl Step for CI {
],
forbid: vec![],
};
builder.ensure(Std::new(
builder,
builder.ensure(Std::from_build_compiler(
// This will be the stage 1 compiler, to avoid building rustc stage 2 just to lint std
builder.compiler(1, self.target),
self.target,
self.config.merge(&library_clippy_cfg),
vec![],
@ -552,6 +579,7 @@ impl Step for CI {
],
forbid: vec![],
};
// This will lint stage 2 rustc using stage 1 Clippy
builder.ensure(Rustc::new(
builder,
self.target,
@ -565,6 +593,7 @@ impl Step for CI {
deny: vec!["warnings".into()],
forbid: vec![],
};
// This will check stage 2 rustc
builder.ensure(CodegenGcc::new(
builder,
self.target,

View file

@ -2068,25 +2068,6 @@ mod snapshot {
#[test]
fn clippy_ci() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("clippy")
.path("ci")
.render_steps(), @r"
[clippy] rustc 0 <host> -> bootstrap 1 <host>
[build] llvm <host>
[build] rustc 0 <host> -> rustc 1 <host>
[build] rustc 0 <host> -> clippy-driver 1 <host>
[build] rustc 0 <host> -> cargo-clippy 1 <host>
[clippy] rustc 1 <host> -> std 1 <host>
[clippy] rustc 0 <host> -> rustc 1 <host>
[check] rustc 0 <host> -> rustc 1 <host>
[clippy] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
");
}
#[test]
fn clippy_ci_stage_2() {
let ctx = TestCtx::new();
insta::assert_snapshot!(
ctx.config("clippy")
@ -2099,10 +2080,7 @@ mod snapshot {
[build] rustc 0 <host> -> clippy-driver 1 <host>
[build] rustc 0 <host> -> cargo-clippy 1 <host>
[clippy] rustc 1 <host> -> bootstrap 2 <host>
[build] rustc 1 <host> -> rustc 2 <host>
[build] rustc 1 <host> -> clippy-driver 2 <host>
[build] rustc 1 <host> -> cargo-clippy 2 <host>
[clippy] rustc 2 <host> -> std 2 <host>
[clippy] rustc 1 <host> -> std 1 <host>
[clippy] rustc 1 <host> -> rustc 2 <host>
[check] rustc 1 <host> -> rustc 2 <host>
[clippy] rustc 1 <host> -> rustc_codegen_gcc 2 <host>