about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Beránek <berykubik@gmail.com>2025-08-11 20:00:29 +0200
committerJakub Beránek <berykubik@gmail.com>2025-08-13 08:11:00 +0200
commit0acfe86faa35eb47ecfe8fb36d4119c8a280e01a (patch)
tree46d87e493bd005d5e663e7526f6e6c2d965cfc86
parent92e1541f76106601bf33d3fe2bc0564b97c85d6e (diff)
downloadrust-0acfe86faa35eb47ecfe8fb36d4119c8a280e01a.tar.gz
rust-0acfe86faa35eb47ecfe8fb36d4119c8a280e01a.zip
Manually optimize steps performed by `x clippy ci`
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs33
-rw-r--r--src/bootstrap/src/core/builder/tests.rs24
2 files changed, 32 insertions, 25 deletions
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index 2f1adde7016..ae35513a544 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -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,
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 226732cd2af..210f05a8346 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -2072,25 +2072,6 @@ mod snapshot {
         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")
-                .path("ci")
                 .stage(2)
                 .render_steps(), @r"
         [build] llvm <host>
@@ -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>