rustc_parse/parser/
cfg_select.rs

1use rustc_ast::token;
2use rustc_ast::tokenstream::{TokenStream, TokenTree};
3use rustc_ast::util::classify;
4use rustc_errors::PResult;
5
6use crate::exp;
7use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos};
8
9impl<'a> Parser<'a> {
10    /// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an
11    /// expression followed by a comma (and strip the comma).
12    pub fn parse_delimited_token_tree(&mut self) -> PResult<'a, TokenStream> {
13        if self.token == token::OpenBrace {
14            // Strip the outer '{' and '}'.
15            match self.parse_token_tree() {
16                TokenTree::Token(..) => unreachable!("because of the expect above"),
17                TokenTree::Delimited(.., tts) => return Ok(tts),
18            }
19        }
20        let expr = self.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| {
21            p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty())
22                .map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No))
23        })?;
24        if !classify::expr_is_complete(&expr)
25            && self.token != token::CloseBrace
26            && self.token != token::Eof
27        {
28            self.expect(exp!(Comma))?;
29        } else {
30            let _ = self.eat(exp!(Comma));
31        }
32        Ok(TokenStream::from_ast(&expr))
33    }
34}