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 and configuring expected names and values
22
+
23
+ To specifying and configuring expected names and values, the _ check cfg specification_ provides
24
+ the ` cfg(...) ` form 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 values 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 values of ` name ` _ ):
52
68
` ` ` bash
53
69
rustc --check-cfg ' cfg(name, values(any()))'
54
70
` ` `
@@ -59,16 +75,27 @@ 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
+ In order to avoid the need for users have to specify configs set by Rust Toolchain, ` rustc`
94
+ maintains a list of well known names and their corresponding values.
95
+
96
+ > Those well known names and values follows the same stability as what they refer to.
70
97
71
- Well known names and values checking is always enabled as long as at least one
98
+ Well known names and values are implicitly added as long as at least one
72
99
` --check-cfg` argument is present.
73
100
74
101
As of ` 2024-04-06T` , the list of known names is as follows:
@@ -108,11 +135,9 @@ As of `2024-04-06T`, the list of known names is as follows:
108
135
Like with `values(any ())` , well known names checking can be disabled by passing ` cfg(any())`
109
136
as argument to ` --check-cfg` .
110
137
111
- # # Examples
112
-
113
- # ## Equivalence table
138
+ # # Equivalence table with `--cfg`
114
139
115
- This table describe the equivalence of a ` --cfg` argument to a ` --check-cfg` argument.
140
+ This table describe the equivalence between a ` --cfg` argument to a ` --check-cfg` argument.
116
141
117
142
| ` --cfg` | ` --check-cfg` |
118
143
| -------------------------------| ------------------------------------------------------------|
@@ -124,40 +149,42 @@ This table describe the equivalence of a `--cfg` argument to a `--check-cfg` arg
124
149
| ` --cfg foo=" 1" --cfg bar=" 2" ` | ` --check-cfg=cfg(foo, values(" 1" )) --check-cfg=cfg(bar, values(" 2" ))` |
125
150
| ` --cfg foo --cfg foo=" bar" ` | ` --check-cfg=cfg(foo, values(none (), " bar" ))` |
126
151
152
+ # # Examples
153
+
127
154
# ## Example: Cargo-like `feature` example
128
155
129
156
Consider this command line:
130
157
131
158
` ` ` bash
132
159
rustc --check-cfg ' cfg(feature, values("lion", "zebra"))' \
133
- --cfg ' feature="lion"' -Z unstable-options example.rs
160
+ --cfg ' feature="lion"' example.rs
134
161
` ` `
135
162
136
- This command line indicates that this crate has two features: ` lion` and ` zebra` . The ` lion`
163
+ > This command line indicates that this crate has two features: ` lion` and ` zebra` . The ` lion`
137
164
feature is enabled, while the ` zebra` feature is disabled.
138
- Given the ` --check-cfg` arguments, exhaustive checking of names and
139
- values are enabled.
140
165
141
- ` example.rs` :
142
166
` ` ` rust
143
- # [cfg(feature = "lion")] // This condition is expected, as "lion" is an expected value of `feature`
167
+ # [cfg(feature = "lion")] // This condition is expected, as "lion" is an
168
+ // expected value of ` feature`
144
169
fn tame_lion(lion: Lion) {}
145
170
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
171
+ # [cfg(feature = "zebra")] // This condition is expected, as "zebra" is an expected
172
+ // value of ` feature ` but the condition will evaluate
173
+ // to false since only --cfg feature=" lion" was passed
149
174
fn ride_zebra(z: Zebra) {}
150
175
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).
176
+ # [cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT
177
+ // an expected value of ` feature` and will cause a
178
+ // the compiler to emit the ` unexpected_cfgs` lint
153
179
fn poke_platypus () {}
154
180
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`
181
+ # [cfg(feechure = "lion")] // This condition is UNEXPECTED, as 'feechure' is NOT
182
+ // a expected condition name, no ` cfg(feechure, ...)`
183
+ // was passed in ` --check-cfg`
157
184
fn tame_lion () {}
158
185
159
- # [cfg(windows = "unix")] // This condition is UNEXPECTED, as while 'windows' is a well known
160
- // condition name, it doesn' t expect any values
186
+ # [cfg(windows = "unix")] // This condition is UNEXPECTED, as the well known
187
+ // ' windows ' cfg doesn' t expect any values
161
188
fn tame_windows() {}
162
189
```
163
190
@@ -166,50 +193,54 @@ fn tame_windows() {}
166
193
```bash
167
194
rustc --check-cfg ' cfg(is_embedded, has_feathers)' \
168
195
--check-cfg ' cfg(feature, values(" zapping" , " lasers" ))' \
169
- --cfg has_feathers --cfg ' feature=" zapping" ' -Z unstable-options
196
+ --cfg has_feathers --cfg ' feature=" zapping" '
170
197
```
171
198
172
199
```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
200
+ #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was
201
+ // provided in --check-cfg and doesn' t take any value
202
+ fn do_embedded () {}
175
203
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
204
+ # [cfg(has_feathers)] // This condition is expected, as 'has_feathers' was
205
+ // provided in --check-cfg and doesn' t take any value
206
+ fn do_features() {}
178
207
179
- #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz' was NEVER provided
180
- // in any --check-cfg arguments
208
+ #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz'
209
+ // was NEVER provided in any --check-cfg arguments
181
210
fn do_mumble_frotz() {}
182
211
183
- #[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an expected value of `feature`
212
+ #[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an
213
+ // expected value of `feature`
184
214
fn shoot_lasers() {}
185
215
186
- #[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT an expected value of
187
- // `feature`
216
+ #[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT
217
+ // an expected value of `feature`
188
218
fn write_shakespeare() {}
189
219
```
190
220
191
221
### Example: Condition names without values
192
222
193
223
```bash
194
224
rustc --check-cfg ' cfg(is_embedded, has_feathers, values(any ()))' \
195
- --cfg has_feathers -Z unstable-options
225
+ --cfg has_feathers
196
226
```
197
227
198
228
```rust
199
- #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was provided in --check-cfg
200
- // as condition name
229
+ #[cfg(is_embedded)] // This condition is expected, as ' is_embedded' was
230
+ // provided in --check-cfg as condition name
201
231
fn do_embedded() {}
202
232
203
- #[cfg(has_feathers)] // This condition is expected, as "has_feathers" was provided in --check-cfg
204
- // as condition name
233
+ #[cfg(has_feathers)] // This condition is expected, as "has_feathers" was
234
+ // provided in --check-cfg as condition name
205
235
fn do_features() {}
206
236
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
237
+ #[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers"
238
+ // was provided and because *any* values is
239
+ // expected for ' has_feathers' no
209
240
// warning is emitted for the value "zapping"
210
241
fn do_zapping() {}
211
242
212
- #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz' was not provided
213
- // in any --check-cfg arguments
243
+ #[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as ' has_mumble_frotz'
244
+ // was not provided in any --check-cfg arguments
214
245
fn do_mumble_frotz() {}
215
246
```
0 commit comments