1
1
# Checking conditional configurations
2
2
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.
6
5
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.
8
10
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.
11
13
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_ .
13
16
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:
16
27
17
28
``` bash
18
29
rustc --check-cfg ' cfg(name, values("value1", "value2", ... "valueN"))'
19
30
```
20
31
21
32
where ` name ` is a bare identifier (has no quotes) and each ` "value" ` term is a quoted literal
22
33
string. ` 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
23
41
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.*
29
44
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 ` .
32
48
33
49
To check for the _ none_ value (ie ` #[cfg(foo)] ` ) one can use the ` none() ` predicate inside
34
50
` 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()))'
43
59
44
60
To enable checking of name but not values, use one of these forms:
45
61
46
- - No expected values (_ will lint on every value _ ):
62
+ - No expected values (_ will lint on every value of ` name ` _ ):
47
63
``` bash
48
64
rustc --check-cfg ' cfg(name, values())'
49
65
```
50
66
51
- - Unknown expected values (_will never lint_ ):
67
+ - Unknown expected values (_will never lint on value of ` name ` _ ):
52
68
` ` ` bash
53
69
rustc --check-cfg ' cfg(name, values(any()))'
54
70
` ` `
@@ -59,17 +75,26 @@ To avoid repeating the same set of values, use this form:
59
75
rustc --check-cfg ' cfg(name1, ..., nameN, values("value1", "value2", ... "valueN"))'
60
76
` ` `
61
77
78
+ To enable checking without specifying any names or values, use this form:
79
+
80
+ ` ` ` bash
81
+ rustc --check-cfg ' cfg()'
82
+ ` ` `
83
+
62
84
The ` --check-cfg cfg(...)` option can be repeated, both for the same condition name and for
63
85
different names. If it is repeated for the same condition name, then the sets of values for that
64
86
condition are merged together (precedence is given to `values(any ())` ).
65
87
88
+ > To help out an equivalence table between ` --cfg` arguments and ` --check-cfg` is available
89
+ [down below](# equivalence-table-with---cfg).
90
+
66
91
# # Well known names and values
67
92
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 .
70
95
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.
73
98
74
99
As of ` 2024-05-06T` , the list of known names is as follows:
75
100
@@ -109,11 +134,9 @@ As of `2024-05-06T`, the list of known names is as follows:
109
134
Like with `values(any ())` , well known names checking can be disabled by passing ` cfg(any())`
110
135
as argument to ` --check-cfg` .
111
136
112
- # # Examples
113
-
114
- # ## Equivalence table
137
+ # # Equivalence table with `--cfg`
115
138
116
- This table describe the equivalence of a ` --cfg` argument to a ` --check-cfg` argument.
139
+ This table describe the equivalence between a ` --cfg` argument to a ` --check-cfg` argument.
117
140
118
141
| ` --cfg` | ` --check-cfg` |
119
142
| -------------------------------| ------------------------------------------------------------|
@@ -125,40 +148,42 @@ This table describe the equivalence of a `--cfg` argument to a `--check-cfg` arg
125
148
| ` --cfg foo=" 1" --cfg bar=" 2" ` | ` --check-cfg=cfg(foo, values(" 1" )) --check-cfg=cfg(bar, values(" 2" ))` |
126
149
| ` --cfg foo --cfg foo=" bar" ` | ` --check-cfg=cfg(foo, values(none (), " bar" ))` |
127
150
151
+ # # Examples
152
+
128
153
# ## Example: Cargo-like `feature` example
129
154
130
155
Consider this command line:
131
156
132
157
` ` ` bash
133
158
rustc --check-cfg ' cfg(feature, values("lion", "zebra"))' \
134
- --cfg ' feature="lion"' -Z unstable-options example.rs
159
+ --cfg ' feature="lion"' example.rs
135
160
` ` `
136
161
137
- This command line indicates that this crate has two features: ` lion` and ` zebra` . The ` lion`
162
+ > This command line indicates that this crate has two features: ` lion` and ` zebra` . The ` lion`
138
163
feature is enabled, while the ` zebra` feature is disabled.
139
- Given the ` --check-cfg` arguments, exhaustive checking of names and
140
- values are enabled.
141
164
142
- ` example.rs` :
143
165
` ` ` rust
144
- # [cfg(feature = "lion")] // This condition is expected, as "lion" is an expected value of `feature`
166
+ # [cfg(feature = "lion")] // This condition is expected, as "lion" is an
167
+ // expected value of ` feature`
145
168
fn tame_lion(lion: Lion) {}
146
169
147
- # [cfg(feature = "zebra")] // This condition is expected, as "zebra" is an expected value of `feature`
148
- // but the condition will still evaluate to false
149
- // since only --cfg feature=" lion" was passed
170
+ # [cfg(feature = "zebra")] // This condition is expected, as "zebra" is an expected
171
+ // value of ` feature ` but the condition will evaluate
172
+ // to false since only --cfg feature=" lion" was passed
150
173
fn ride_zebra(z: Zebra) {}
151
174
152
- # [cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT an expected value of
153
- // ` feature` and will cause a compiler warning (by default).
175
+ # [cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT
176
+ // an expected value of ` feature` and will cause a
177
+ // the compiler to emit the ` unexpected_cfgs` lint
154
178
fn poke_platypus () {}
155
179
156
- # [cfg(feechure = "lion")] // This condition is UNEXPECTED, as 'feechure' is NOT a expected condition
157
- // name, no ` cfg(feechure, ...)` was passed in ` --check-cfg`
180
+ # [cfg(feechure = "lion")] // This condition is UNEXPECTED, as 'feechure' is NOT
181
+ // a expected condition name, no ` cfg(feechure, ...)`
182
+ // was passed in ` --check-cfg`
158
183
fn tame_lion () {}
159
184
160
- # [cfg(windows = "unix")] // This condition is UNEXPECTED, as while 'windows' is a well known
161
- // condition name, it doesn' t expect any values
185
+ # [cfg(windows = "unix")] // This condition is UNEXPECTED, as the well known
186
+ // ' windows ' cfg doesn' t expect any values
162
187
fn tame_windows() {}
163
188
```
164
189
@@ -167,50 +192,54 @@ fn tame_windows() {}
167
192
```bash
168
193
rustc --check-cfg ' cfg(is_embedded, has_feathers)' \
169
194
--check-cfg ' cfg(feature, values(" zapping" , " lasers" ))' \
170
- --cfg has_feathers --cfg ' feature=" zapping" ' -Z unstable-options
195
+ --cfg has_feathers --cfg ' feature=" zapping" '
171
196
```
172
197
173
198
```rust
174
- #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was provided in --check-cfg
175
- fn do_embedded() {} // and doesn' t take any value
199
+ #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was
200
+ // provided in --check-cfg and doesn' t take any value
201
+ fn do_embedded () {}
176
202
177
- # [cfg(has_feathers)] // This condition is expected, as 'has_feathers' was provided in --check-cfg
178
- fn do_features () {} // and doesn' t take any value
203
+ # [cfg(has_feathers)] // This condition is expected, as 'has_feathers' was
204
+ // provided in --check-cfg and doesn' t take any value
205
+ fn do_features() {}
179
206
180
- #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz' was NEVER provided
181
- // in any --check-cfg arguments
207
+ #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz'
208
+ // was NEVER provided in any --check-cfg arguments
182
209
fn do_mumble_frotz() {}
183
210
184
- #[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an expected value of `feature`
211
+ #[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an
212
+ // expected value of `feature`
185
213
fn shoot_lasers() {}
186
214
187
- #[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT an expected value of
188
- // `feature`
215
+ #[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT
216
+ // an expected value of `feature`
189
217
fn write_shakespeare() {}
190
218
```
191
219
192
220
### Example: Condition names without values
193
221
194
222
```bash
195
223
rustc --check-cfg ' cfg(is_embedded, has_feathers, values(any ()))' \
196
- --cfg has_feathers -Z unstable-options
224
+ --cfg has_feathers
197
225
```
198
226
199
227
```rust
200
- #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was provided in --check-cfg
201
- // as condition name
228
+ #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was
229
+ // provided in --check-cfg as condition name
202
230
fn do_embedded() {}
203
231
204
- #[cfg(has_feathers)] // This condition is expected, as "has_feathers" was provided in --check-cfg
205
- // as condition name
232
+ #[cfg(has_feathers)] // This condition is expected, as "has_feathers" was
233
+ // provided in --check-cfg as condition name
206
234
fn do_features() {}
207
235
208
- #[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers" was provided in
209
- // and because *any* values is expected for ' has_feathers' no
236
+ #[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers"
237
+ // was provided and because *any* values is
238
+ // expected for ' has_feathers' no
210
239
// warning is emitted for the value "zapping"
211
240
fn do_zapping() {}
212
241
213
- #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz' was not provided
214
- // in any --check-cfg arguments
242
+ #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz'
243
+ // was not provided in any --check-cfg arguments
215
244
fn do_mumble_frotz() {}
216
245
```
0 commit comments