about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-09 14:50:14 +0000
committerbors <bors@rust-lang.org>2024-01-09 14:50:14 +0000
commit5876c8cdfd3df742c334d6447d44d760c77103b6 (patch)
treeb2437656721ba0a5f4068566975525a9bab87974 /src/doc
parentbe00c5a9b89161b7f45ba80340f709e8e41122f9 (diff)
parentf41d7739880e72743a74722ae6fcc1be9f7b4e5c (diff)
downloadrust-5876c8cdfd3df742c334d6447d44d760c77103b6.tar.gz
rust-5876c8cdfd3df742c334d6447d44d760c77103b6.zip
Auto merge of #119767 - GuillaumeGomez:rollup-fbp26yb, r=GuillaumeGomez
Rollup of 9 pull requests

Successful merges:

 - #117556 (Disallow reference to `static mut` and adding `static_mut_ref` lint)
 - #118748 (std: getrandom simplification for freebsd.)
 - #119282 (Rework and improve the unstable documentation of check-cfg)
 - #119527 (don't reexport atomic::ordering via rustc_data_structures, use std import)
 - #119668 (Simplify implementation of MIR promotion)
 - #119699 (Merge dead bb pruning and unreachable bb deduplication.)
 - #119723 (Remove `-Zdont-buffer-diagnostics`.)
 - #119756 (rustdoc-search: reuse individual types in function signatures)
 - #119758 (GNU/Hurd: unconditionally use inline stack probes)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src/doc')
-rw-r--r--src/doc/unstable-book/src/compiler-flags/check-cfg.md224
1 files changed, 123 insertions, 101 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 8ab6e83d99e..e8fc2fe986e 100644
--- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md
+++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
@@ -4,18 +4,16 @@ The tracking issue for this feature is: [#82450](https://github.com/rust-lang/ru
 
 ------------------------
 
-This feature allows you to enable complete or partial checking of configuration.
+This feature enables checking of conditional configuration.
 
 `rustc` accepts the `--check-cfg` option, which specifies whether to check conditions and how to
-check them. The `--check-cfg` option takes a value, called the _check cfg specification_. The
-check cfg specification is parsed using the Rust metadata syntax, just as the `--cfg` option is.
+check them. The `--check-cfg` option takes a value, called the _check cfg specification_.
+This specification has one form:
 
-`--check-cfg` option take one form:
+1. `--check-cfg cfg(...)` mark a configuration and it's expected values as expected.
 
-1. `--check-cfg cfg(...)` enables checking the values within list-valued conditions.
-
-NOTE: No implicit expectation is added when using `--cfg` for both forms. Users are expected to
-pass all expected names and values using `cfg(...)`.
+*No implicit expectation is added when using `--cfg`. Users are expected to
+pass all expected names and values using the _check cfg specification_.*
 
 ## The `cfg(...)` form
 
@@ -23,7 +21,7 @@ The `cfg(...)` form enables checking the values within list-valued conditions. I
 basic form:
 
 ```bash
-rustc --check-cfg 'cfg(name1, ..., nameN, values("value1", "value2", ... "valueN"))'
+rustc --check-cfg 'cfg(name, values("value1", "value2", ... "valueN"))'
 ```
 
 where `name` is a bare identifier (has no quotes) and each `"value"` term is a quoted literal
@@ -31,162 +29,186 @@ string. `name` specifies the name of the condition, such as `feature` or `my_cfg
 
 When the `cfg(...)` option is specified, `rustc` will check every `#[cfg(name = "value")]`
 attribute, `#[cfg_attr(name = "value")]` attribute, `#[link(name = "a", cfg(name = "value"))]`
-and `cfg!(name = "value")` call. It will check that the `"value"` specified is present in the
-list of expected values. If `"value"` is not in it, then `rustc` will report an `unexpected_cfgs`
-lint diagnostic. The default diagnostic level for this lint is `Warn`.
+attribute and `cfg!(name = "value")` macro call. It will check that the `"value"` specified is
+present in the list of expected values. If `"value"` is not in it, then `rustc` will report an
+`unexpected_cfgs` lint diagnostic. The default diagnostic level for this lint is `Warn`.
 
-The command line `--cfg` arguments are currently *NOT* checked but may very well be checked in
-the future.
+*The command line `--cfg` arguments are currently *NOT* checked but may very well be checked in
+the future.*
 
-To enable checking of values, but to provide an empty set of expected values, use these forms:
+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(name1, ..., nameN)'
-rustc --check-cfg 'cfg(name1, ..., nameN, values())'
+rustc --check-cfg 'cfg(name)'
+rustc --check-cfg 'cfg(name, values())'
 ```
 
 To enable checking of name but not values (i.e. unknown expected values), use this form:
 
 ```bash
-rustc --check-cfg 'cfg(name1, ..., nameN, values(any()))'
+rustc --check-cfg 'cfg(name, values(any()))'
+```
+
+To avoid repeating the same set of values, use this form:
+
+```bash
+rustc --check-cfg 'cfg(name1, ..., nameN, values("value1", "value2", ... "valueN"))'
 ```
 
 The `--check-cfg cfg(...)` option can be repeated, both for the same condition name and for
 different names. If it is repeated for the same condition name, then the sets of values for that
-condition are merged together (presedence is given to `any()`).
+condition are merged together (precedence is given to `values(any())`).
 
 ## Well known names and values
 
 `rustc` has a internal list of well known names and their corresponding values.
 Those well known names and values follows the same stability as what they refer to.
 
-Well known values checking is always enabled as long as a `--check-cfg` argument is present.
+Well known names and values checking is always enabled as long as at least one
+`--check-cfg` argument is present.
+
+As of `2024-01-09T`, the list of known names is as follows:
+
+<!--- See CheckCfg::fill_well_known in compiler/rustc_session/src/config.rs -->
+
+ - `debug_assertions`
+ - `doc`
+ - `doctest`
+ - `miri`
+ - `overflow_checks`
+ - `panic`
+ - `proc_macro`
+ - `relocation_model`
+ - `sanitize`
+ - `sanitizer_cfi_generalize_pointers`
+ - `sanitizer_cfi_normalize_integers`
+ - `target_abi`
+ - `target_arch`
+ - `target_endian`
+ - `target_env`
+ - `target_family`
+ - `target_feature`
+ - `target_has_atomic`
+ - `target_has_atomic_equal_alignment`
+ - `target_has_atomic_load_store`
+ - `target_os`
+ - `target_pointer_width`
+ - `target_thread_local`
+ - `target_vendor`
+ - `test`
+ - `unix`
+ - `windows`
+
+Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())`
+as argument to `--check-cfg`.
 
-Well known names checking is always enable as long as a `--check-cfg` argument is present
-**unless** any `cfg(any())` argument is passed.
+## Examples
 
-To disable checking of well known names, use this form:
+### Equivalence table
 
-```bash
-rustc --check-cfg 'cfg(any())'
-```
+This table describe the equivalence of a `--cfg` argument to a `--check-cfg` argument.
 
-NOTE: If one want to enable values and names checking without having any cfg to declare, one
-can use an empty `cfg()` argument.
+| `--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, 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"))` |
 
-## Examples
+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.
+
+### Example: Cargo-like `feature` example
 
 Consider this command line:
 
 ```bash
 rustc --check-cfg 'cfg(feature, values("lion", "zebra"))' \
-      --cfg 'feature="lion"' -Z unstable-options \
-      example.rs
+      --cfg 'feature="lion"' -Z unstable-options example.rs
 ```
 
 This command line indicates that this crate has two features: `lion` and `zebra`. The `lion`
-feature is enabled, while the `zebra` feature is disabled. Exhaustive checking of names and
-values are enabled by default. Consider compiling this code:
+feature is enabled, while the `zebra` feature is disabled.
+Given the `--check-cfg` arguments, exhaustive checking of names and
+values are enabled.
 
+`example.rs`:
 ```rust
-// This is expected, and tame_lion() will be compiled
-#[cfg(feature = "lion")]
+#[cfg(feature = "lion")]     // This condition is expected, as "lion" is an expected value of `feature`
 fn tame_lion(lion: Lion) {}
 
-// This is expected, and ride_zebra() will NOT be compiled.
-#[cfg(feature = "zebra")]
-fn ride_zebra(zebra: Zebra) {}
+#[cfg(feature = "zebra")]    // This condition is expected, as "zebra" is an expected value of `feature`
+                             // but the condition will still evaluate to false
+                             // since only --cfg feature="lion" was passed
+fn ride_zebra(z: Zebra) {}
 
-// This is UNEXPECTED, and will cause a compiler warning (by default).
-#[cfg(feature = "platypus")]
+#[cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT an expected value of
+                             // `feature` and will cause a compiler warning (by default).
 fn poke_platypus() {}
 
-// This is UNEXPECTED, because 'feechure' is not a known condition name,
-// and will cause a compiler warning (by default).
-#[cfg(feechure = "lion")]
+#[cfg(feechure = "lion")]    // This condition is UNEXPECTED, as 'feechure' is NOT a expected condition
+                             // name, no `cfg(feechure, ...)` was passed in `--check-cfg`
 fn tame_lion() {}
 
-// This is UNEXPECTED, because 'windows' is a well known condition name,
-// and because 'windows' doesn't take any values,
-// and will cause a compiler warning (by default).
-#[cfg(windows = "unix")]
+#[cfg(windows = "unix")]     // This condition is UNEXPECTED, as while 'windows' is a well known
+                             // condition name, it doens't expect any values
 fn tame_windows() {}
 ```
 
-### Example: Checking condition names, but not values
+### Example: Multiple names and values
 
 ```bash
-# This turns on checking for condition names, but not values, such as 'feature' values.
-rustc --check-cfg 'cfg(is_embedded, has_feathers, values(any()))' \
-      --cfg has_feathers -Z unstable-options
+rustc --check-cfg 'cfg(is_embedded, has_feathers)' \
+      --check-cfg 'cfg(feature, values("zapping", "lasers"))' \
+      --cfg has_feathers --cfg 'feature="zapping"' -Z unstable-options
 ```
 
 ```rust
-#[cfg(is_embedded)]         // This is expected as "is_embedded" was provided in cfg()
-fn do_embedded() {}         // and because names exhaustiveness was not disabled
-
-#[cfg(has_feathers)]        // This is expected as "has_feathers" was provided in cfg()
-fn do_features() {}         // and because names exhaustiveness was not disabled
+#[cfg(is_embedded)]         // This condition is expected, as 'is_embedded' was provided in --check-cfg
+fn do_embedded() {}         // and doesn't take any value
 
-#[cfg(has_feathers = "zapping")] // This is expected as "has_feathers" was provided in cfg()
-                                 // and because no value checking was enable for "has_feathers"
-                                 // no warning is emitted for the value "zapping"
-fn do_zapping() {}
+#[cfg(has_feathers)]        // This condition is expected, as 'has_feathers' was provided in --check-cfg
+fn do_features() {}         // and doesn't take any value
 
-#[cfg(has_mumble_frotz)]    // This is UNEXPECTED because names checking is enable and
-                            // "has_mumble_frotz" was not provided in cfg()
+#[cfg(has_mumble_frotz)]    // This condition is UNEXPECTED, as 'has_mumble_frotz' was NEVER provided
+                            // in any --check-cfg arguments
 fn do_mumble_frotz() {}
-```
-
-### Example: Checking feature values, but not condition names
 
-```bash
-# This turns on checking for feature values, but not for condition names.
-rustc --check-cfg 'cfg(feature, values("zapping", "lasers"))' \
-      --check-cfg 'cfg(any())' \
-      --cfg 'feature="zapping"' -Z unstable-options
-```
-
-```rust
-#[cfg(is_embedded)]         // This is doesn't raise a warning, because names checking was
-                            // disabled by 'cfg(any())'
-fn do_embedded() {}
-
-#[cfg(has_feathers)]        // Same as above, 'cfg(any())' was provided so no name
-                            // checking is performed
-fn do_features() {}
-
-#[cfg(feature = "lasers")]  // This is expected, "lasers" is in the cfg(feature) list
+#[cfg(feature = "lasers")]  // This condition is expected, as "lasers" is an expected value of `feature`
 fn shoot_lasers() {}
 
-#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in the
-                            // cfg(feature) list
+#[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT an expected value of
+                            // `feature`
 fn write_shakespeare() {}
 ```
 
-### Example: Checking both condition names and feature values
+### Example: Condition names without values
 
 ```bash
-# This turns on checking for feature values and for condition names.
-rustc --check-cfg 'cfg(is_embedded, has_feathers)' \
-      --check-cfg 'cfg(feature, values("zapping", "lasers"))' \
-      --cfg has_feathers --cfg 'feature="zapping"' -Z unstable-options
+rustc --check-cfg 'cfg(is_embedded, has_feathers, values(any()))' \
+      --cfg has_feathers -Z unstable-options
 ```
 
 ```rust
-#[cfg(is_embedded)]         // This is expected because "is_embedded" was provided in cfg()
-fn do_embedded() {}         // and doesn't take any value
-
-#[cfg(has_feathers)]        // This is expected because "has_feathers" was provided in cfg()
-fn do_features() {}         // and deosn't take any value
+#[cfg(is_embedded)]      // This condition is expected, as 'is_embedded' was provided in --check-cfg
+                         // as condition name
+fn do_embedded() {}
 
-#[cfg(has_mumble_frotz)]    // This is UNEXPECTED, because "has_mumble_frotz" was never provided
-fn do_mumble_frotz() {}
+#[cfg(has_feathers)]     // This condition is expected, as "has_feathers" was provided in --check-cfg
+                         // as condition name
+fn do_features() {}
 
-#[cfg(feature = "lasers")]  // This is expected, "lasers" is in the cfg(feature) list
-fn shoot_lasers() {}
+#[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers" was provided in
+                                 // and because *any* values is expected for 'has_feathers' no
+                                 // warning is emitted for the value "zapping"
+fn do_zapping() {}
 
-#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in
-                            // the cfg(feature) list
-fn write_shakespeare() {}
+#[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as 'has_mumble_frotz' was not provided
+                         // in any --check-cfg arguments
+fn do_mumble_frotz() {}
 ```