Auto merge of #119473 - Urgau:check-cfg-explicit-none, r=petrochenkov

Add explicit `none()` value variant in check-cfg

This PR adds an explicit none value variant in check-cfg values: `values(none())`.

Currently the only way to define the none variant is with an empty `values()` which means that if someone has a cfg that takes none and strings they need to use two invocations: `--check-cfg=cfg(foo) --check-cfg=cfg(foo, values("bar"))`.
Which would now be `--check-cfg=cfg(foo, values(none(),"bar"))`, this is simpler and easier to understand.

`--check-cfg=cfg(foo)`, `--check-cfg=cfg(foo, values())` and `--check-cfg=cfg(foo, values(none()))` would be equivalent.

*Another motivation for doing this is to make empty `values()` actually means no-values, but this is orthogonal to this PR and adding `none()` is sufficient in it-self.*

`@rustbot` label +F-check-cfg
r? `@petrochenkov`
This commit is contained in:
bors 2024-01-13 06:17:46 +00:00
commit 7585c62658
12 changed files with 101 additions and 6 deletions

View File

@ -202,8 +202,15 @@ macro_rules! error {
if !args.is_empty() {
error!("`any()` must be empty");
}
} else if arg.has_name(sym::none)
&& let Some(args) = arg.meta_item_list()
{
values.insert(None);
if !args.is_empty() {
error!("`none()` must be empty");
}
} else {
error!("`values()` arguments must be string literals or `any()`");
error!("`values()` arguments must be string literals, `none()` or `any()`");
}
}
} else {

View File

@ -36,12 +36,16 @@ present in the list of expected values. If `"value"` is not in it, then `rustc`
*The command line `--cfg` arguments are currently *NOT* checked but may very well be checked in
the future.*
To check for the _none_ value (ie `#[cfg(foo)]`) one can use the `none()` predicate inside
`values()`: `values(none())`. It can be followed or precessed by any number of `"value"`.
To enable checking of values, but to provide an *none*/empty set of expected values
(ie. expect `#[cfg(name)]`), use these forms:
```bash
rustc --check-cfg 'cfg(name)'
rustc --check-cfg 'cfg(name, values())'
rustc --check-cfg 'cfg(name, values(none()))'
```
To enable checking of name but not values (i.e. unknown expected values), use this form:
@ -112,7 +116,7 @@ This table describe the equivalence of a `--cfg` argument to a `--check-cfg` arg
| `--cfg` | `--check-cfg` |
|-----------------------------|----------------------------------------------------------|
| *nothing* | *nothing* or `--check-cfg=cfg()` (to enable the checking) |
| `--cfg foo` | `--check-cfg=cfg(foo) or --check-cfg=cfg(foo, values())` |
| `--cfg foo` | `--check-cfg=cfg(foo), --check-cfg=cfg(foo, values())` or `--check-cfg=cfg(foo, values(none()))` |
| `--cfg foo=""` | `--check-cfg=cfg(foo, values(""))` |
| `--cfg foo="bar"` | `--check-cfg=cfg(foo, values("bar"))` |
| `--cfg foo="1" --cfg foo="2"` | `--check-cfg=cfg(foo, values("1", "2"))` |

View File

@ -0,0 +1,2 @@
error: invalid `--check-cfg` argument: `cfg(none())` (`cfg()` arguments must be simple identifiers, `any()` or `values(...)`)

View File

@ -1,2 +1,2 @@
error: invalid `--check-cfg` argument: `cfg(foo,values(bar))` (`values()` arguments must be string literals or `any()`)
error: invalid `--check-cfg` argument: `cfg(foo,values(bar))` (`values()` arguments must be string literals, `none()` or `any()`)

View File

@ -1,2 +1,2 @@
error: invalid `--check-cfg` argument: `cfg(foo,values("bar",bar,"bar"))` (`values()` arguments must be string literals or `any()`)
error: invalid `--check-cfg` argument: `cfg(foo,values("bar",bar,"bar"))` (`values()` arguments must be string literals, `none()` or `any()`)

View File

@ -0,0 +1,2 @@
error: invalid `--check-cfg` argument: `cfg(foo,values(none("test")))` (`none()` must be empty)

View File

@ -7,6 +7,7 @@
// revisions: values_any_missing_values values_any_before_ident ident_in_values_1
// revisions: ident_in_values_2 unknown_meta_item_1 unknown_meta_item_2 unknown_meta_item_3
// revisions: mixed_values_any mixed_any any_values giberich unterminated
// revisions: none_not_empty cfg_none
//
// compile-flags: -Z unstable-options
// [anything_else]compile-flags: --check-cfg=anything_else(...)
@ -24,9 +25,11 @@
// [unknown_meta_item_1]compile-flags: --check-cfg=abc()
// [unknown_meta_item_2]compile-flags: --check-cfg=cfg(foo,test())
// [unknown_meta_item_3]compile-flags: --check-cfg=cfg(foo,values(test()))
// [none_not_empty]compile-flags: --check-cfg=cfg(foo,values(none("test")))
// [mixed_values_any]compile-flags: --check-cfg=cfg(foo,values("bar",any()))
// [mixed_any]compile-flags: --check-cfg=cfg(any(),values(any()))
// [any_values]compile-flags: --check-cfg=cfg(any(),values())
// [cfg_none]compile-flags: --check-cfg=cfg(none())
// [giberich]compile-flags: --check-cfg=cfg(...)
// [unterminated]compile-flags: --check-cfg=cfg(

View File

@ -1,2 +1,2 @@
error: invalid `--check-cfg` argument: `cfg(foo,values(test()))` (`values()` arguments must be string literals or `any()`)
error: invalid `--check-cfg` argument: `cfg(foo,values(test()))` (`values()` arguments must be string literals, `none()` or `any()`)

View File

@ -6,7 +6,7 @@
// compile-flags: --check-cfg=cfg(values,simple,mixed,empty)
// [simple]compile-flags: --check-cfg=cfg(test) --check-cfg=cfg(feature)
// [mixed]compile-flags: --check-cfg=cfg(test,feature)
// [empty]compile-flags: --check-cfg=cfg(test,feature,values())
// [empty]compile-flags: --check-cfg=cfg(test,feature,values(none()))
#[cfg(feature = "foo")]
//~^ WARNING unexpected `cfg` condition value

View File

@ -0,0 +1,27 @@
warning: unexpected `cfg` condition value: `too`
--> $DIR/values-none.rs:11:7
|
LL | #[cfg(foo = "too")]
| ^^^--------
| |
| help: remove the value
|
= note: no expected value for `foo`
= help: to expect this configuration use `--check-cfg=cfg(foo, values("too"))`
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value: `bar`
--> $DIR/values-none.rs:16:7
|
LL | #[cfg(foo = "bar")]
| ^^^--------
| |
| help: remove the value
|
= note: no expected value for `foo`
= help: to expect this configuration use `--check-cfg=cfg(foo, values("bar"))`
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
warning: 2 warnings emitted

View File

@ -0,0 +1,27 @@
warning: unexpected `cfg` condition value: `too`
--> $DIR/values-none.rs:11:7
|
LL | #[cfg(foo = "too")]
| ^^^--------
| |
| help: remove the value
|
= note: no expected value for `foo`
= help: to expect this configuration use `--check-cfg=cfg(foo, values("too"))`
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value: `bar`
--> $DIR/values-none.rs:16:7
|
LL | #[cfg(foo = "bar")]
| ^^^--------
| |
| help: remove the value
|
= note: no expected value for `foo`
= help: to expect this configuration use `--check-cfg=cfg(foo, values("bar"))`
= note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
warning: 2 warnings emitted

View File

@ -0,0 +1,23 @@
// check-pass
//
// revisions: explicit implicit
// compile-flags: -Zunstable-options
// [explicit]compile-flags: --check-cfg=cfg(foo,values(none()))
// [implicit]compile-flags: --check-cfg=cfg(foo)
// [simple] compile-flags: --check-cfg=cfg(foo,values(none(),"too"))
// [concat_1]compile-flags: --check-cfg=cfg(foo) --check-cfg=cfg(foo,values("too"))
// [concat_2]compile-flags: --check-cfg=cfg(foo,values("too")) --check-cfg=cfg(foo)
#[cfg(foo = "too")]
//[explicit]~^ WARNING unexpected `cfg` condition value
//[implicit]~^^ WARNING unexpected `cfg` condition value
fn foo_too() {}
#[cfg(foo = "bar")]
//~^ WARNING unexpected `cfg` condition value
fn foo_bar() {}
#[cfg(foo)]
fn foo() {}
fn main() {}