11# Checking conditional configurations
22
3- ` rustc ` accepts the ` --check-cfg ` option, which specifies whether to check conditions and how to
4- check them. The ` --check-cfg ` option takes a value, called the _ check cfg specification_ .
5- This specification has one form:
3+ ` rustc ` supports checking that every _ reachable_ [ ^ reachable ] ` #[cfg] ` matches a list of the
4+ expected config names and values.
65
7- 1 . ` --check-cfg cfg(...) ` mark a configuration and it's expected values as expected.
6+ This can help with verifying that the crate is correctly handling conditional compilation for
7+ different target platforms or features. It ensures that the cfg settings are consistent between
8+ what is intended and what is used, helping to catch potential bugs or errors early in the
9+ development process.
810
9- * No implicit expectation is added when using ` --cfg ` . Users are expected to
10- pass all expected names and values using the _ check cfg specification _ . *
11+ In order to accomplish that goal, ` rustc ` accepts the ` --check- cfg ` flag, which specifies
12+ whether to check conditions and how to check them.
1113
12- ## The ` cfg(...) ` form
14+ > ** Note:** No implicit expectation is added when using ` --cfg ` . Users are expected to
15+ pass all expected names and values using the _ check cfg specification_ .
1316
14- The ` cfg(...) ` form enables checking the values within list-valued conditions. It has this
15- basic form:
17+ [ ^ reachable ] : ` rustc ` promises to at least check reachable ` #[cfg] ` , and while non-reachable
18+ ` #[cfg] ` are not currently checked, they may well be checked in the future without it being a
19+ breaking change.
20+
21+ ## Specifying expected names and values
22+
23+ To specify expected names and values, the _ check cfg specification_ provides the ` cfg(...) `
24+ option which enables specifying for an expected config name and it's expected values.
25+
26+ It has this basic form:
1627
1728``` bash
1829rustc --check-cfg ' cfg(name, values("value1", "value2", ... "valueN"))'
1930```
2031
2132where ` name ` is a bare identifier (has no quotes) and each ` "value" ` term is a quoted literal
2233string. ` name ` specifies the name of the condition, such as ` feature ` or ` my_cfg ` .
34+ ` "value" ` specify one of the value of that condition name.
35+
36+ When the ` cfg(...) ` option is specified, ` rustc ` will check every[ ^ reachable ] :
37+ - ` #[cfg(name = "value")] ` attribute
38+ - ` #[cfg_attr(name = "value")] ` attribute
39+ - ` #[link(name = "a", cfg(name = "value"))] ` attribute
40+ - ` cfg!(name = "value") ` macro call
2341
24- When the ` cfg(...) ` option is specified, ` rustc ` will check every ` #[cfg(name = "value")] `
25- attribute, ` #[cfg_attr(name = "value")] ` attribute, ` #[link(name = "a", cfg(name = "value"))] `
26- attribute and ` cfg!(name = "value") ` macro call. It will check that the ` "value" ` specified is
27- present in the list of expected values. If ` "value" ` is not in it, then ` rustc ` will report an
28- ` unexpected_cfgs ` lint diagnostic. The default diagnostic level for this lint is ` Warn ` .
42+ > * The command line ` --cfg ` arguments are currently NOT checked but may very well be checked
43+ in the future.*
2944
30- * The command line ` --cfg ` arguments are currently * NOT* checked but may very well be checked in
31- the future.*
45+ ` rustc ` will check that the ` "value" ` specified is present in the list of expected values.
46+ If ` "value" ` is not in it, then ` rustc ` will report an ` unexpected_cfgs ` lint diagnostic.
47+ The default diagnostic level for this lint is ` Warn ` .
3248
3349To check for the _ none_ value (ie ` #[cfg(foo)] ` ) one can use the ` none() ` predicate inside
3450` values() ` : ` values(none()) ` . It can be followed or preceded by any number of ` "value" ` .
@@ -43,12 +59,12 @@ rustc --check-cfg 'cfg(name, values(none()))'
4359
4460To enable checking of name but not values, use one of these forms:
4561
46- - No expected values (_ will lint on every value _ ):
62+ - No expected values (_ will lint on every value of ` name ` _ ):
4763 ``` bash
4864 rustc --check-cfg ' cfg(name, values())'
4965 ```
5066
51- - Unknown expected values (_will never lint_ ):
67+ - Unknown expected values (_will never lint on value of ` name ` _ ):
5268 ` ` ` bash
5369 rustc --check-cfg ' cfg(name, values(any()))'
5470 ` ` `
@@ -59,17 +75,26 @@ To avoid repeating the same set of values, use this form:
5975rustc --check-cfg ' cfg(name1, ..., nameN, values("value1", "value2", ... "valueN"))'
6076` ` `
6177
78+ To enable checking without specifying any names or values, use this form:
79+
80+ ` ` ` bash
81+ rustc --check-cfg ' cfg()'
82+ ` ` `
83+
6284The ` --check-cfg cfg(...)` option can be repeated, both for the same condition name and for
6385different names. If it is repeated for the same condition name, then the sets of values for that
6486condition are merged together (precedence is given to `values(any ())` ).
6587
88+ > To help out an equivalence table between ` --cfg` arguments and ` --check-cfg` is available
89+ [down below](# equivalence-table-with---cfg).
90+
6691# # Well known names and values
6792
68- ` rustc` has a internal list of well known names and their corresponding values.
69- Those well known names and values follows the same stability as what they refer to .
93+ ` rustc` maintains a list of well- known names and their corresponding values in order to avoid
94+ the need to specify them manually .
7095
71- Well known names and values checking is always enabled as long as at least one
72- ` --check-cfg ` argument is present.
96+ Well known names and values are implicitly added as long as at least one ` --check-cfg ` argument
97+ is present.
7398
7499As of ` 2024-04-06T` , the list of known names is as follows:
75100
@@ -108,11 +133,9 @@ As of `2024-04-06T`, the list of known names is as follows:
108133Like with `values(any ())` , well known names checking can be disabled by passing ` cfg(any())`
109134as argument to ` --check-cfg` .
110135
111- # # Examples
112-
113- # ## Equivalence table
136+ # # Equivalence table with `--cfg`
114137
115- This table describe the equivalence of a ` --cfg` argument to a ` --check-cfg` argument.
138+ This table describe the equivalence between a ` --cfg` argument to a ` --check-cfg` argument.
116139
117140| ` --cfg` | ` --check-cfg` |
118141| -------------------------------| ------------------------------------------------------------|
@@ -124,40 +147,42 @@ This table describe the equivalence of a `--cfg` argument to a `--check-cfg` arg
124147| ` --cfg foo=" 1" --cfg bar=" 2" ` | ` --check-cfg=cfg(foo, values(" 1" )) --check-cfg=cfg(bar, values(" 2" ))` |
125148| ` --cfg foo --cfg foo=" bar" ` | ` --check-cfg=cfg(foo, values(none (), " bar" ))` |
126149
150+ # # Examples
151+
127152# ## Example: Cargo-like `feature` example
128153
129154Consider this command line:
130155
131156` ` ` bash
132157rustc --check-cfg ' cfg(feature, values("lion", "zebra"))' \
133- --cfg ' feature="lion"' -Z unstable-options example.rs
158+ --cfg ' feature="lion"' example.rs
134159` ` `
135160
136- This command line indicates that this crate has two features: ` lion` and ` zebra` . The ` lion`
161+ > This command line indicates that this crate has two features: ` lion` and ` zebra` . The ` lion`
137162feature is enabled, while the ` zebra` feature is disabled.
138- Given the ` --check-cfg` arguments, exhaustive checking of names and
139- values are enabled.
140163
141- ` example.rs` :
142164` ` ` rust
143- # [cfg(feature = "lion")] // This condition is expected, as "lion" is an expected value of `feature`
165+ # [cfg(feature = "lion")] // This condition is expected, as "lion" is an
166+ // expected value of ` feature`
144167fn tame_lion(lion: Lion) {}
145168
146- # [cfg(feature = "zebra")] // This condition is expected, as "zebra" is an expected value of `feature`
147- // but the condition will still evaluate to false
148- // since only --cfg feature=" lion" was passed
169+ # [cfg(feature = "zebra")] // This condition is expected, as "zebra" is an expected
170+ // value of ` feature ` but the condition will evaluate
171+ // to false since only --cfg feature=" lion" was passed
149172fn ride_zebra(z: Zebra) {}
150173
151- # [cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT an expected value of
152- // ` feature` and will cause a compiler warning (by default).
174+ # [cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT
175+ // an expected value of ` feature` and will cause a
176+ // the compiler to emit the ` unexpected_cfgs` lint
153177fn poke_platypus () {}
154178
155- # [cfg(feechure = "lion")] // This condition is UNEXPECTED, as 'feechure' is NOT a expected condition
156- // name, no ` cfg(feechure, ...)` was passed in ` --check-cfg`
179+ # [cfg(feechure = "lion")] // This condition is UNEXPECTED, as 'feechure' is NOT
180+ // a expected condition name, no ` cfg(feechure, ...)`
181+ // was passed in ` --check-cfg`
157182fn tame_lion () {}
158183
159- # [cfg(windows = "unix")] // This condition is UNEXPECTED, as while 'windows' is a well known
160- // condition name, it doesn' t expect any values
184+ # [cfg(windows = "unix")] // This condition is UNEXPECTED, as the well known
185+ // ' windows ' cfg doesn' t expect any values
161186fn tame_windows() {}
162187```
163188
@@ -166,50 +191,54 @@ fn tame_windows() {}
166191```bash
167192rustc --check-cfg ' cfg(is_embedded, has_feathers)' \
168193 --check-cfg ' cfg(feature, values(" zapping" , " lasers" ))' \
169- --cfg has_feathers --cfg ' feature=" zapping" ' -Z unstable-options
194+ --cfg has_feathers --cfg ' feature=" zapping" '
170195```
171196
172197```rust
173- #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was provided in --check-cfg
174- fn do_embedded() {} // and doesn' t take any value
198+ #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was
199+ // provided in --check-cfg and doesn' t take any value
200+ fn do_embedded () {}
175201
176- # [cfg(has_feathers)] // This condition is expected, as 'has_feathers' was provided in --check-cfg
177- fn do_features () {} // and doesn' t take any value
202+ # [cfg(has_feathers)] // This condition is expected, as 'has_feathers' was
203+ // provided in --check-cfg and doesn' t take any value
204+ fn do_features() {}
178205
179- #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz' was NEVER provided
180- // in any --check-cfg arguments
206+ #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz'
207+ // was NEVER provided in any --check-cfg arguments
181208fn do_mumble_frotz() {}
182209
183- #[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an expected value of `feature`
210+ #[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an
211+ // expected value of `feature`
184212fn shoot_lasers() {}
185213
186- #[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT an expected value of
187- // `feature`
214+ #[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT
215+ // an expected value of `feature`
188216fn write_shakespeare() {}
189217```
190218
191219### Example: Condition names without values
192220
193221```bash
194222rustc --check-cfg ' cfg(is_embedded, has_feathers, values(any ()))' \
195- --cfg has_feathers -Z unstable-options
223+ --cfg has_feathers
196224```
197225
198226```rust
199- #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was provided in --check-cfg
200- // as condition name
227+ #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was
228+ // provided in --check-cfg as condition name
201229fn do_embedded() {}
202230
203- #[cfg(has_feathers)] // This condition is expected, as "has_feathers" was provided in --check-cfg
204- // as condition name
231+ #[cfg(has_feathers)] // This condition is expected, as "has_feathers" was
232+ // provided in --check-cfg as condition name
205233fn do_features() {}
206234
207- #[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers" was provided in
208- // and because *any* values is expected for ' has_feathers' no
235+ #[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers"
236+ // was provided and because *any* values is
237+ // expected for ' has_feathers' no
209238 // warning is emitted for the value "zapping"
210239fn do_zapping() {}
211240
212- #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz' was not provided
213- // in any --check-cfg arguments
241+ #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz'
242+ // was not provided in any --check-cfg arguments
214243fn do_mumble_frotz() {}
215244```
0 commit comments