Skip to content

Commit a5b10fd

Browse files
authored
Merge pull request #2103 from folkertdev/cfg-select
`cfg_select!` macro
2 parents 442cbef + 5c1d0c5 commit a5b10fd

2 files changed

Lines changed: 94 additions & 35 deletions

File tree

src/conditional-compilation.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ r[cfg.intro]
3131
*Conditionally compiled source code* is source code that is compiled only under certain conditions.
3232

3333
r[cfg.attributes-macro]
34-
Source code can be made conditionally compiled using the [`cfg`] and [`cfg_attr`] [attributes] and the built-in [`cfg` macro].
34+
Source code can be made conditionally compiled using the [`cfg`] and [`cfg_attr`] [attributes] and the built-in [`cfg!`] and [`cfg_select!`] [macros].
3535

3636
r[cfg.conditional]
3737
Whether to compile can depend on the target architecture of the compiled crate, arbitrary values passed to the compiler, and other things further described below.
@@ -436,17 +436,76 @@ let machine_kind = if cfg!(unix) {
436436
println!("I'm running on a {} machine!", machine_kind);
437437
```
438438
439+
r[cfg.cfg_select]
440+
### The `cfg_select` macro
441+
442+
r[cfg.cfg_select.intro]
443+
The built-in [`cfg_select!`][std::cfg_select] macro can be used to select code at compile-time based on multiple configuration predicates.
444+
445+
> [!EXAMPLE]
446+
> ```rust
447+
> cfg_select! {
448+
> unix => {
449+
> fn foo() { /* unix specific functionality */ }
450+
> }
451+
> target_pointer_width = "32" => {
452+
> fn foo() { /* non-unix, 32-bit functionality */ }
453+
> }
454+
> _ => {
455+
> fn foo() { /* fallback implementation */ }
456+
> }
457+
> }
458+
>
459+
> let is_unix_str = cfg_select! {
460+
> unix => "unix",
461+
> _ => "not unix",
462+
> };
463+
> ```
464+
465+
r[cfg.cfg_select.syntax]
466+
```grammar,configuration
467+
@root CfgSelect -> CfgSelectArms?
468+
469+
CfgSelectArms ->
470+
CfgSelectConfigurationPredicate `=>`
471+
(
472+
`{` ^ TokenTree `}` `,`? CfgSelectArms?
473+
| ExpressionWithBlockNoAttrs `,`? CfgSelectArms?
474+
| ExpressionWithoutBlockNoAttrs ( `,` CfgSelectArms? )?
475+
)
476+
477+
CfgSelectConfigurationPredicate ->
478+
ConfigurationPredicate | `_`
479+
```
480+
481+
r[cfg.cfg_select.first-arm]
482+
`cfg_select` expands to the payload of the first arm whose configuration predicate evaluates to true.
483+
484+
r[cfg.cfg_select.braces]
485+
If the entire payload is wrapped in curly braces, the braces are removed during expansion.
486+
487+
r[cfg.cfg_select.wildcard]
488+
The configuration predicate `_` always evaluates to true.
489+
490+
r[cfg.cfg_select.fallthrough]
491+
It is a compile error if none of the predicates evaluate to true.
492+
493+
r[cfg.cfg_select.well-formed]
494+
Each right-hand side must be a syntactically valid expansion for the position in which the macro is invoked.
495+
439496
[Testing]: attributes/testing.md
440497
[`--cfg`]: ../rustc/command-line-arguments.html#--cfg-configure-the-compilation-environment
441498
[`--test`]: ../rustc/command-line-arguments.html#--test-build-a-test-harness
442499
[`cfg`]: #the-cfg-attribute
443-
[`cfg` macro]: #the-cfg-macro
500+
[`cfg!`]: #the-cfg-macro
444501
[`cfg_attr`]: #the-cfg_attr-attribute
502+
[`cfg_select!`]: #the-cfg_select-macro
445503
[`crate_name`]: crates-and-source-files.md#the-crate_name-attribute
446504
[`crate_type`]: linkage.md
447505
[`target_feature` attribute]: attributes/codegen.md#the-target_feature-attribute
448506
[attribute]: attributes.md
449507
[attributes]: attributes.md
450508
[cargo-feature]: ../cargo/reference/features.html
451509
[crate type]: linkage.md
510+
[macros]: macros.md
452511
[static C runtime]: linkage.md#static-and-dynamic-c-runtimes

src/expressions.md

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,41 @@ Expression ->
88
| ExpressionWithBlock
99
1010
ExpressionWithoutBlock ->
11-
OuterAttribute*
12-
(
13-
LiteralExpression
14-
| PathExpression
15-
| OperatorExpression
16-
| GroupedExpression
17-
| ArrayExpression
18-
| AwaitExpression
19-
| IndexExpression
20-
| TupleExpression
21-
| TupleIndexingExpression
22-
| StructExpression
23-
| CallExpression
24-
| MethodCallExpression
25-
| FieldExpression
26-
| ClosureExpression
27-
| AsyncBlockExpression
28-
| ContinueExpression
29-
| BreakExpression
30-
| RangeExpression
31-
| ReturnExpression
32-
| UnderscoreExpression
33-
| MacroInvocation
34-
)
11+
OuterAttribute* ExpressionWithoutBlockNoAttrs
12+
13+
ExpressionWithoutBlockNoAttrs ->
14+
LiteralExpression
15+
| PathExpression
16+
| OperatorExpression
17+
| GroupedExpression
18+
| ArrayExpression
19+
| AwaitExpression
20+
| IndexExpression
21+
| TupleExpression
22+
| TupleIndexingExpression
23+
| StructExpression
24+
| CallExpression
25+
| MethodCallExpression
26+
| FieldExpression
27+
| ClosureExpression
28+
| AsyncBlockExpression
29+
| ContinueExpression
30+
| BreakExpression
31+
| RangeExpression
32+
| ReturnExpression
33+
| UnderscoreExpression
34+
| MacroInvocation
3535
3636
ExpressionWithBlock ->
37-
OuterAttribute*
38-
(
39-
BlockExpression
40-
| ConstBlockExpression
41-
| UnsafeBlockExpression
42-
| LoopExpression
43-
| IfExpression
44-
| MatchExpression
45-
)
37+
OuterAttribute* ExpressionWithBlockNoAttrs
38+
39+
ExpressionWithBlockNoAttrs ->
40+
BlockExpression
41+
| ConstBlockExpression
42+
| UnsafeBlockExpression
43+
| LoopExpression
44+
| IfExpression
45+
| MatchExpression
4646
```
4747

4848
r[expr.intro]

0 commit comments

Comments
 (0)