Skip to content

update cfg_select! documentation #143941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a l
builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified
builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified

builtin_macros_cfg_select_no_matches = none of the rules in this `cfg_select` evaluated to true
builtin_macros_cfg_select_no_matches = none of the predicates in this `cfg_select` evaluated to true

builtin_macros_cfg_select_unreachable = unreachable rule
builtin_macros_cfg_select_unreachable = unreachable predicate
.label = always matches
.label2 = this rules is never reached
.label2 = this predicate is never reached

builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized`

Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_builtin_macros/src/cfg_select.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use rustc_ast::tokenstream::TokenStream;
use rustc_attr_parsing as attr;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectRule, parse_cfg_select};
use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectPredicate, parse_cfg_select};
use rustc_span::{Ident, Span, sym};

use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};

/// Selects the first arm whose rule evaluates to true.
/// Selects the first arm whose predicate evaluates to true.
fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
for (cfg, tt, arm_span) in branches.reachable {
if attr::cfg_matches(
Expand All @@ -30,11 +30,11 @@ pub(super) fn expand_cfg_select<'cx>(
ExpandResult::Ready(match parse_cfg_select(&mut ecx.new_parser_from_tts(tts)) {
Ok(branches) => {
if let Some((underscore, _, _)) = branches.wildcard {
// Warn for every unreachable rule. We store the fully parsed branch for rustfmt.
for (rule, _, _) in &branches.unreachable {
let span = match rule {
CfgSelectRule::Wildcard(underscore) => underscore.span,
CfgSelectRule::Cfg(cfg) => cfg.span(),
// Warn for every unreachable predicate. We store the fully parsed branch for rustfmt.
for (predicate, _, _) in &branches.unreachable {
let span = match predicate {
CfgSelectPredicate::Wildcard(underscore) => underscore.span,
CfgSelectPredicate::Cfg(cfg) => cfg.span(),
};
let err = CfgSelectUnreachable { span, wildcard_span: underscore.span };
ecx.dcx().emit_warn(err);
Expand All @@ -50,7 +50,7 @@ pub(super) fn expand_cfg_select<'cx>(
Ident::with_dummy_span(sym::cfg_select),
);
} else {
// Emit a compiler error when none of the rules matched.
// Emit a compiler error when none of the predicates matched.
let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp });
DummyResult::any(sp, guar)
}
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_parse/src/parser/cfg_select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_span::Span;
use crate::exp;
use crate::parser::Parser;

pub enum CfgSelectRule {
pub enum CfgSelectPredicate {
Cfg(MetaItemInner),
Wildcard(Token),
}
Expand All @@ -20,7 +20,7 @@ pub struct CfgSelectBranches {
pub wildcard: Option<(Token, TokenStream, Span)>,
/// All branches after the first wildcard, including further wildcards.
/// These branches are kept for formatting.
pub unreachable: Vec<(CfgSelectRule, TokenStream, Span)>,
pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>,
}

/// Parses a `TokenTree` that must be of the form `{ /* ... */ }`, and returns a `TokenStream` where
Expand Down Expand Up @@ -52,7 +52,7 @@ pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches
match branches.wildcard {
None => branches.wildcard = Some((underscore, tts, span)),
Some(_) => {
branches.unreachable.push((CfgSelectRule::Wildcard(underscore), tts, span))
branches.unreachable.push((CfgSelectPredicate::Wildcard(underscore), tts, span))
}
}
} else {
Expand All @@ -64,7 +64,9 @@ pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches

match branches.wildcard {
None => branches.reachable.push((meta_item, tts, span)),
Some(_) => branches.unreachable.push((CfgSelectRule::Cfg(meta_item), tts, span)),
Some(_) => {
branches.unreachable.push((CfgSelectPredicate::Cfg(meta_item), tts, span))
}
}
}
}
Expand Down
16 changes: 7 additions & 9 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,14 @@ pub macro assert_matches {
},
}

/// A macro for defining `#[cfg]` match-like statements.
/// Selects code at compile-time based on `cfg` predicates.
///
/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
/// `#[cfg]` cases, emitting the implementation which matches first.
/// This macro evaluates, at compile-time, a series of `cfg` predicates,
/// selects the first that is true, and emits the code guarded by that
/// predicate. The code guarded by other predicates is not emitted.
///
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
/// without having to rewrite each clause multiple times.
///
/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
/// all previous declarations do not evaluate to true.
/// An optional trailing `_` wildcard can be used to specify a fallback. If
/// none of the predicates are true, a [`compile_error`] is emitted.
///
/// # Example
///
Expand All @@ -225,7 +223,7 @@ pub macro assert_matches {
/// }
/// ```
///
/// If desired, it is possible to return expressions through the use of surrounding braces:
/// The `cfg_select!` macro can also be used in expression position:
///
/// ```
/// #![feature(cfg_select)]
Expand Down
7 changes: 5 additions & 2 deletions tests/ui/macros/cfg_select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ fn arm_rhs_must_be_in_braces() -> i32 {
cfg_select! {
_ => {}
true => {}
//~^ WARN unreachable rule
//~^ WARN unreachable predicate
}

cfg_select! {
//~^ ERROR none of the rules in this `cfg_select` evaluated to true
//~^ ERROR none of the predicates in this `cfg_select` evaluated to true
false => {}
}

cfg_select! {}
//~^ ERROR none of the predicates in this `cfg_select` evaluated to true
14 changes: 10 additions & 4 deletions tests/ui/macros/cfg_select.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ error: expected `{`, found `1`
LL | true => 1
| ^ expected `{`

warning: unreachable rule
warning: unreachable predicate
--> $DIR/cfg_select.rs:20:5
|
LL | _ => {}
| - always matches
LL | true => {}
| ^^^^ this rules is never reached
| ^^^^ this predicate is never reached

error: none of the rules in this `cfg_select` evaluated to true
error: none of the predicates in this `cfg_select` evaluated to true
--> $DIR/cfg_select.rs:24:1
|
LL | / cfg_select! {
Expand All @@ -21,5 +21,11 @@ LL | | false => {}
LL | | }
| |_^

error: aborting due to 2 previous errors; 1 warning emitted
error: none of the predicates in this `cfg_select` evaluated to true
--> $DIR/cfg_select.rs:29:1
|
LL | cfg_select! {}
| ^^^^^^^^^^^^^^

error: aborting due to 3 previous errors; 1 warning emitted

Loading