mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-28 03:07:24 +03:00
6bcb461903
stabilize `cfg_select!` *[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/149783)* tracking issue: https://github.com/rust-lang/rust/issues/115585 closes https://github.com/rust-lang/rust/issues/115585 reference PR: - https://github.com/rust-lang/reference/pull/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: - https://github.com/rust-lang/reference/pull/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 - rust-lang/rust#115416 - rust-lang/rust#117162 - rust-lang/rust#133720 - rust-lang/rust#135625 - rust-lang/rust#137198 - rust-lang/rust#138993 - rust-lang/rust#138996 - rust-lang/rust#143461 - rust-lang/rust#143941 - rust-lang/rust#145233 - rust-lang/rust#148712 - rust-lang/rust#149380 - https://github.com/rust-lang/rust/pull/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 https://github.com/rust-lang/rust/pull/144323. r? @traviscross <!-- TRIAGEBOT_START --> <!-- TRIAGEBOT_CONCERN-ISSUE_START --> > [!NOTE] > # Concerns (0 active) > > - ~~[allowing-comma-after-closing-brace](https://github.com/rust-lang/rust/pull/149783#issuecomment-3808533494)~~ resolved in [this comment](https://github.com/rust-lang/rust/pull/149783#issuecomment-3882251672) > > *Managed by `@rustbot`—see [help](https://forge.rust-lang.org/triagebot/concern.html) for details.* <!-- TRIAGEBOT_CONCERN-ISSUE_END --> <!-- TRIAGEBOT_END -->