Skip to content

Commit 32c006c

Browse files
committed
Auto merge of rust-lang#12292 - GuillaumeGomez:DEPRECATED_CLIPPY_CFG_ATTR, r=flip1995
Add new lint `DEPRECATED_CLIPPY_CFG_ATTR` As discussed [on zulip](https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Is.20.60--cfg.20feature.3Dcargo-clippy.60.20deprecated.20or.20can.20it.20be.3F). This lint suggests to replace `feature = "cargo-clippy"` with `clippy`. r? `@flip1995` changelog: Add new lint `DEPRECATED_CLIPPY_CFG_ATTR`
2 parents 61daf67 + f4a3db8 commit 32c006c

11 files changed

+181
-38
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5125,6 +5125,7 @@ Released 2018-09-13
51255125
[`default_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access
51265126
[`default_union_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_union_representation
51275127
[`deprecated_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr
5128+
[`deprecated_clippy_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_clippy_cfg_attr
51285129
[`deprecated_semver`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_semver
51295130
[`deref_addrof`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof
51305131
[`deref_by_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_by_slicing

book/src/configuration.md

+3-6
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,14 @@ found [here](https://rust-lang.github.io/rust-clippy/master/index.html#msrv)
113113
114114
Very rarely, you may wish to prevent Clippy from evaluating certain sections of code entirely. You can do this with
115115
[conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html) by checking that the
116-
`cargo-clippy` feature is not set. You may need to provide a stub so that the code compiles:
116+
`clippy` cfg is not set. You may need to provide a stub so that the code compiles:
117117

118118
```rust
119-
#[cfg(not(feature = "cargo-clippy"))]
119+
#[cfg(not(clippy)]
120120
include!(concat!(env!("OUT_DIR"), "/my_big_function-generated.rs"));
121121

122-
#[cfg(feature = "cargo-clippy")]
122+
#[cfg(clippy)]
123123
fn my_big_function(_input: &str) -> Option<MyStruct> {
124124
None
125125
}
126126
```
127-
128-
This feature is not actually part of your crate, so specifying `--all-features` to other tools, e.g. `cargo test
129-
--all-features`, will not disable it.

clippy_lints/src/attrs.rs

+97-28
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,32 @@ declare_clippy_lint! {
433433
"prevent from misusing the wrong attr name"
434434
}
435435

436+
declare_clippy_lint! {
437+
/// ### What it does
438+
/// Checks for `#[cfg_attr(feature = "cargo-clippy", ...)]` and for
439+
/// `#[cfg(feature = "cargo-clippy")]` and suggests to replace it with
440+
/// `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.
441+
///
442+
/// ### Why is this bad?
443+
/// This feature has been deprecated for years and shouldn't be used anymore.
444+
///
445+
/// ### Example
446+
/// ```no_run
447+
/// #[cfg(feature = "cargo-clippy")]
448+
/// struct Bar;
449+
/// ```
450+
///
451+
/// Use instead:
452+
/// ```no_run
453+
/// #[cfg(clippy)]
454+
/// struct Bar;
455+
/// ```
456+
#[clippy::version = "1.78.0"]
457+
pub DEPRECATED_CLIPPY_CFG_ATTR,
458+
suspicious,
459+
"usage of `cfg(feature = \"cargo-clippy\")` instead of `cfg(clippy)`"
460+
}
461+
436462
declare_lint_pass!(Attributes => [
437463
ALLOW_ATTRIBUTES_WITHOUT_REASON,
438464
INLINE_ALWAYS,
@@ -794,6 +820,7 @@ impl_lint_pass!(EarlyAttributes => [
794820
EMPTY_LINE_AFTER_DOC_COMMENTS,
795821
NON_MINIMAL_CFG,
796822
MAYBE_MISUSED_CFG,
823+
DEPRECATED_CLIPPY_CFG_ATTR,
797824
]);
798825

799826
impl EarlyLintPass for EarlyAttributes {
@@ -803,6 +830,7 @@ impl EarlyLintPass for EarlyAttributes {
803830

804831
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
805832
check_deprecated_cfg_attr(cx, attr, &self.msrv);
833+
check_deprecated_cfg(cx, attr);
806834
check_mismatched_target_os(cx, attr);
807835
check_minimal_cfg_condition(cx, attr);
808836
check_misused_cfg(cx, attr);
@@ -857,39 +885,80 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
857885
}
858886
}
859887

888+
fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
889+
if item.has_name(sym::feature) && item.value_str().is_some_and(|v| v.as_str() == "cargo-clippy") {
890+
span_lint_and_sugg(
891+
cx,
892+
DEPRECATED_CLIPPY_CFG_ATTR,
893+
item.span,
894+
"`feature = \"cargo-clippy\"` was replaced by `clippy`",
895+
"replace with",
896+
"clippy".to_string(),
897+
Applicability::MachineApplicable,
898+
);
899+
}
900+
}
901+
902+
fn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::MetaItem) {
903+
if let Some(ident) = attr.ident() {
904+
if ["any", "all", "not"].contains(&ident.name.as_str()) {
905+
let Some(list) = attr.meta_item_list() else { return };
906+
for item in list.iter().filter_map(|item| item.meta_item()) {
907+
check_deprecated_cfg_recursively(cx, item);
908+
}
909+
} else {
910+
check_cargo_clippy_attr(cx, attr);
911+
}
912+
}
913+
}
914+
915+
fn check_deprecated_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
916+
if attr.has_name(sym::cfg)
917+
&& let Some(list) = attr.meta_item_list()
918+
{
919+
for item in list.iter().filter_map(|item| item.meta_item()) {
920+
check_deprecated_cfg_recursively(cx, item);
921+
}
922+
}
923+
}
924+
860925
fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
861-
if msrv.meets(msrvs::TOOL_ATTRIBUTES)
862-
// check cfg_attr
863-
&& attr.has_name(sym::cfg_attr)
926+
// check cfg_attr
927+
if attr.has_name(sym::cfg_attr)
864928
&& let Some(items) = attr.meta_item_list()
865929
&& items.len() == 2
866-
// check for `rustfmt`
867930
&& let Some(feature_item) = items[0].meta_item()
868-
&& feature_item.has_name(sym::rustfmt)
869-
// check for `rustfmt_skip` and `rustfmt::skip`
870-
&& let Some(skip_item) = &items[1].meta_item()
871-
&& (skip_item.has_name(sym!(rustfmt_skip))
872-
|| skip_item
873-
.path
874-
.segments
875-
.last()
876-
.expect("empty path in attribute")
877-
.ident
878-
.name
879-
== sym::skip)
880-
// Only lint outer attributes, because custom inner attributes are unstable
881-
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
882-
&& attr.style == AttrStyle::Outer
883931
{
884-
span_lint_and_sugg(
885-
cx,
886-
DEPRECATED_CFG_ATTR,
887-
attr.span,
888-
"`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes",
889-
"use",
890-
"#[rustfmt::skip]".to_string(),
891-
Applicability::MachineApplicable,
892-
);
932+
// check for `rustfmt`
933+
if feature_item.has_name(sym::rustfmt)
934+
&& msrv.meets(msrvs::TOOL_ATTRIBUTES)
935+
// check for `rustfmt_skip` and `rustfmt::skip`
936+
&& let Some(skip_item) = &items[1].meta_item()
937+
&& (skip_item.has_name(sym!(rustfmt_skip))
938+
|| skip_item
939+
.path
940+
.segments
941+
.last()
942+
.expect("empty path in attribute")
943+
.ident
944+
.name
945+
== sym::skip)
946+
// Only lint outer attributes, because custom inner attributes are unstable
947+
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
948+
&& attr.style == AttrStyle::Outer
949+
{
950+
span_lint_and_sugg(
951+
cx,
952+
DEPRECATED_CFG_ATTR,
953+
attr.span,
954+
"`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes",
955+
"use",
956+
"#[rustfmt::skip]".to_string(),
957+
Applicability::MachineApplicable,
958+
);
959+
} else {
960+
check_deprecated_cfg_recursively(cx, feature_item);
961+
}
893962
}
894963
}
895964

clippy_lints/src/declared_lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
5151
crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,
5252
crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,
5353
crate::attrs::DEPRECATED_CFG_ATTR_INFO,
54+
crate::attrs::DEPRECATED_CLIPPY_CFG_ATTR_INFO,
5455
crate::attrs::DEPRECATED_SEMVER_INFO,
5556
crate::attrs::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
5657
crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,

src/driver.rs

+2
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ pub fn main() {
271271
},
272272
_ => Some(s.to_string()),
273273
})
274+
// FIXME: remove this line in 1.79 to only keep `--cfg clippy`.
274275
.chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
276+
.chain(vec!["--cfg".into(), "clippy".into()])
275277
.collect::<Vec<String>>();
276278

277279
// We enable Clippy if one of the following conditions is met

tests/ui/cfg_attr_cargo_clippy.fixed

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![warn(clippy::deprecated_clippy_cfg_attr)]
2+
#![allow(clippy::non_minimal_cfg)]
3+
#![cfg_attr(clippy, doc = "a")] //~ ERROR: `feature = "cargo-clippy"` was
4+
5+
#[cfg_attr(clippy, derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was
6+
#[cfg_attr(not(clippy), derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was
7+
#[cfg(clippy)] //~ ERROR: `feature = "cargo-clippy"` was
8+
#[cfg(not(clippy))] //~ ERROR: `feature = "cargo-clippy"` was
9+
#[cfg(any(clippy))] //~ ERROR: `feature = "cargo-clippy"` was
10+
#[cfg(all(clippy))] //~ ERROR: `feature = "cargo-clippy"` was
11+
pub struct Bar;
12+
13+
fn main() {}

tests/ui/cfg_attr_cargo_clippy.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![warn(clippy::deprecated_clippy_cfg_attr)]
2+
#![allow(clippy::non_minimal_cfg)]
3+
#![cfg_attr(feature = "cargo-clippy", doc = "a")] //~ ERROR: `feature = "cargo-clippy"` was
4+
5+
#[cfg_attr(feature = "cargo-clippy", derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was
6+
#[cfg_attr(not(feature = "cargo-clippy"), derive(Debug))] //~ ERROR: `feature = "cargo-clippy"` was
7+
#[cfg(feature = "cargo-clippy")] //~ ERROR: `feature = "cargo-clippy"` was
8+
#[cfg(not(feature = "cargo-clippy"))] //~ ERROR: `feature = "cargo-clippy"` was
9+
#[cfg(any(feature = "cargo-clippy"))] //~ ERROR: `feature = "cargo-clippy"` was
10+
#[cfg(all(feature = "cargo-clippy"))] //~ ERROR: `feature = "cargo-clippy"` was
11+
pub struct Bar;
12+
13+
fn main() {}

tests/ui/cfg_attr_cargo_clippy.stderr

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error: `feature = "cargo-clippy"` was replaced by `clippy`
2+
--> $DIR/cfg_attr_cargo_clippy.rs:5:12
3+
|
4+
LL | #[cfg_attr(feature = "cargo-clippy", derive(Debug))]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
6+
|
7+
= note: `-D clippy::deprecated-clippy-cfg-attr` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::deprecated_clippy_cfg_attr)]`
9+
10+
error: `feature = "cargo-clippy"` was replaced by `clippy`
11+
--> $DIR/cfg_attr_cargo_clippy.rs:6:16
12+
|
13+
LL | #[cfg_attr(not(feature = "cargo-clippy"), derive(Debug))]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
15+
16+
error: `feature = "cargo-clippy"` was replaced by `clippy`
17+
--> $DIR/cfg_attr_cargo_clippy.rs:7:7
18+
|
19+
LL | #[cfg(feature = "cargo-clippy")]
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
21+
22+
error: `feature = "cargo-clippy"` was replaced by `clippy`
23+
--> $DIR/cfg_attr_cargo_clippy.rs:8:11
24+
|
25+
LL | #[cfg(not(feature = "cargo-clippy"))]
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
27+
28+
error: `feature = "cargo-clippy"` was replaced by `clippy`
29+
--> $DIR/cfg_attr_cargo_clippy.rs:9:11
30+
|
31+
LL | #[cfg(any(feature = "cargo-clippy"))]
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
33+
34+
error: `feature = "cargo-clippy"` was replaced by `clippy`
35+
--> $DIR/cfg_attr_cargo_clippy.rs:10:11
36+
|
37+
LL | #[cfg(all(feature = "cargo-clippy"))]
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
39+
40+
error: `feature = "cargo-clippy"` was replaced by `clippy`
41+
--> $DIR/cfg_attr_cargo_clippy.rs:3:13
42+
|
43+
LL | #![cfg_attr(feature = "cargo-clippy", doc = "a")]
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`
45+
46+
error: aborting due to 7 previous errors
47+

tests/ui/useless_attribute.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#![feature(rustc_private)]
77

88
#![allow(dead_code)]
9-
#![cfg_attr(feature = "cargo-clippy", allow(dead_code))]
9+
#![cfg_attr(clippy, allow(dead_code))]
1010
#[rustfmt::skip]
1111
#[allow(unused_imports)]
1212
#[allow(unused_extern_crates)]

tests/ui/useless_attribute.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#![feature(rustc_private)]
77

88
#[allow(dead_code)]
9-
#[cfg_attr(feature = "cargo-clippy", allow(dead_code))]
9+
#[cfg_attr(clippy, allow(dead_code))]
1010
#[rustfmt::skip]
1111
#[allow(unused_imports)]
1212
#[allow(unused_extern_crates)]

tests/ui/useless_attribute.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | #[allow(dead_code)]
1010
error: useless lint attribute
1111
--> $DIR/useless_attribute.rs:9:1
1212
|
13-
LL | #[cfg_attr(feature = "cargo-clippy", allow(dead_code))]
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(feature = "cargo-clippy", allow(dead_code)`
13+
LL | #[cfg_attr(clippy, allow(dead_code))]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(clippy, allow(dead_code)`
1515

1616
error: useless lint attribute
1717
--> $DIR/useless_attribute.rs:20:5

0 commit comments

Comments
 (0)