diff options
| author | Jakub Beránek <berykubik@gmail.com> | 2025-08-08 17:09:58 +0200 |
|---|---|---|
| committer | Jakub Beránek <berykubik@gmail.com> | 2025-08-13 08:11:00 +0200 |
| commit | 5ffd5c2ec23f823a6dcb7c67d9d19b0723777fda (patch) | |
| tree | f7d21314b944f072ee933c9e973d792837573128 | |
| parent | ba27938c8ca9a6b7e97a1011d611dcfcab78b550 (diff) | |
| download | rust-5ffd5c2ec23f823a6dcb7c67d9d19b0723777fda.tar.gz rust-5ffd5c2ec23f823a6dcb7c67d9d19b0723777fda.zip | |
Fix Clippy staging for compiler
| -rw-r--r-- | src/bootstrap/src/core/build_steps/check.rs | 6 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/clippy.rs | 74 | ||||
| -rw-r--r-- | src/bootstrap/src/core/builder/mod.rs | 17 | ||||
| -rw-r--r-- | src/bootstrap/src/core/builder/tests.rs | 34 | ||||
| -rw-r--r-- | src/bootstrap/src/utils/build_stamp.rs | 6 |
5 files changed, 84 insertions, 53 deletions
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 2d27ad4cdf3..ae258bf2939 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -30,10 +30,6 @@ pub struct Std { impl Std { const CRATE_OR_DEPS: &[&str] = &["sysroot", "coretests", "alloctests"]; - - pub fn new(build_compiler: Compiler, target: TargetSelection) -> Self { - Self { build_compiler, target, crates: vec![] } - } } impl Step for Std { @@ -241,7 +237,7 @@ impl Step for Rustc { } /// Prepares a compiler that will check something with the given `mode`. -fn prepare_compiler_for_check( +pub fn prepare_compiler_for_check( builder: &Builder<'_>, target: TargetSelection, mode: Mode, diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index f029f9fa939..364d9bed883 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -1,14 +1,27 @@ //! Implementation of running clippy on the compiler, standard library and various tools. +//! +//! This serves a double purpose: +//! - The first is to run Clippy itself on in-tree code, in order to test and dogfood it. +//! - The second is to actually lint the in-tree codebase on CI, with a hard-coded set of rules, +//! which is performed by the `x clippy ci` command. +//! +//! In order to prepare a build compiler for running clippy, use the +//! `check::prepare_compiler_for_check` function. That prepares a compiler and a standard library +//! for running Clippy. The second part (actually building Clippy) is performed inside +//! [Builder::cargo_clippy_cmd]. It would be nice if this was more explicit, and we actually had +//! to pass a prebuilt Clippy from the outside when running `cargo clippy`, but that would be +//! (as usual) a massive undertaking/refactoring. use super::check; use super::compile::{run_cargo, rustc_cargo, std_cargo}; use super::tool::{RustcPrivateCompilers, SourceType, prepare_tool_cargo}; use crate::builder::{Builder, ShouldRun}; +use crate::core::build_steps::check::prepare_compiler_for_check; use crate::core::build_steps::compile::std_crates_for_run_make; use crate::core::builder; use crate::core::builder::{Alias, Kind, RunConfig, Step, StepMetadata, crate_description}; use crate::utils::build_stamp::{self, BuildStamp}; -use crate::{Mode, Subcommand, TargetSelection}; +use crate::{Compiler, Mode, Subcommand, TargetSelection}; /// Disable the most spammy clippy lints const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[ @@ -184,14 +197,35 @@ impl Step for Std { } } +/// Lints the compiler. +/// +/// This will build Clippy with the `build_compiler` and use it to lint +/// in-tree rustc. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Rustc { - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, config: LintConfig, /// Whether to lint only a subset of crates. crates: Vec<String>, } +impl Rustc { + fn new( + builder: &Builder<'_>, + target: TargetSelection, + config: LintConfig, + crates: Vec<String>, + ) -> Self { + Self { + build_compiler: prepare_compiler_for_check(builder, target, Mode::Rustc), + target, + config, + crates, + } + } +} + impl Step for Rustc { type Output = (); const ONLY_HOSTS: bool = true; @@ -202,33 +236,16 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { + let builder = run.builder; let crates = run.make_run_crates(Alias::Compiler); let config = LintConfig::new(run.builder); - run.builder.ensure(Rustc { target: run.target, config, crates }); + run.builder.ensure(Rustc::new(builder, run.target, config, crates)); } - /// Lints the compiler. - /// - /// This will lint the compiler for a particular stage of the build using - /// the `compiler` targeting the `target` architecture. fn run(self, builder: &Builder<'_>) { - let build_compiler = builder.compiler(builder.top_stage, builder.config.host_target); + let build_compiler = self.build_compiler; let target = self.target; - if !builder.download_rustc() { - if build_compiler.stage != 0 { - // If we're not in stage 0, then we won't have a std from the beta - // compiler around. That means we need to make sure there's one in - // the sysroot for the compiler to find. Otherwise, we're going to - // fail when building crates that need to generate code (e.g., build - // scripts and their dependencies). - builder.std(build_compiler, build_compiler.host); - builder.std(build_compiler, target); - } else { - builder.ensure(check::Std::new(build_compiler, target)); - } - } - let mut cargo = builder::Cargo::new( builder, build_compiler, @@ -267,7 +284,7 @@ impl Step for Rustc { } fn metadata(&self) -> Option<StepMetadata> { - Some(StepMetadata::clippy("rustc", self.target)) + Some(StepMetadata::clippy("rustc", self.target).built_by(self.build_compiler)) } } @@ -518,11 +535,12 @@ impl Step for CI { ], forbid: vec![], }; - builder.ensure(Rustc { - target: self.target, - config: self.config.merge(&compiler_clippy_cfg), - crates: vec![], - }); + builder.ensure(Rustc::new( + builder, + self.target, + self.config.merge(&compiler_clippy_cfg), + vec![], + )); let rustc_codegen_gcc = LintConfig { allow: vec![], diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 8e9f3c1eab4..9719bcbc563 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1556,8 +1556,10 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s self.ensure(tool::Rustdoc { target_compiler }) } - pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> BootstrapCommand { - if run_compiler.stage == 0 { + /// Create a Cargo command for running Clippy. + /// The used Clippy is (or in the case of stage 0, already was) built using `build_compiler`. + pub fn cargo_clippy_cmd(&self, build_compiler: Compiler) -> BootstrapCommand { + if build_compiler.stage == 0 { let cargo_clippy = self .config .initial_cargo_clippy @@ -1569,15 +1571,16 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s return cmd; } - // FIXME: double check that `run_compiler`'s stage is what we want to use - let compilers = - RustcPrivateCompilers::new(self, run_compiler.stage, self.build.host_target); - assert_eq!(run_compiler, compilers.target_compiler()); + let compilers = RustcPrivateCompilers::from_build_compiler( + self, + build_compiler, + self.build.host_target, + ); let _ = self.ensure(tool::Clippy::from_compilers(compilers)); let cargo_clippy = self.ensure(tool::CargoClippy::from_compilers(compilers)); let mut dylib_path = helpers::dylib_path(); - dylib_path.insert(0, self.sysroot(run_compiler).join("lib")); + dylib_path.insert(0, self.sysroot(build_compiler).join("lib")); let mut cmd = command(cargo_clippy.tool_path); cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b9fc3ed57ec..2c1623f5385 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2076,12 +2076,13 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [check] rustc 1 <host> -> rustc 2 <host> - [build] rustc 0 <host> -> clippy-driver 1 <host> - [build] rustc 0 <host> -> cargo-clippy 1 <host> + [build] rustc 1 <host> -> std 1 <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] bootstrap <host> [clippy] std <host> - [build] rustc 1 <host> -> std 1 <host> - [clippy] rustc <host> + [clippy] rustc 0 <host> -> rustc 1 <host> [clippy] rustc 0 <host> -> rustc_codegen_gcc 1 <host> "); } @@ -2099,17 +2100,30 @@ mod snapshot { [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> [check] rustc 2 <host> -> rustc 3 <host> - [build] rustc 1 <host> -> clippy-driver 2 <host> - [build] rustc 1 <host> -> cargo-clippy 2 <host> + [build] rustc 2 <host> -> std 2 <host> + [build] rustc 2 <host> -> rustc 3 <host> + [build] rustc 2 <host> -> clippy-driver 3 <host> + [build] rustc 2 <host> -> cargo-clippy 3 <host> [clippy] bootstrap <host> [clippy] std <host> - [build] rustc 2 <host> -> std 2 <host> - [clippy] rustc <host> - [build] rustc 0 <host> -> clippy-driver 1 <host> - [build] rustc 0 <host> -> cargo-clippy 1 <host> + [build] rustc 1 <host> -> clippy-driver 2 <host> + [build] rustc 1 <host> -> cargo-clippy 2 <host> + [clippy] rustc 1 <host> -> rustc 2 <host> [clippy] rustc 1 <host> -> rustc_codegen_gcc 2 <host> "); } + + #[test] + fn clippy_compiler() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("compiler") + .render_steps(), @r" + [build] llvm <host> + [clippy] rustc 0 <host> -> rustc 1 <host> + "); + } } struct ExecutedSteps { diff --git a/src/bootstrap/src/utils/build_stamp.rs b/src/bootstrap/src/utils/build_stamp.rs index bd4eb790ae5..6c79385190e 100644 --- a/src/bootstrap/src/utils/build_stamp.rs +++ b/src/bootstrap/src/utils/build_stamp.rs @@ -146,13 +146,13 @@ pub fn libstd_stamp( } /// Cargo's output path for librustc in a given stage, compiled by a particular -/// compiler for the specified target. +/// `build_compiler` for the specified target. pub fn librustc_stamp( builder: &Builder<'_>, - compiler: Compiler, + build_compiler: Compiler, target: TargetSelection, ) -> BuildStamp { - BuildStamp::new(&builder.cargo_out(compiler, Mode::Rustc, target)).with_prefix("librustc") + BuildStamp::new(&builder.cargo_out(build_compiler, Mode::Rustc, target)).with_prefix("librustc") } /// Computes a hash representing the state of a repository/submodule and additional input. |
