diff options
| author | Jakub Beránek <berykubik@gmail.com> | 2025-08-14 21:48:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-14 21:48:42 +0200 |
| commit | 01bd889098a6d9f7125bf4643d60ce9b95c8edf6 (patch) | |
| tree | e223edd3f8cb1408e1ff4e0a53e8e3562ca6e6fc /compiler/rustc_parse/src | |
| parent | fadd083512ce90d359a4ee07a8454a69c5538527 (diff) | |
| parent | 38df15805ba5be78d70c515f1d585ee6be95e13b (diff) | |
| download | rust-01bd889098a6d9f7125bf4643d60ce9b95c8edf6.tar.gz rust-01bd889098a6d9f7125bf4643d60ce9b95c8edf6.zip | |
Rollup merge of #145233 - joshtriplett:cfg-select-expr, r=jieyouxu
cfg_select: Support unbraced expressions Tracking issue for `cfg_select`: rust-lang/rust#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. :)
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/cfg_select.rs | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs index 2c6fb224d70..08a71db4de8 100644 --- a/compiler/rustc_parse/src/parser/cfg_select.rs +++ b/compiler/rustc_parse/src/parser/cfg_select.rs @@ -1,11 +1,12 @@ use rustc_ast::token::Token; use rustc_ast::tokenstream::{TokenStream, TokenTree}; +use rustc_ast::util::classify; use rustc_ast::{MetaItemInner, token}; use rustc_errors::PResult; use rustc_span::Span; use crate::exp; -use crate::parser::Parser; +use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos}; pub enum CfgSelectPredicate { Cfg(MetaItemInner), @@ -23,19 +24,26 @@ pub struct CfgSelectBranches { pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>, } -/// Parses a `TokenTree` that must be of the form `{ /* ... */ }`, and returns a `TokenStream` where -/// the surrounding braces are stripped. +/// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an +/// expression followed by a comma (and strip the comma). fn parse_token_tree<'a>(p: &mut Parser<'a>) -> PResult<'a, TokenStream> { - // Generate an error if the `=>` is not followed by `{`. - if p.token != token::OpenBrace { - p.expect(exp!(OpenBrace))?; + if p.token == token::OpenBrace { + // Strip the outer '{' and '}'. + match p.parse_token_tree() { + TokenTree::Token(..) => unreachable!("because of the expect above"), + TokenTree::Delimited(.., tts) => return Ok(tts), + } } - - // Strip the outer '{' and '}'. - match p.parse_token_tree() { - TokenTree::Token(..) => unreachable!("because of the expect above"), - TokenTree::Delimited(.., tts) => Ok(tts), + let expr = p.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| { + p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty()) + .map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No)) + })?; + if !classify::expr_is_complete(&expr) && p.token != token::CloseBrace && p.token != token::Eof { + p.expect(exp!(Comma))?; + } else { + let _ = p.eat(exp!(Comma)); } + Ok(TokenStream::from_ast(&expr)) } pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> { |
