about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-17 14:01:05 +0000
committerbors <bors@rust-lang.org>2024-01-17 14:01:05 +0000
commitc58a5da7d48ff3887afe4c618dc04defdee3dab5 (patch)
tree439e5fddd670d6a8895696d947e44dfbc9342912 /src/doc
parent52790a98e568f2e4f37b041ce353c660f5fb073d (diff)
parent41b69aae912aa9a1a8d5ed9518e73d136b42e7ca (diff)
downloadrust-c58a5da7d48ff3887afe4c618dc04defdee3dab5.tar.gz
rust-c58a5da7d48ff3887afe4c618dc04defdee3dab5.zip
Auto merge of #119930 - Urgau:check-cfg-empty-values-means-empty, r=petrochenkov
Add way to express that no values are expected with check-cfg

This PR adds way to express no-values (no values expected) with `--check-cfg` by making empty `values()` no longer mean `values(none())` (internal: `&[None]`) and now be an empty list (internal: `&[]`).

### Context

Currently `--check-cfg` has a way to express that _any value is expected_ with `values(any())`, but has no way to do the inverse and say that _no value is expected_.

This would be particularly useful for build systems that control a config name and it's values as they could always declare a config name as expected and if in the current state they have values pass them and if not pass an empty list.

To give a more concrete example, Cargo `--check-cfg` currently needs to generate:
 - `--check-cfg=cfg(feature, values(...))` for the case with declared features
 - and `--check-cfg=cfg()` for the case without any features declared

This means that when there are no features declared, users will get an `unexpected config name` but from the point of view of Cargo the config name `feature` is expected, it's just that for now there aren't any values for it.

See [Cargo `check_cfg_args` function](https://github.com/rust-lang/cargo/blob/92395d90106b3b61bcb68bcf2069052c93771764/src/cargo/core/compiler/mod.rs#L1263-L1281) for more details.

### De-specializing *empty* `values()`

To solve this issue I propose that we "de-specialize" empty `values()` to no longer mean `values(none())` but to actually mean empty set/list. This is one of the last source of confusion for my-self and others with the `--check-cfg` syntax.

> The confusing part here is that an empty `values()` currently means the same as `values(none())`, i.e. an expected list of values with the _none_ variant (as in `#[cfg(name)]` where the value is none) instead of meaning an empty set.

Before the new `cfg()` syntax, defining the _none_ variant was only possible under certain circumstances, so in https://github.com/rust-lang/rust/pull/111068 I decided to make `values()` to mean the _none_ variant, but it is no longer necessary since https://github.com/rust-lang/rust/pull/119473 which introduced the `none()` syntax.

A simplified representation of the proposed "de-specialization" would be:

| Syntax                                  | List/set of expected values |
|-----------------------------------------|-----------------------------|
| `cfg(name)`/`cfg(name, values(none()))` | `&[None]`                   |
| `cfg(name, values())`                   | `&[]`                       |

Note that I have my-self made the mistake of using an empty `values()` as meaning empty set, see https://github.com/rust-lang/cargo/pull/13011.

`@rustbot` label +F-check-cfg
r? `@petrochenkov`
cc `@epage`
Diffstat (limited to 'src/doc')
-rw-r--r--src/doc/unstable-book/src/compiler-flags/check-cfg.md25
1 files changed, 13 insertions, 12 deletions
diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
index 78bc8dceb78..bf83f6ad7c5 100644
--- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md
+++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
@@ -44,15 +44,20 @@ To enable checking of values, but to provide an *none*/empty set of expected val
 
 ```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:
+To enable checking of name but not values, use one of these forms:
 
-```bash
-rustc --check-cfg 'cfg(name, values(any()))'
-```
+  - No expected values (_will lint on every value_):
+    ```bash
+    rustc --check-cfg 'cfg(name, values())'
+    ```
+
+  - Unknown expected values (_will never lint_):
+    ```bash
+    rustc --check-cfg 'cfg(name, values(any()))'
+    ```
 
 To avoid repeating the same set of values, use this form:
 
@@ -114,18 +119,14 @@ as argument to `--check-cfg`.
 This table describe the equivalence of a `--cfg` argument to a `--check-cfg` argument.
 
 | `--cfg`                       | `--check-cfg`                                              |
-|-----------------------------|----------------------------------------------------------|
+|-------------------------------|------------------------------------------------------------|
 | *nothing*                     | *nothing* or `--check-cfg=cfg()` (to enable the checking)  |
-| `--cfg foo`                   | `--check-cfg=cfg(foo), --check-cfg=cfg(foo, values())` or `--check-cfg=cfg(foo, values(none()))`   |
+| `--cfg foo`                   | `--check-cfg=cfg(foo)` 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"))`                   |
 | `--cfg foo="1" --cfg bar="2"` | `--check-cfg=cfg(foo, values("1")) --check-cfg=cfg(bar, values("2"))` |
-| `--cfg foo --cfg foo="bar"`   | `--check-cfg=cfg(foo) --check-cfg=cfg(foo, values("bar"))` |
-
-NOTE: There is (currently) no way to express that a condition name is expected but no (!= none)
-values are expected. Passing an empty `values()` means *(none)* in the sense of `#[cfg(foo)]`
-with no value. Users are expected to NOT pass a `--check-cfg` with that condition name.
+| `--cfg foo --cfg foo="bar"`   | `--check-cfg=cfg(foo, values(none(), "bar"))`              |
 
 ### Example: Cargo-like `feature` example