diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 3e754c33cad6a..08401223722df 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -7,6 +7,7 @@ use rustc_errors::{Applicability, Diagnostic, PResult, msg}; use rustc_feature::{Features, GatedCfg, find_gated_cfg}; use rustc_hir::attrs::CfgEntry; use rustc_hir::{AttrPath, RustcVersion, Target}; +use rustc_lint_defs::builtin::EMPTY_CFG_PREDICATE; use rustc_parse::parser::{ForceCollect, Parser, Recovery}; use rustc_parse::{exp, parse_in}; use rustc_session::Session; @@ -19,6 +20,7 @@ use thin_vec::ThinVec; use crate::attributes::AttributeSafety; use crate::context::{AcceptContext, ShouldEmit}; +use crate::diagnostics::EmptyCfgPredictate; use crate::parser::{ AllowExprMetavar, ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser, }; @@ -92,14 +94,42 @@ pub fn parse_cfg_entry( }; CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span) } - Some(sym::any) => CfgEntry::Any( - list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(), - list.span, - ), - Some(sym::all) => CfgEntry::All( - list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(), - list.span, - ), + Some(sym::any) => { + if list.is_empty() && !list.span.from_expansion() { + let span = meta.span(); + cx.emit_lint( + EMPTY_CFG_PREDICATE, + EmptyCfgPredictate { + predicate_span: span, + predicate: sym::any, + lit: false, + }, + span, + ); + } + CfgEntry::Any( + list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(), + list.span, + ) + } + Some(sym::all) => { + if list.is_empty() && !list.span.from_expansion() { + let span = meta.span(); + cx.emit_lint( + EMPTY_CFG_PREDICATE, + EmptyCfgPredictate { + predicate_span: span, + predicate: sym::all, + lit: true, + }, + span, + ); + } + CfgEntry::All( + list.mixed().flat_map(|sub_item| parse_cfg_entry(cx, sub_item)).collect(), + list.span, + ) + } Some(sym::target) => parse_cfg_entry_target(cx, list, meta.span())?, Some(sym::version) => parse_cfg_entry_version(cx, list, meta.span())?, _ => { diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 98b72f2fa97f6..046230894411f 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -780,6 +780,23 @@ pub(crate) mod unexpected_cfg_value { } } +#[derive(Diagnostic)] +#[diag("use of empty `cfg({$predicate}())`")] +#[note( + "this used to be a common pattern before `cfg(true)` and `cfg(false)` were added to the language in Rust 1.88" +)] +pub(crate) struct EmptyCfgPredictate { + #[suggestion( + "consider using a boolean literal", + code = "{lit}", + applicability = "machine-applicable", + style = "verbose" + )] + pub predicate_span: Span, + pub predicate: Symbol, + pub lit: bool, +} + #[derive(Diagnostic)] pub(crate) enum InvalidOnClause { #[diag("empty `on`-clause in `#[rustc_on_unimplemented]`", code = E0232)] diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index d38b1cf47bd6f..6ef2a16ccb00a 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -46,6 +46,7 @@ pub mod hardwired { DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, + EMPTY_CFG_PREDICATE, EXPLICIT_BUILTIN_CFGS_IN_FLAGS, EXPORTED_PRIVATE_DEPENDENCIES, FFI_UNWIND_CALLS, @@ -5578,3 +5579,31 @@ declare_lint! { "usage of `unsafe` code and other potentially unsound constructs", @eval_always = true } + +declare_lint! { + /// The `empty_cfg_predicate` lint detects the use of empty `cfg` predicate lists. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(empty_cfg_predicate)] + /// #[cfg(any())] + /// fn foo() {} + /// + /// #[cfg(all())] + /// fn bar() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The meaning of `cfg(any())` and `cfg(all())` is not immediately obvious; + /// `cfg(false)` and `cfg(true)` respectively may be used instead. + /// This used to be a common pattern before `cfg(true)` and `cfg(false)` + /// were added to the language in Rust 1.88 + pub EMPTY_CFG_PREDICATE, + Warn, + "detects use of empty `cfg(any())` and `cfg(all())`", + @msrv = "1.88.0"; +} diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs index 5b302e3c2c824..05d12377b157b 100644 --- a/library/std/src/os/raw/mod.rs +++ b/library/std/src/os/raw/mod.rs @@ -9,7 +9,7 @@ macro_rules! alias_core_ffi { ($($t:ident)*) => {$( #[stable(feature = "raw_os", since = "1.1.0")] #[doc = include_str!(concat!("../../../../core/src/ffi/", stringify!($t), ".md"))] - #[doc(cfg(all()))] + #[doc(cfg(true))] pub type $t = core::ffi::$t; )*} } diff --git a/library/std/src/os/windows/raw.rs b/library/std/src/os/windows/raw.rs index 0ef3adade5c83..f61cc797568d3 100644 --- a/library/std/src/os/windows/raw.rs +++ b/library/std/src/os/windows/raw.rs @@ -7,10 +7,10 @@ use crate::os::raw::c_void; #[stable(feature = "raw_ext", since = "1.1.0")] pub type HANDLE = *mut c_void; #[cfg(target_pointer_width = "32")] -#[doc(cfg(all()))] +#[doc(cfg(true))] #[stable(feature = "raw_ext", since = "1.1.0")] pub type SOCKET = u32; #[cfg(target_pointer_width = "64")] -#[doc(cfg(all()))] +#[doc(cfg(true))] #[stable(feature = "raw_ext", since = "1.1.0")] pub type SOCKET = u64; diff --git a/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed index 0e6778e58d8ab..35f1220df3986 100644 --- a/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed +++ b/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed @@ -44,6 +44,7 @@ mod field_attributes { // https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1874539800 mod cfgs_between_fields { #[allow(clippy::non_minimal_cfg)] + #[allow(empty_cfg_predicate)] fn cfg_all() { struct S { a: i32, @@ -62,6 +63,7 @@ mod cfgs_between_fields { }; } + #[allow(empty_cfg_predicate)] fn cfg_any() { struct S { a: i32, diff --git a/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs index 044844c694429..30dd030b21ac7 100644 --- a/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs +++ b/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs @@ -44,6 +44,7 @@ mod field_attributes { // https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1874539800 mod cfgs_between_fields { #[allow(clippy::non_minimal_cfg)] + #[allow(empty_cfg_predicate)] fn cfg_all() { struct S { a: i32, @@ -62,6 +63,7 @@ mod cfgs_between_fields { }; } + #[allow(empty_cfg_predicate)] fn cfg_any() { struct S { a: i32, diff --git a/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr b/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr index a25185cdf7641..3c7ae1d7b6f94 100644 --- a/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr +++ b/src/tools/clippy/tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr @@ -40,7 +40,7 @@ LL ~ expn_depth: if condition { 1 } else { 0 }, | error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:56:13 + --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:57:13 | LL | / d: 0, LL | | @@ -61,7 +61,7 @@ LL ~ d: 0, | error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:74:13 + --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:76:13 | LL | / d: 0, LL | | diff --git a/src/tools/clippy/tests/ui/double_must_use_unfixable.rs b/src/tools/clippy/tests/ui/double_must_use_unfixable.rs index 88c2502da9f74..c897139327d22 100644 --- a/src/tools/clippy/tests/ui/double_must_use_unfixable.rs +++ b/src/tools/clippy/tests/ui/double_must_use_unfixable.rs @@ -2,13 +2,13 @@ #![expect(clippy::result_unit_err)] #![feature(never_type)] -#[cfg_attr(all(), must_use, deprecated)] +#[cfg_attr(true, must_use, deprecated)] pub fn issue_12320() -> Result<(), ()> { //~^ double_must_use unimplemented!(); } -#[cfg_attr(all(), deprecated, must_use)] +#[cfg_attr(true, deprecated, must_use)] pub fn issue_12320_2() -> Result<(), ()> { //~^ double_must_use unimplemented!(); diff --git a/src/tools/clippy/tests/ui/double_must_use_unfixable.stderr b/src/tools/clippy/tests/ui/double_must_use_unfixable.stderr index ce3de9e36de88..bb66c3a68cf1c 100644 --- a/src/tools/clippy/tests/ui/double_must_use_unfixable.stderr +++ b/src/tools/clippy/tests/ui/double_must_use_unfixable.stderr @@ -5,10 +5,10 @@ LL | pub fn issue_12320() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove `must_use` - --> tests/ui/double_must_use_unfixable.rs:5:19 + --> tests/ui/double_must_use_unfixable.rs:5:18 | -LL | #[cfg_attr(all(), must_use, deprecated)] - | ^^^^^^^^ +LL | #[cfg_attr(true, must_use, deprecated)] + | ^^^^^^^^ = note: alternatively, you may add an explicit reason to the `must_use` attribute = note: `-D clippy::double-must-use` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]` @@ -20,10 +20,10 @@ LL | pub fn issue_12320_2() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove `must_use` - --> tests/ui/double_must_use_unfixable.rs:11:31 + --> tests/ui/double_must_use_unfixable.rs:11:30 | -LL | #[cfg_attr(all(), deprecated, must_use)] - | ^^^^^^^^ +LL | #[cfg_attr(true, deprecated, must_use)] + | ^^^^^^^^ = note: alternatively, you may add an explicit reason to the `must_use` attribute error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed index c2073e1dbe70e..14adafa68a7c5 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed +++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed @@ -126,7 +126,7 @@ pub struct EmptyInBlockComment; pub struct BlockComment; /// Ignore the empty line inside a cfg_attr'd out attribute -#[cfg_attr(any(), multiline( +#[cfg_attr(false, multiline( foo = 1 bar = 2 diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed index 9d3947d245861..ebb4c2799916d 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed +++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed @@ -135,7 +135,7 @@ pub struct EmptyInBlockComment; pub struct BlockComment; /// Ignore the empty line inside a cfg_attr'd out attribute -#[cfg_attr(any(), multiline( +#[cfg_attr(false, multiline( foo = 1 bar = 2 diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs index 6ea274154d151..cf2a44fd54072 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs +++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs @@ -138,7 +138,7 @@ pub struct EmptyInBlockComment; pub struct BlockComment; /// Ignore the empty line inside a cfg_attr'd out attribute -#[cfg_attr(any(), multiline( +#[cfg_attr(false, multiline( foo = 1 bar = 2 diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed b/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed index ed9843c3e13d3..7909c3e22f934 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.edition2021.fixed @@ -211,7 +211,7 @@ fn_in_macro!({ fn issue9150() -> usize { let x = 1; - #[cfg(any())] + #[cfg(false)] panic!("can't see me"); x } diff --git a/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed b/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed index 964d4b9f98d89..11b9978db1501 100644 --- a/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed +++ b/src/tools/clippy/tests/ui/let_and_return.edition2024.fixed @@ -211,7 +211,7 @@ fn_in_macro!({ fn issue9150() -> usize { let x = 1; - #[cfg(any())] + #[cfg(false)] panic!("can't see me"); x } diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs index e7239e90cb3a6..15ed1b8f5c369 100644 --- a/src/tools/clippy/tests/ui/let_and_return.rs +++ b/src/tools/clippy/tests/ui/let_and_return.rs @@ -211,7 +211,7 @@ fn_in_macro!({ fn issue9150() -> usize { let x = 1; - #[cfg(any())] + #[cfg(false)] panic!("can't see me"); x } diff --git a/src/tools/clippy/tests/ui/must_use_unit_unfixable.rs b/src/tools/clippy/tests/ui/must_use_unit_unfixable.rs index 8eeaf36dca290..6f4b4b3b1d23e 100644 --- a/src/tools/clippy/tests/ui/must_use_unit_unfixable.rs +++ b/src/tools/clippy/tests/ui/must_use_unit_unfixable.rs @@ -1,8 +1,8 @@ -#[cfg_attr(all(), must_use, deprecated)] +#[cfg_attr(true, must_use, deprecated)] fn issue_12320() {} //~^ must_use_unit -#[cfg_attr(all(), deprecated, doc = "foo", must_use)] +#[cfg_attr(true, deprecated, doc = "foo", must_use)] fn issue_12320_2() {} //~^ must_use_unit diff --git a/src/tools/clippy/tests/ui/must_use_unit_unfixable.stderr b/src/tools/clippy/tests/ui/must_use_unit_unfixable.stderr index 8b5e556b1b2ed..09d8a73dffdaf 100644 --- a/src/tools/clippy/tests/ui/must_use_unit_unfixable.stderr +++ b/src/tools/clippy/tests/ui/must_use_unit_unfixable.stderr @@ -5,10 +5,10 @@ LL | fn issue_12320() {} | ^^^^^^^^^^^^^^^^ | help: remove `must_use` - --> tests/ui/must_use_unit_unfixable.rs:1:19 + --> tests/ui/must_use_unit_unfixable.rs:1:18 | -LL | #[cfg_attr(all(), must_use, deprecated)] - | ^^^^^^^^ +LL | #[cfg_attr(true, must_use, deprecated)] + | ^^^^^^^^ = note: `-D clippy::must-use-unit` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]` @@ -19,10 +19,10 @@ LL | fn issue_12320_2() {} | ^^^^^^^^^^^^^^^^^^ | help: remove `must_use` - --> tests/ui/must_use_unit_unfixable.rs:5:44 + --> tests/ui/must_use_unit_unfixable.rs:5:43 | -LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)] - | ^^^^^^^^ +LL | #[cfg_attr(true, deprecated, doc = "foo", must_use)] + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/needless_ifs.fixed b/src/tools/clippy/tests/ui/needless_ifs.fixed index 89d5b1da7b3f0..204cec7ba9ae4 100644 --- a/src/tools/clippy/tests/ui/needless_ifs.fixed +++ b/src/tools/clippy/tests/ui/needless_ifs.fixed @@ -67,7 +67,7 @@ fn main() { } if true { - #[cfg(any())] + #[cfg(false)] foo; } diff --git a/src/tools/clippy/tests/ui/needless_ifs.rs b/src/tools/clippy/tests/ui/needless_ifs.rs index 837eaaf9647b0..b248034c445e1 100644 --- a/src/tools/clippy/tests/ui/needless_ifs.rs +++ b/src/tools/clippy/tests/ui/needless_ifs.rs @@ -68,7 +68,7 @@ fn main() { } if true { - #[cfg(any())] + #[cfg(false)] foo; } diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg.fixed b/src/tools/clippy/tests/ui/non_minimal_cfg.fixed index a2b69d0662ee9..e4a57a949a5cd 100644 --- a/src/tools/clippy/tests/ui/non_minimal_cfg.fixed +++ b/src/tools/clippy/tests/ui/non_minimal_cfg.fixed @@ -1,4 +1,5 @@ #![allow(unused)] +#![allow(empty_cfg_predicate)] #[cfg(windows)] //~^ non_minimal_cfg diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg.rs b/src/tools/clippy/tests/ui/non_minimal_cfg.rs index 7178cd189c08d..33072e58b7dda 100644 --- a/src/tools/clippy/tests/ui/non_minimal_cfg.rs +++ b/src/tools/clippy/tests/ui/non_minimal_cfg.rs @@ -1,4 +1,5 @@ #![allow(unused)] +#![allow(empty_cfg_predicate)] #[cfg(all(windows))] //~^ non_minimal_cfg diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg.stderr b/src/tools/clippy/tests/ui/non_minimal_cfg.stderr index 3bf306dd89c2f..0899e1629c83e 100644 --- a/src/tools/clippy/tests/ui/non_minimal_cfg.stderr +++ b/src/tools/clippy/tests/ui/non_minimal_cfg.stderr @@ -1,5 +1,5 @@ error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:3:7 + --> tests/ui/non_minimal_cfg.rs:4:7 | LL | #[cfg(all(windows))] | ^^^^^^^^^^^^ help: try: `windows` @@ -8,19 +8,19 @@ LL | #[cfg(all(windows))] = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]` error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:7:7 + --> tests/ui/non_minimal_cfg.rs:8:7 | LL | #[cfg(any(windows))] | ^^^^^^^^^^^^ help: try: `windows` error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:11:11 + --> tests/ui/non_minimal_cfg.rs:12:11 | LL | #[cfg(all(any(unix), all(not(windows))))] | ^^^^^^^^^ help: try: `unix` error: unneeded sub `cfg` when there is only one condition - --> tests/ui/non_minimal_cfg.rs:11:22 + --> tests/ui/non_minimal_cfg.rs:12:22 | LL | #[cfg(all(any(unix), all(not(windows))))] | ^^^^^^^^^^^^^^^^^ help: try: `not(windows)` diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg2.rs b/src/tools/clippy/tests/ui/non_minimal_cfg2.rs index d073feedb1da2..f561bb35fbccb 100644 --- a/src/tools/clippy/tests/ui/non_minimal_cfg2.rs +++ b/src/tools/clippy/tests/ui/non_minimal_cfg2.rs @@ -1,5 +1,6 @@ //@require-annotations-for-level: WARN #![allow(unused)] +#![allow(empty_cfg_predicate)] #[cfg(all())] //~^ ERROR: unneeded sub `cfg` when there is no condition diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr b/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr index 169d2989aa13d..22b7f2788bed3 100644 --- a/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr +++ b/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr @@ -1,5 +1,5 @@ error: unneeded sub `cfg` when there is no condition - --> tests/ui/non_minimal_cfg2.rs:4:7 + --> tests/ui/non_minimal_cfg2.rs:5:7 | LL | #[cfg(all())] | ^^^^^ diff --git a/src/tools/miri/tests/pass/static_align.rs b/src/tools/miri/tests/pass/static_align.rs index bc6a9bf8af7dc..bd707937f223f 100644 --- a/src/tools/miri/tests/pass/static_align.rs +++ b/src/tools/miri/tests/pass/static_align.rs @@ -1,5 +1,6 @@ #![feature(static_align)] #![deny(non_upper_case_globals)] +#![allow(empty_cfg_predicate)] use std::cell::Cell; diff --git a/tests/incremental/lint-unused-features.rs b/tests/incremental/lint-unused-features.rs index 0bf9730727f74..c1f1485b55d44 100644 --- a/tests/incremental/lint-unused-features.rs +++ b/tests/incremental/lint-unused-features.rs @@ -5,12 +5,12 @@ // Used language features #![feature(decl_macro)] -#![cfg_attr(all(), feature(rustc_attrs))] +#![cfg_attr(true, feature(rustc_attrs))] // Used library features #![feature(error_iter)] //[bfail]~^ ERROR feature `error_iter` is declared but not used -#![cfg_attr(all(), feature(allocator_api))] +#![cfg_attr(true, feature(allocator_api))] //[bfail]~^ ERROR feature `allocator_api` is declared but not used macro m() {} diff --git a/tests/ui/conditional-compilation/cfg-empty-any-all.rs b/tests/ui/conditional-compilation/cfg-empty-any-all.rs index 48ed4342235ca..a678039f9cbb1 100644 --- a/tests/ui/conditional-compilation/cfg-empty-any-all.rs +++ b/tests/ui/conditional-compilation/cfg-empty-any-all.rs @@ -1,4 +1,5 @@ //! Test the behaviour of `cfg(any())` and `cfg(all())` +#![allow(empty_cfg_predicate)] #[cfg(any())] // Equivalent to cfg(false) struct Disabled; diff --git a/tests/ui/conditional-compilation/cfg-empty-any-all.stderr b/tests/ui/conditional-compilation/cfg-empty-any-all.stderr index 1674f2def23a9..a652baeb91dde 100644 --- a/tests/ui/conditional-compilation/cfg-empty-any-all.stderr +++ b/tests/ui/conditional-compilation/cfg-empty-any-all.stderr @@ -1,11 +1,11 @@ error[E0425]: cannot find value `Disabled` in this scope - --> $DIR/cfg-empty-any-all.rs:10:13 + --> $DIR/cfg-empty-any-all.rs:11:13 | LL | let _ = Disabled; | ^^^^^^^^ not found in this scope | note: found an item that was configured out - --> $DIR/cfg-empty-any-all.rs:4:8 + --> $DIR/cfg-empty-any-all.rs:5:8 | LL | #[cfg(any())] // Equivalent to cfg(false) | -- the item is gated here diff --git a/tests/ui/lint/empty-cfg-predicate.highvers.stderr b/tests/ui/lint/empty-cfg-predicate.highvers.stderr new file mode 100644 index 0000000000000..fb514faf7af89 --- /dev/null +++ b/tests/ui/lint/empty-cfg-predicate.highvers.stderr @@ -0,0 +1,33 @@ +error: use of empty `cfg(any())` + --> $DIR/empty-cfg-predicate.rs:11:7 + | +LL | #[cfg(any())] + | ^^^^^ + | + = note: this used to be a common pattern before `cfg(true)` and `cfg(false)` were added to the language in Rust 1.88 +note: the lint level is defined here + --> $DIR/empty-cfg-predicate.rs:8:9 + | +LL | #![deny(empty_cfg_predicate)] + | ^^^^^^^^^^^^^^^^^^^ +help: consider using a boolean literal + | +LL - #[cfg(any())] +LL + #[cfg(false)] + | + +error: use of empty `cfg(all())` + --> $DIR/empty-cfg-predicate.rs:15:7 + | +LL | #[cfg(all())] + | ^^^^^ + | + = note: this used to be a common pattern before `cfg(true)` and `cfg(false)` were added to the language in Rust 1.88 +help: consider using a boolean literal + | +LL - #[cfg(all())] +LL + #[cfg(true)] + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/empty-cfg-predicate.novers.stderr b/tests/ui/lint/empty-cfg-predicate.novers.stderr new file mode 100644 index 0000000000000..fb514faf7af89 --- /dev/null +++ b/tests/ui/lint/empty-cfg-predicate.novers.stderr @@ -0,0 +1,33 @@ +error: use of empty `cfg(any())` + --> $DIR/empty-cfg-predicate.rs:11:7 + | +LL | #[cfg(any())] + | ^^^^^ + | + = note: this used to be a common pattern before `cfg(true)` and `cfg(false)` were added to the language in Rust 1.88 +note: the lint level is defined here + --> $DIR/empty-cfg-predicate.rs:8:9 + | +LL | #![deny(empty_cfg_predicate)] + | ^^^^^^^^^^^^^^^^^^^ +help: consider using a boolean literal + | +LL - #[cfg(any())] +LL + #[cfg(false)] + | + +error: use of empty `cfg(all())` + --> $DIR/empty-cfg-predicate.rs:15:7 + | +LL | #[cfg(all())] + | ^^^^^ + | + = note: this used to be a common pattern before `cfg(true)` and `cfg(false)` were added to the language in Rust 1.88 +help: consider using a boolean literal + | +LL - #[cfg(all())] +LL + #[cfg(true)] + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/empty-cfg-predicate.rs b/tests/ui/lint/empty-cfg-predicate.rs new file mode 100644 index 0000000000000..e8c7a3d627a4c --- /dev/null +++ b/tests/ui/lint/empty-cfg-predicate.rs @@ -0,0 +1,18 @@ +//@ revisions: novers lowvers highvers +//@[lowvers] compile-flags: -Zlint-rust-version=1.87.0 +//@[highvers] compile-flags: -Zlint-rust-version=1.89.0 +//@[lowvers] check-pass + +//! Check that we suggest `cfg(any())` -> `false` and `cfg(all())` -> true +//! Additionally tests the behaviour of empty cfg predicates. +#![deny(empty_cfg_predicate)] +#![crate_type = "lib"] + +#[cfg(any())] +//[novers]~^ ERROR: use of empty `cfg(any())` +//[highvers]~^^ ERROR: use of empty `cfg(any())` +pub struct A; +#[cfg(all())] +//[novers]~^ ERROR: use of empty `cfg(all())` +//[highvers]~^^ ERROR: use of empty `cfg(all())` +pub struct B; diff --git a/tests/ui/lint/unused-features/unused-language-features.rs b/tests/ui/lint/unused-features/unused-language-features.rs index 9334c1df0408a..6a045eace361b 100644 --- a/tests/ui/lint/unused-features/unused-language-features.rs +++ b/tests/ui/lint/unused-features/unused-language-features.rs @@ -12,11 +12,11 @@ //~^ ERROR feature `asm_unwind` is declared but not used // Enabled via cfg_attr, unused -#![cfg_attr(all(), feature(negative_impls))] +#![cfg_attr(true, feature(negative_impls))] //~^ ERROR feature `negative_impls` is declared but not used // Not enabled via cfg_attr, so should not warn even if unused -#![cfg_attr(any(), feature(never_type))] +#![cfg_attr(false, feature(never_type))] macro_rules! use_asm_unwind { () => { diff --git a/tests/ui/lint/unused-features/unused-language-features.stderr b/tests/ui/lint/unused-features/unused-language-features.stderr index 3cede1a6fe726..acdd720c95f8a 100644 --- a/tests/ui/lint/unused-features/unused-language-features.stderr +++ b/tests/ui/lint/unused-features/unused-language-features.stderr @@ -29,10 +29,10 @@ LL | #![feature(asm_unwind)] | ^^^^^^^^^^ error: feature `negative_impls` is declared but not used - --> $DIR/unused-language-features.rs:15:28 + --> $DIR/unused-language-features.rs:15:27 | -LL | #![cfg_attr(all(), feature(negative_impls))] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(true, feature(negative_impls))] + | ^^^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/lint/unused-features/unused-library-features.rs b/tests/ui/lint/unused-features/unused-library-features.rs index 2f53ab66b160c..3d40502e34873 100644 --- a/tests/ui/lint/unused-features/unused-library-features.rs +++ b/tests/ui/lint/unused-features/unused-library-features.rs @@ -8,5 +8,5 @@ //~^ WARN the feature `is_sorted` has been stable since 1.82.0 and no longer requires an attribute to enable // Enabled via cfg_attr, unused -#![cfg_attr(all(), feature(slice_ptr_get))] +#![cfg_attr(true, feature(slice_ptr_get))] //~^ ERROR feature `slice_ptr_get` is declared but not used diff --git a/tests/ui/lint/unused-features/unused-library-features.stderr b/tests/ui/lint/unused-features/unused-library-features.stderr index bf71e269e2f0f..ccb406f290a91 100644 --- a/tests/ui/lint/unused-features/unused-library-features.stderr +++ b/tests/ui/lint/unused-features/unused-library-features.stderr @@ -19,10 +19,10 @@ LL | #![deny(unused_features)] | ^^^^^^^^^^^^^^^ error: feature `slice_ptr_get` is declared but not used - --> $DIR/unused-library-features.rs:11:28 + --> $DIR/unused-library-features.rs:11:27 | -LL | #![cfg_attr(all(), feature(slice_ptr_get))] - | ^^^^^^^^^^^^^ +LL | #![cfg_attr(true, feature(slice_ptr_get))] + | ^^^^^^^^^^^^^ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/lint/unused-features/used-language-features.rs b/tests/ui/lint/unused-features/used-language-features.rs index ddc40ce2e96b9..69d30b53f8d8f 100644 --- a/tests/ui/lint/unused-features/used-language-features.rs +++ b/tests/ui/lint/unused-features/used-language-features.rs @@ -5,7 +5,7 @@ // Used language features #![feature(decl_macro)] -#![cfg_attr(all(), feature(rustc_attrs))] +#![cfg_attr(true, feature(rustc_attrs))] macro m() {} pub fn use_decl_macro() { diff --git a/tests/ui/lint/unused-features/used-library-features.rs b/tests/ui/lint/unused-features/used-library-features.rs index 1747c7741880e..7e524f5ed677c 100644 --- a/tests/ui/lint/unused-features/used-library-features.rs +++ b/tests/ui/lint/unused-features/used-library-features.rs @@ -5,7 +5,7 @@ // Used library features #![feature(error_iter)] -#![cfg_attr(all(), feature(allocator_api))] +#![cfg_attr(true, feature(allocator_api))] pub fn use_error_iter(e: &(dyn std::error::Error + 'static)) { for _ in e.sources() {}