about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLoïc BRANSTETT <lolo.branstett@numericable.fr>2022-02-21 15:29:04 +0100
committerLoïc BRANSTETT <lolo.branstett@numericable.fr>2022-02-23 13:22:23 +0100
commita556a2a8e60501203f310407b27cf739618c0000 (patch)
tree30479f66d2e2b9abba64a2af1f84a79999f9cf96
parent8d3de56da1eba68d012977d4c743d5eaaa1baee8 (diff)
downloadrust-a556a2a8e60501203f310407b27cf739618c0000.tar.gz
rust-a556a2a8e60501203f310407b27cf739618c0000.zip
Add compiler flag `--check-cfg` to the unstable book
-rw-r--r--src/doc/unstable-book/src/compiler-flags/check-cfg.md221
1 files changed, 221 insertions, 0 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
new file mode 100644
index 00000000000..d7345ad0c33
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
@@ -0,0 +1,221 @@
+# `check-cfg`
+
+The tracking issue for this feature is: [#82450](https://github.com/rust-lang/rust/issues/82450).
+
+------------------------
+
+This feature allows you to enable complete or partial checking of 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-cfg` option can take one of two forms:
+
+1. `--check-cfg names(...)` enables checking condition names.
+2. `--check-cfg values(...)` enables checking the values within list-valued conditions.
+
+These two options are independent. `names` checks only the namespace of condition names
+while `values` checks only the namespace of the values of list-valued conditions.
+
+## The `names(...)` form
+
+The `names(...)` form enables checking the names. This form uses a named list:
+
+```bash
+rustc --check-cfg 'names(name1, name2, ... nameN)'
+```
+
+where each `name` is a bare identifier (has no quotes). The order of the names is not significant.
+
+If `--check-cfg names(...)` is specified at least once, then `rustc` will check all references to
+condition names. `rustc` will check every `#[cfg]` attribute, `#[cfg_attr]` attribute, `cfg` clause
+inside `#[link]` attribute and `cfg!(...)` call against the provided list of expected condition
+names. If a name is not present in this list, then `rustc` will report an `unexpected_cfgs` lint
+diagnostic. The default diagnostic level for this lint is `Warn`.
+
+If `--check-cfg names(...)` is not specified, then `rustc` will not check references to condition
+names.
+
+`--check-cfg names(...)` may be specified more than once. The result is that the list of valid
+condition names is merged across all options. It is legal for a condition name to be specified
+more than once; redundantly specifying a condition name has no effect.
+
+To enable checking condition names with an empty set of valid condition names, use the following
+form. The parentheses are required.
+
+```bash
+rustc --check-cfg 'names()'
+```
+
+Note that `--check-cfg 'names()'` is _not_ equivalent to omitting the option entirely.
+The first form enables checking condition names, while specifying that there are no valid
+condition names (outside of the set of well-known names defined by `rustc`). Omitting the
+`--check-cfg 'names(...)'` option does not enable checking condition names.
+
+Conditions that are enabled are implicitly valid; it is unnecessary (but legal) to specify a
+condition name as both enabled and valid. For example, the following invocations are equivalent:
+
+```bash
+# condition names will be checked, and 'has_time_travel' is valid
+rustc --cfg 'has_time_travel' --check-cfg 'names()'
+
+# condition names will be checked, and 'has_time_travel' is valid
+rustc --cfg 'has_time_travel' --check-cfg 'names(has_time_travel)'
+```
+
+In contrast, the following two invocations are _not_ equivalent:
+
+```bash
+# condition names will not be checked (because there is no --check-cfg names(...))
+rustc --cfg 'has_time_travel'
+
+# condition names will be checked, and 'has_time_travel' is both valid and enabled.
+rustc --cfg 'has_time_travel' --check-cfg 'names(has_time_travel)'
+```
+
+## The `values(...)` form
+
+The `values(...)` form enables checking the values within list-valued conditions. It has this
+form:
+
+```bash
+rustc --check-cfg `values(name, "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 `target_os`.
+
+When the `values(...)` 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`.
+
+The form `values()` is an error, because it does not specify a condition name.
+
+To enable checking of values, but to provide an empty set of valid values, use this form:
+
+```bash
+rustc --check-cfg `values(name)`
+```
+
+The `--check-cfg values(...)` 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.
+
+## Examples
+
+Consider this command line:
+
+```bash
+rustc --check-cfg 'names(feature)' \
+      --check-cfg 'values(feature,"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. Consider compiling this code:
+
+```rust
+// This is expected, and tame_lion() will be compiled
+#[cfg(feature = "lion")]
+fn tame_lion(lion: Lion) {}
+
+// This is expected, and ride_zebra() will NOT be compiled.
+#[cfg(feature = "zebra")]
+fn ride_zebra(zebra: Zebra) {}
+
+// This is UNEXPECTED, and will cause a compiler warning (by default).
+#[cfg(feature = "platypus")]
+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")]
+fn tame_lion() {}
+```
+
+> Note: The `--check-cfg names(feature)` option is necessary only to enable checking the condition
+> name, as in the last example. `feature` is a well-known (always-expected) condition name, and so
+> it is not necessary to specify it in a `--check-cfg 'names(...)'` option. That option can be
+> shortened to > `--check-cfg names()` in order to enable checking well-known condition names.
+
+### Example: Checking condition names, but not values
+
+```bash
+# This turns on checking for condition names, but not values, such as 'feature' values.
+rustc --check-cfg 'names(is_embedded, has_feathers)' \
+      --cfg has_feathers --cfg 'feature = "zapping"' -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]         // This is expected as "is_embedded" was provided in names()
+fn do_embedded() {}
+
+#[cfg(has_feathers)]        // This is expected as "has_feathers" was provided in names()
+fn do_features() {}
+
+#[cfg(has_mumble_frotz)]    // This is UNEXPECTED because names checking is enable and
+                            // "has_mumble_frotz" was not provided in names()
+fn do_mumble_frotz() {}
+
+#[cfg(feature = "lasers")]  // This doesn't raise a warning, because values checking for "feature"
+                            // was never used
+fn shoot_lasers() {}
+```
+
+### Example: Checking feature values, but not condition names
+
+```bash
+# This turns on checking for feature values, but not for condition names.
+rustc --check-cfg 'values(feature, "zapping", "lasers")' \
+      --cfg 'feature="zapping"' -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]         // This is doesn't raise a warning, because names checking was not
+                            // enable (ie not names())
+fn do_embedded() {}
+
+#[cfg(has_feathers)]        // Same as above, --check-cfg names(...) was never used so no name
+                            // checking is performed
+fn do_features() {}
+
+
+#[cfg(feature = "lasers")]  // This is expected, "lasers" is in the values(feature) list
+fn shoot_lasers() {}
+
+#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in the
+                            // --check-cfg values(feature) list
+fn write_shakespeare() {}
+```
+
+### Example: Checking both condition names and feature values
+
+```bash
+# This turns on checking for feature values and for condition names.
+rustc --check-cfg 'names(is_embedded, has_feathers)' \
+      --check-cfg 'values(feature, "zapping", "lasers")' \
+      --cfg has_feathers --cfg 'feature="zapping"' -Z unstable-options
+```
+
+```rust
+#[cfg(is_embedded)]         // This is expected because "is_embedded" was provided in names()
+fn do_embedded() {}
+
+#[cfg(has_feathers)]        // This is expected because "has_feathers" was provided in names()
+fn do_features() {}
+
+#[cfg(has_mumble_frotz)]    // This is UNEXPECTED, because has_mumble_frotz is not in the
+                            // --check-cfg names(...) list
+fn do_mumble_frotz() {}
+
+#[cfg(feature = "lasers")]  // This is expected, "lasers" is in the values(feature) list
+fn shoot_lasers() {}
+
+#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in
+                            // the values(feature) list
+fn write_shakespear() {}
+```