Skip to content

bootstrap: allow to set clippy.toml for x.py clippy #137785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 64 additions & 20 deletions src/bootstrap/src/core/build_steps/clippy.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! Implementation of running clippy on the compiler, standard library and various tools.

use std::path::PathBuf;

use super::compile::{run_cargo, rustc_cargo, std_cargo};
use super::tool::{SourceType, prepare_tool_cargo};
use super::{check, compile};
use crate::builder::{Builder, ShouldRun};
use crate::builder::{Builder, Cargo, ShouldRun};
use crate::core::build_steps::compile::std_crates_for_run_make;
use crate::core::builder;
use crate::core::builder::{Alias, Kind, RunConfig, Step, crate_description};
Expand Down Expand Up @@ -92,19 +94,22 @@ pub struct LintConfig {
pub warn: Vec<String>,
pub deny: Vec<String>,
pub forbid: Vec<String>,
// Path to folder containing clippy.toml, if any
pub clippy_cfg_path: Option<PathBuf>,
}

impl LintConfig {
fn new(builder: &Builder<'_>) -> Self {
fn new(builder: &Builder<'_>, clippy_config: Option<PathBuf>) -> Self {
match builder.config.cmd.clone() {
Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
Self { allow, warn, deny, forbid }
Self { allow, warn, deny, forbid, clippy_cfg_path: clippy_config }
}
_ => unreachable!("LintConfig can only be called from `clippy` subcommands."),
}
}

fn merge(&self, other: &Self) -> Self {
/// prefer_self - use self.clippy_cfg_path when merging, otherwise - other.clippy_cfg_path
fn merge(&self, other: &Self, prefer_self: bool) -> Self {
let merged = |self_attr: &[String], other_attr: &[String]| -> Vec<String> {
self_attr.iter().cloned().chain(other_attr.iter().cloned()).collect()
};
Expand All @@ -114,8 +119,23 @@ impl LintConfig {
warn: merged(&self.warn, &other.warn),
deny: merged(&self.deny, &other.deny),
forbid: merged(&self.forbid, &other.forbid),
// FIXME: this skip merging clippy.toml,
// but maybe there is a better way?
Comment on lines +122 to +123
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this comment mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function named merge, but it don't merge 1 field, so i left this as note, better rephrase this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we want to merge this field?

clippy_cfg_path: if prefer_self {
self.clippy_cfg_path.clone()
} else {
other.clippy_cfg_path.clone()
},
}
}

fn apply_clippy_cfg(&self, cargo: &mut Cargo, builder: &Builder<'_>) {
let Some(cfg_path) = &self.clippy_cfg_path else {
return;
};
let absolute_path = builder.src.join(cfg_path);
cargo.env("CLIPPY_CONF_DIR", absolute_path);
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand All @@ -136,7 +156,7 @@ impl Step for Std {

fn make_run(run: RunConfig<'_>) {
let crates = std_crates_for_run_make(&run);
let config = LintConfig::new(run.builder);
let config = LintConfig::new(run.builder, None);
run.builder.ensure(Std { target: run.target, config, crates });
}

Expand All @@ -155,6 +175,8 @@ impl Step for Std {
Kind::Clippy,
);

self.config.apply_clippy_cfg(&mut cargo, builder);

std_cargo(builder, target, compiler.stage, &mut cargo);

for krate in &*self.crates {
Expand Down Expand Up @@ -195,7 +217,10 @@ impl Step for Rustc {

fn make_run(run: RunConfig<'_>) {
let crates = run.make_run_crates(Alias::Compiler);
let config = LintConfig::new(run.builder);
let config = LintConfig::new(
run.builder,
Some("src/etc/clippy_configs/compiler/clippy.toml".into()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a bit of an odd place to put clippy configs.. maybe we can move them to e.g. src/bootstrap, similar to profile files?

I'm also wondering if there's any clippy-native feature for these configs that we could be using instead? For example package-specific configs or something like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, location not really important, i can move it.

Lints can be set via https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-lints-section, but not config for them https://doc.rust-lang.org/clippy/lint_configuration.html, as i understand.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I thought we had user-configurable config for e.g. the cfg lints. Maybe those are special cased though.

);
run.builder.ensure(Rustc { target: run.target, config, crates });
}

Expand Down Expand Up @@ -228,6 +253,8 @@ impl Step for Rustc {
Kind::Clippy,
);

self.config.apply_clippy_cfg(&mut cargo, builder);

rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);

// Explicitly pass -p for all compiler crates -- this will force cargo
Expand Down Expand Up @@ -255,6 +282,7 @@ impl Step for Rustc {
macro_rules! lint_any {
($(
$name:ident, $path:expr, $readable_name:expr
$(,clippy_cfg = $cfg_path:expr)?
$(,lint_by_default = $lint_by_default:expr)*
;
)+) => {
Expand All @@ -275,7 +303,14 @@ macro_rules! lint_any {
}

fn make_run(run: RunConfig<'_>) {
let config = LintConfig::new(run.builder);
#[allow(unused_mut, unused_assignments)] // optional cfg_path
let mut clippy_cfg: Option<PathBuf> = None;

$(
clippy_cfg = Some($cfg_path.into());
)?

let config = LintConfig::new(run.builder, clippy_cfg);
run.builder.ensure($name {
target: run.target,
config,
Expand All @@ -288,7 +323,7 @@ macro_rules! lint_any {

builder.ensure(check::Rustc::new(target, builder).build_kind(Some(Kind::Check)));

let cargo = prepare_tool_cargo(
let mut cargo = prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
Expand All @@ -299,6 +334,8 @@ macro_rules! lint_any {
&[],
);

self.config.apply_clippy_cfg(&mut cargo, builder);

let _guard = builder.msg_tool(
Kind::Clippy,
Mode::ToolRustc,
Expand Down Expand Up @@ -328,7 +365,7 @@ macro_rules! lint_any {
}

lint_any!(
Bootstrap, "src/bootstrap", "bootstrap";
Bootstrap, "src/bootstrap", "bootstrap", clippy_cfg = "src/etc/clippy_configs/bootstrap/clippy.toml";
BuildHelper, "src/build_helper", "build_helper";
BuildManifest, "src/tools/build-manifest", "build-manifest";
CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri";
Expand All @@ -348,7 +385,7 @@ lint_any!(
RemoteTestServer, "src/tools/remote-test-server", "remote-test-server";
Rls, "src/tools/rls", "rls";
RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer";
Rustdoc, "src/librustdoc", "clippy";
Rustdoc, "src/librustdoc", "rustdoc";
Rustfmt, "src/tools/rustfmt", "rustfmt";
RustInstaller, "src/tools/rust-installer", "rust-installer";
Tidy, "src/tools/tidy", "tidy";
Expand All @@ -370,19 +407,23 @@ impl Step for CI {
}

fn make_run(run: RunConfig<'_>) {
let config = LintConfig::new(run.builder);
let config = LintConfig::new(run.builder, None);
run.builder.ensure(CI { target: run.target, config });
}

fn run(self, builder: &Builder<'_>) -> Self::Output {
builder.ensure(Bootstrap {
target: self.target,
config: self.config.merge(&LintConfig {
allow: vec![],
warn: vec![],
deny: vec!["warnings".into()],
forbid: vec![],
}),
config: self.config.merge(
&LintConfig {
allow: vec![],
warn: vec![],
deny: vec!["warnings".into()],
forbid: vec![],
clippy_cfg_path: Some("src/etc/clippy_configs/bootstrap/clippy.toml".into()),
},
false,
),
});
let library_clippy_cfg = LintConfig {
allow: vec!["clippy::all".into()],
Expand All @@ -400,10 +441,11 @@ impl Step for CI {
"clippy::to_string_in_format_args".into(),
],
forbid: vec![],
clippy_cfg_path: None,
};
builder.ensure(Std {
target: self.target,
config: self.config.merge(&library_clippy_cfg),
config: self.config.merge(&library_clippy_cfg, true),
crates: vec![],
});

Expand All @@ -425,10 +467,11 @@ impl Step for CI {
"clippy::to_string_in_format_args".into(),
],
forbid: vec![],
clippy_cfg_path: Some("src/etc/clippy_configs/compiler/clippy.toml".into()),
};
builder.ensure(Rustc {
target: self.target,
config: self.config.merge(&compiler_clippy_cfg),
config: self.config.merge(&compiler_clippy_cfg, false),
crates: vec![],
});

Expand All @@ -437,10 +480,11 @@ impl Step for CI {
warn: vec![],
deny: vec!["warnings".into()],
forbid: vec![],
clippy_cfg_path: None,
};
builder.ensure(CodegenGcc {
target: self.target,
config: self.config.merge(&rustc_codegen_gcc),
config: self.config.merge(&rustc_codegen_gcc, true),
});
}
}
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/config/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ fn order_of_clippy_rules() {

let actual = match config.cmd.clone() {
crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
let cfg = LintConfig { allow, deny, warn, forbid };
let cfg = LintConfig { allow, deny, warn, forbid, clippy_cfg_path: None };
get_clippy_rules_in_order(&args, &cfg)
}
_ => panic!("invalid subcommand"),
Expand All @@ -342,7 +342,7 @@ fn clippy_rule_separate_prefix() {

let actual = match config.cmd.clone() {
crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
let cfg = LintConfig { allow, deny, warn, forbid };
let cfg = LintConfig { allow, deny, warn, forbid, clippy_cfg_path: None };
get_clippy_rules_in_order(&args, &cfg)
}
_ => panic!("invalid subcommand"),
Expand Down
1 change: 1 addition & 0 deletions src/etc/clippy_configs/bootstrap/clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
avoid-breaking-exported-api = false
1 change: 1 addition & 0 deletions src/etc/clippy_configs/compiler/clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
avoid-breaking-exported-api = false
Loading