cfg_select: Support unbraced expressions
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.
This commit is contained in:
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user