Skip to content

Commit 2a27f5c

Browse files
committed
Lint against cfg(any()) and cfg(all())
1 parent d5525a7 commit 2a27f5c

File tree

92 files changed

+577
-468
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+577
-468
lines changed

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_parse::parser::{ForceCollect, Parser};
1212
use rustc_parse::{exp, parse_in};
1313
use rustc_session::Session;
1414
use rustc_session::config::ExpectedValues;
15-
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
15+
use rustc_session::lint::builtin::{EMPTY_CFG_PREDICATE, UNEXPECTED_CFGS};
1616
use rustc_session::parse::{ParseSess, feature_err};
1717
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
1818
use thin_vec::ThinVec;
@@ -63,14 +63,42 @@ pub fn parse_cfg_entry<S: Stage>(
6363
};
6464
CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
6565
}
66-
Some(sym::any) => CfgEntry::Any(
67-
list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(),
68-
list.span,
69-
),
70-
Some(sym::all) => CfgEntry::All(
71-
list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(),
72-
list.span,
73-
),
66+
Some(sym::any) => {
67+
if list.is_empty() && !list.span.from_expansion() {
68+
let span = meta.span();
69+
cx.emit_lint(
70+
EMPTY_CFG_PREDICATE,
71+
AttributeLintKind::EmptyCfgPredictate {
72+
predicate_span: span,
73+
predicate: sym::any,
74+
lit: false,
75+
},
76+
span,
77+
);
78+
}
79+
CfgEntry::Any(
80+
list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(),
81+
list.span,
82+
)
83+
}
84+
Some(sym::all) => {
85+
if list.is_empty() && !list.span.from_expansion() {
86+
let span = meta.span();
87+
cx.emit_lint(
88+
EMPTY_CFG_PREDICATE,
89+
AttributeLintKind::EmptyCfgPredictate {
90+
predicate_span: span,
91+
predicate: sym::all,
92+
lit: true,
93+
},
94+
span,
95+
);
96+
}
97+
CfgEntry::All(
98+
list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(),
99+
list.span,
100+
)
101+
}
74102
Some(sym::target) => parse_cfg_entry_target(cx, list, meta.span())?,
75103
Some(sym::version) => parse_cfg_entry_version(cx, list, meta.span())?,
76104
_ => {

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub(crate) fn compile_fn(
167167
context.clear();
168168
context.func = codegened_func.func;
169169

170-
#[cfg(any())] // This is never true
170+
#[cfg(false)]
171171
let _clif_guard = {
172172
use std::fmt::Write;
173173

compiler/rustc_lint/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ lint_empty_attribute =
256256
*[other] using `{$attr_path}` with an empty list has no effect
257257
}
258258
259+
lint_empty_cfg_predicate = use of empty `cfg({$predicate}())`
260+
.note = this used to be a common pattern before `cfg(true)` and `cfg(false)` were added to the language in Rust 1.88
261+
.suggestion = consider using a boolean literal
262+
259263
-lint_previously_accepted =
260264
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
261265
lint_enum_intrinsics_mem_discriminant =

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,5 +367,8 @@ pub fn decorate_attribute_lint(
367367
&AttributeLintKind::UnexpectedCfgValue(name, value) => {
368368
check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag)
369369
}
370+
&AttributeLintKind::EmptyCfgPredictate { predicate_span, predicate, lit } => {
371+
lints::EmptyCfgPredicate { predicate_span, predicate, lit }.decorate_lint(diag)
372+
}
370373
}
371374
}

compiler/rustc_lint/src/lints.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3137,6 +3137,16 @@ pub(crate) struct EmptyAttributeList {
31373137
pub valid_without_list: bool,
31383138
}
31393139

3140+
#[derive(LintDiagnostic)]
3141+
#[diag(lint_empty_cfg_predicate)]
3142+
#[note]
3143+
pub(crate) struct EmptyCfgPredicate {
3144+
#[suggestion(code = "{lit}", applicability = "machine-applicable", style = "verbose")]
3145+
pub predicate_span: Span,
3146+
pub predicate: Symbol,
3147+
pub lit: bool,
3148+
}
3149+
31403150
#[derive(LintDiagnostic)]
31413151
#[diag(lint_invalid_target)]
31423152
#[warning]

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ declare_lint_pass! {
4040
DUPLICATE_MACRO_ATTRIBUTES,
4141
ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4242
ELIDED_LIFETIMES_IN_PATHS,
43+
EMPTY_CFG_PREDICATE,
4344
EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
4445
EXPORTED_PRIVATE_DEPENDENCIES,
4546
FFI_UNWIND_CALLS,
@@ -5368,3 +5369,30 @@ declare_lint! {
53685369
report_in_deps: false,
53695370
};
53705371
}
5372+
5373+
declare_lint! {
5374+
/// The `empty_cfg_predicate` lint detects the use of empty `cfg` predicate lists.
5375+
///
5376+
/// ### Example
5377+
///
5378+
/// ```rust,compile_fail
5379+
/// #![deny(empty_cfg_predicate)]
5380+
/// #[cfg(any())]
5381+
/// fn foo() {}
5382+
///
5383+
/// #[cfg(all())]
5384+
/// fn bar() {}
5385+
/// ```
5386+
///
5387+
/// {{produces}}
5388+
///
5389+
/// ### Explanation
5390+
///
5391+
/// The meaning of `cfg(any())` and `cfg(all())` is not immediately obvious;
5392+
/// `cfg(false)` and `cfg(true)` respectively may be used instead.
5393+
/// This used to be a common pattern before `cfg(true)` and `cfg(false)`
5394+
/// were added to the language in Rust 1.88
5395+
pub EMPTY_CFG_PREDICATE,
5396+
Warn,
5397+
"detects use of empty `cfg(any())` and `cfg(all())`"
5398+
}

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,14 @@ pub enum AttributeLintKind {
733733
},
734734
UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
735735
UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
736+
EmptyCfgPredictate {
737+
/// Span of `any()`/`all()`
738+
predicate_span: Span,
739+
/// Either `any` or `all`
740+
predicate: Symbol,
741+
/// The boolean literal to replace with
742+
lit: bool,
743+
},
736744
}
737745

738746
pub type RegisteredTools = FxIndexSet<Ident>;

library/core/src/primitive_docs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ impl () {}
591591
/// # pub unsafe fn malloc(_size: usize) -> *mut core::ffi::c_void { core::ptr::NonNull::dangling().as_ptr() }
592592
/// # pub unsafe fn free(_ptr: *mut core::ffi::c_void) {}
593593
/// # }
594-
/// # #[cfg(any())]
594+
/// # #[cfg(false)]
595595
/// #[allow(unused_extern_crates)]
596596
/// extern crate libc;
597597
///

src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,6 @@ fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[MetaItemInner]) {
3939
}
4040
},
4141
);
42-
} else if list.is_empty() && meta.has_name(sym::all) {
43-
span_lint_and_then(
44-
cx,
45-
NON_MINIMAL_CFG,
46-
meta.span,
47-
"unneeded sub `cfg` when there is no condition",
48-
|_| {},
49-
);
5042
}
5143
}
5244
}

src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,36 @@ mod field_attributes {
4646
// https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1874539800
4747
mod cfgs_between_fields {
4848
#[allow(clippy::non_minimal_cfg)]
49-
fn cfg_all() {
49+
fn cfg_true() {
5050
struct S {
5151
a: i32,
5252
b: i32,
53-
#[cfg(all())]
53+
#[cfg(true)]
5454
c: i32,
5555
d: i32,
5656
}
5757
let s = S {
5858
a: 3,
5959
//~^ inconsistent_struct_constructor
6060
b: 2,
61-
#[cfg(all())]
61+
#[cfg(true)]
6262
c: 1,
6363
d: 0,
6464
};
6565
}
6666

67-
fn cfg_any() {
67+
fn cfg_false() {
6868
struct S {
6969
a: i32,
7070
b: i32,
71-
#[cfg(any())]
71+
#[cfg(false)]
7272
c: i32,
7373
d: i32,
7474
}
7575
let s = S {
7676
a: 3,
7777
//~^ inconsistent_struct_constructor
78-
#[cfg(any())]
78+
#[cfg(false)]
7979
c: 1,
8080
b: 2,
8181
d: 0,

0 commit comments

Comments
 (0)