about summary refs log tree commit diff
path: root/src/doc/rustc
diff options
context:
space:
mode:
authorUrgau <urgau@numericable.fr>2024-02-25 15:45:43 +0100
committerUrgau <urgau@numericable.fr>2024-04-15 21:49:56 +0200
commita20de73ccfdf24a59f43da9cf9e0d95ca40d6aab (patch)
treeea3440fac2778442bd857f45feb506ee4090b51a /src/doc/rustc
parent909fcfcb6a01b9a811835ba001954e6c62b2a2bc (diff)
downloadrust-a20de73ccfdf24a59f43da9cf9e0d95ca40d6aab.tar.gz
rust-a20de73ccfdf24a59f43da9cf9e0d95ca40d6aab.zip
Move --check-cfg documentation to stable books
Diffstat (limited to 'src/doc/rustc')
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/check-cfg.md215
-rw-r--r--src/doc/rustc/src/command-line-arguments.md10
3 files changed, 226 insertions, 0 deletions
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index db85753145d..31096b6df92 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -77,6 +77,7 @@
 - [Profile-guided Optimization](profile-guided-optimization.md)
 - [Instrumentation-based Code Coverage](instrument-coverage.md)
 - [Linker-plugin-based LTO](linker-plugin-lto.md)
+- [Checking conditional configurations](check-cfg.md)
 - [Exploit Mitigations](exploit-mitigations.md)
 - [Symbol Mangling](symbol-mangling/index.md)
     - [v0 Symbol Format](symbol-mangling/v0.md)
diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md
new file mode 100644
index 00000000000..37708bda1f3
--- /dev/null
+++ b/src/doc/rustc/src/check-cfg.md
@@ -0,0 +1,215 @@
+# Checking conditional configurations
+
+`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_.
+This specification has one form:
+
+1. `--check-cfg cfg(...)` mark a configuration and it's expected values as expected.
+
+*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
+
+The `cfg(...)` form enables checking the values within list-valued conditions. It has this
+basic form:
+
+```bash
+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
+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"))]`
+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.*
+
+To check for the _none_ value (ie `#[cfg(foo)]`) one can use the `none()` predicate inside
+`values()`: `values(none())`. It can be followed or preceded 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(none()))'
+```
+
+To enable checking of name but not values, use one of these forms:
+
+  - 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:
+
+```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 (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 names and values checking is always enabled as long as at least one
+`--check-cfg` argument is present.
+
+As of `2024-04-06T`, the list of known names is as follows:
+
+<!--- See CheckCfg::fill_well_known in compiler/rustc_session/src/config.rs -->
+
+ - `clippy`
+ - `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`
+ - `ub_checks`
+ - `unix`
+ - `windows`
+
+Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())`
+as argument to `--check-cfg`.
+
+## Examples
+
+### Equivalence table
+
+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)` 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, values(none(), "bar"))`              |
+
+### 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
+```
+
+This command line indicates that this crate has two features: `lion` and `zebra`. The `lion`
+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
+#[cfg(feature = "lion")]     // This condition is expected, as "lion" is an expected value of `feature`
+fn tame_lion(lion: Lion) {}
+
+#[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) {}
+
+#[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() {}
+
+#[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() {}
+
+#[cfg(windows = "unix")]     // This condition is UNEXPECTED, as while 'windows' is a well known
+                             // condition name, it doesn't expect any values
+fn tame_windows() {}
+```
+
+### Example: Multiple names and values
+
+```bash
+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 condition is expected, as 'is_embedded' was provided in --check-cfg
+fn do_embedded() {}         // and doesn't take any value
+
+#[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 condition is UNEXPECTED, as 'has_mumble_frotz' was NEVER provided
+                            // in any --check-cfg arguments
+fn do_mumble_frotz() {}
+
+#[cfg(feature = "lasers")]  // This condition is expected, as "lasers" is an expected value of `feature`
+fn shoot_lasers() {}
+
+#[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT an expected value of
+                            // `feature`
+fn write_shakespeare() {}
+```
+
+### Example: Condition names without values
+
+```bash
+rustc --check-cfg 'cfg(is_embedded, has_feathers, values(any()))' \
+      --cfg has_feathers -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]      // This condition is expected, as 'is_embedded' was provided in --check-cfg
+                         // as condition name
+fn do_embedded() {}
+
+#[cfg(has_feathers)]     // This condition is expected, as "has_feathers" was provided in --check-cfg
+                         // as condition name
+fn do_features() {}
+
+#[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(has_mumble_frotz)] // This condition is UNEXPECTED, as 'has_mumble_frotz' was not provided
+                         // in any --check-cfg arguments
+fn do_mumble_frotz() {}
+```
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 5e02453e236..7c605333c25 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -18,6 +18,16 @@ The value can either be a single identifier or two identifiers separated by `=`.
 For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond
 to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.
 
+<a id="option-check-cfg"></a>
+## `--check-cfg`: enables checking conditional configurations
+
+This flag will enable checking conditional configurations.
+Refer to the [Checking conditional configurations](check-cfg.md) of this book
+for further details and explanation.
+
+For examples, `--check-cfg 'cfg(verbose)'` or `--check-cfg 'cfg(feature, values("serde"))'`.
+These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.
+
 <a id="option-l-search-path"></a>
 ## `-L`: add a directory to the library search path