cfg_select: Support unbraced expressions by joshtriplett · Pull Request #145233 · rust-lang/rust

@joshtriplett

When operating on expressions, `cfg_select!` can now handle expressions
without braces. (It still requires braces for other things, such as
items.)

Expand the test coverage and documentation accordingly.

@joshtriplett added T-lang

Relevant to the language team

T-libs-api

Relevant to the library API team, which will review and decide on the PR/issue.

I-lang-nominated

Nominated for discussion during a lang team meeting.

I-libs-api-nominated

Nominated for discussion during a libs-api team meeting.

labels

Aug 10, 2025

jieyouxu

@traviscross traviscross added the P-lang-drag-1

Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang

label

Aug 12, 2025

This was referenced

Aug 13, 2025

@traviscross traviscross added I-lang-radar

Items that are on lang's radar and will need eventual work or consideration.

and removed I-lang-nominated

Nominated for discussion during a lang team meeting.

P-lang-drag-1

Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang

labels

Aug 14, 2025

jieyouxu

@bors bors added S-waiting-on-bors

Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

and removed S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

labels

Aug 14, 2025

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request

Aug 14, 2025
…eyouxu

cfg_select: Support unbraced expressions

Tracking issue for `cfg_select`: rust-lang#115585

When operating on expressions, `cfg_select!` can now handle expressions
without braces. (It still requires braces for other things, such as
items.)

Expand the test coverage and documentation accordingly.

---

I'm not sure whether deciding to extend `cfg_select!` in this way is T-lang or T-libs-api. I've labeled for both, with the request that both teams don't block on each other. :)

bors added a commit that referenced this pull request

Aug 14, 2025
Rollup of 9 pull requests

Successful merges:

 - #118087 (Add Ref/RefMut try_map method)
 - #140794 (Add information about group a lint belongs to)
 - #144947 (Fix description of unsigned `checked_exact_div`)
 - #145005 (strip prefix of temporary file names when it exceeds filesystem name length limit)
 - #145233 (cfg_select: Support unbraced expressions)
 - #145243 (take attr style into account in diagnostics)
 - #145353 (bootstrap: Fix jemalloc 64K page support for aarch64 tools)
 - #145379 (bootstrap: Support passing `--timings` to cargo)
 - #145389 ([rustdoc] Revert "rustdoc search: prefer stable items in search results")

Failed merges:

 - #144983 (Rehome 37 `tests/ui/issues/` tests to other subdirectories under `tests/ui/`)
 - #145065 (resolve: Introduce `RibKind::Block`)

r? `@ghost`
`@rustbot` modify labels: rollup

Kobzol added a commit to Kobzol/rust that referenced this pull request

Aug 14, 2025
…eyouxu

cfg_select: Support unbraced expressions

Tracking issue for `cfg_select`: rust-lang#115585

When operating on expressions, `cfg_select!` can now handle expressions
without braces. (It still requires braces for other things, such as
items.)

Expand the test coverage and documentation accordingly.

---

I'm not sure whether deciding to extend `cfg_select!` in this way is T-lang or T-libs-api. I've labeled for both, with the request that both teams don't block on each other. :)

This was referenced

Aug 14, 2025

bors added a commit that referenced this pull request

Aug 14, 2025
Rollup of 11 pull requests

Successful merges:

 - #137872 (Include whitespace in "remove |" suggestion and make it hidden)
 - #144631 (Fix test intrinsic-raw_eq-const-bad for big-endian)
 - #145233 (cfg_select: Support unbraced expressions)
 - #145261 (Improve tracing in bootstrap)
 - #145324 (Rename and document `ONLY_HOSTS` in bootstrap)
 - #145353 (bootstrap: Fix jemalloc 64K page support for aarch64 tools)
 - #145379 (bootstrap: Support passing `--timings` to cargo)
 - #145397 (Rust documentation, use `rustc-dev-guide` :3)
 - #145398 (Use `default_field_values` in `Resolver`)
 - #145401 (cleanup: Remove useless `[T].iter().last()`)
 - #145403 (Adjust error message grammar to be less awkward)

r? `@ghost`
`@rustbot` modify labels: rollup

rust-timer added a commit that referenced this pull request

Aug 15, 2025
Rollup merge of #145233 - joshtriplett:cfg-select-expr, r=jieyouxu

cfg_select: Support unbraced expressions

Tracking issue for `cfg_select`: #115585

When operating on expressions, `cfg_select!` can now handle expressions
without braces. (It still requires braces for other things, such as
items.)

Expand the test coverage and documentation accordingly.

---

I'm not sure whether deciding to extend `cfg_select!` in this way is T-lang or T-libs-api. I've labeled for both, with the request that both teams don't block on each other. :)

github-actions bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request

Aug 18, 2025

github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request

Aug 18, 2025
…eyouxu

cfg_select: Support unbraced expressions

Tracking issue for `cfg_select`: rust-lang#115585

When operating on expressions, `cfg_select!` can now handle expressions
without braces. (It still requires braces for other things, such as
items.)

Expand the test coverage and documentation accordingly.

---

I'm not sure whether deciding to extend `cfg_select!` in this way is T-lang or T-libs-api. I've labeled for both, with the request that both teams don't block on each other. :)

folkertdev

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request

Feb 22, 2026

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request

Feb 22, 2026

jhpratt added a commit to jhpratt/rust that referenced this pull request

Feb 22, 2026

Zalathar added a commit to Zalathar/rust that referenced this pull request

Feb 23, 2026

rust-timer added a commit that referenced this pull request

Feb 23, 2026
Rollup merge of #149783 - folkertdev:stabilize-cfg-select, r=JonathanBrouwer

stabilize `cfg_select!`

*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/149783)*

tracking issue: #115585
closes #115585
reference PR:

- rust-lang/reference#2103

# Request for Stabilization

## Summary

The `cfg_select!` macro picks the expansion corresponding to the first `cfg` condition that evaluates to `true`. It simplifies complex conditional expressions.

```rust
cfg_select! {
    unix => {
        fn foo() { /* unix specific functionality */ }
    }
    target_pointer_width = "32" => {
        fn foo() { /* non-unix, 32-bit functionality */ }
    }
    _ => {
        fn foo() { /* fallback implementation */ }
    }
}

let is_unix_str = cfg_select! {
    unix => "unix",
    _ => "not unix",
};
println!("{is_unix_str}");
```
## Semantics

The expansion of a `cfg_select!` call is the right-hand side of the first `cfg` rule that evaluates to true.

This can be roughly expressed using this macro:
```rust
macro_rules! cfg_select {
    ({ $($tt:tt)* }) => {{
        $crate::cfg_select! { $($tt)* }
    }};
    (_ => { $($output:tt)* }) => {
        $($output)*
    };
    (
        $cfg:meta => $output:tt
        $($( $rest:tt )+)?
    ) => {
        #[cfg($cfg)]
        $crate::cfg_select! { _ => $output }
        $(
            #[cfg(not($cfg))]
            $crate::cfg_select! { $($rest)+ }
        )?
    }
}
```

The actual implementation uses a builtin macro so that `cfg_select!` can be used both in item and expression position.

## Documentation

reference PR:

- rust-lang/reference#2103

## Tests

The `cfg_select!` macro is already used extensively in the rust compiler codebase. It has several dedicated tests:

- [`tests/ui/check-cfg/cfg-select.rs`](https://github.com/rust-lang/rust/blob/main/tests/ui/check-cfg/cfg-select.rs)tests that warnings are emitted when an unexpected `cfg` condition is used.
- [`tests/ui/macros/cfg_select.rs`](https://github.com/rust-lang/rust/blob/main/tests/ui/macros/cfg_select.rs) tests that `cfg_select!` has the expected expansion, and tests that the expected syntax is accepted.
## History

- #115416
- #117162
- #133720
- #135625
- #137198
- #138993
- #138996
- #143461
- #143941
- #145233
- #148712
- #149380
- #149925

# Resolved questions

# Unresolved questions

The style team has decided on how to format `cfg_select!`, but this formatting has not yet been implemented. See #144323.

r? @traviscross

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_CONCERN-ISSUE_START -->

> [!NOTE]
> # Concerns (0 active)
>
> - ~~[allowing-comma-after-closing-brace](#149783 (comment) resolved in [this comment](#149783 (comment))
>
> *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.*

<!-- TRIAGEBOT_CONCERN-ISSUE_END -->
<!-- TRIAGEBOT_END -->

RalfJung pushed a commit to RalfJung/miri that referenced this pull request

Feb 24, 2026