rustc_parse/parser/
cfg_select.rs1use rustc_ast::tokenstream::{TokenStream, TokenTree};
2use rustc_ast::util::classify;
3use rustc_ast::{AttrKind, token};
4use rustc_errors::PResult;
5use rustc_span::Span;
6
7use crate::exp;
8use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos};
9
10#[derive(#[automatically_derived]
impl ::core::default::Default for CfgSelectBranchAttrSpans {
#[inline]
fn default() -> CfgSelectBranchAttrSpans {
CfgSelectBranchAttrSpans {
attrs: ::core::default::Default::default(),
doc_comments: ::core::default::Default::default(),
}
}
}Default)]
11pub struct CfgSelectBranchAttrSpans {
12 pub attrs: Vec<Span>,
13 pub doc_comments: Vec<Span>,
14}
15
16impl<'a> Parser<'a> {
17 pub fn parse_cfg_select_branch_rhs(&mut self) -> PResult<'a, TokenStream> {
20 if self.token == token::OpenBrace {
21 match self.parse_token_tree() {
23 TokenTree::Token(..) => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("because the current token is a \'{{\'")));
}unreachable!("because the current token is a '{{'"),
24 TokenTree::Delimited(.., tts) => {
25 let _ = self.eat(crate::parser::token_type::ExpTokenPair {
tok: rustc_ast::token::Comma,
token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma));
27 return Ok(tts);
28 }
29 }
30 }
31 let attrs = AttrWrapper::empty(); let expr = self.collect_tokens(
33 None,
34 AttrWrapper::empty(),
35 ForceCollect::Yes,
36 |p, _empty_attrs| {
37 p.parse_expr_res_after_attrs(Restrictions::STMT_EXPR, attrs)
38 .map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No))
39 },
40 )?;
41 if !classify::expr_is_complete(&expr)
42 && self.token != token::CloseBrace
43 && self.token != token::Eof
44 {
45 self.expect(crate::parser::token_type::ExpTokenPair {
tok: rustc_ast::token::Comma,
token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma))?;
46 } else {
47 let _ = self.eat(crate::parser::token_type::ExpTokenPair {
tok: rustc_ast::token::Comma,
token_type: crate::parser::token_type::TokenType::Comma,
}exp!(Comma));
48 }
49 Ok(TokenStream::from_ast(&expr))
50 }
51
52 pub fn parse_cfg_select_branch_outer_attrs(
54 &mut self,
55 ) -> PResult<'a, Option<CfgSelectBranchAttrSpans>> {
56 let attrs = self.parse_outer_attributes()?;
57 if attrs.is_empty() {
58 return Ok(None);
59 }
60
61 let mut spans = CfgSelectBranchAttrSpans::default();
62 for attr in attrs.take_for_recovery(self.psess) {
63 match attr.kind {
64 AttrKind::Normal(..) => spans.attrs.push(attr.span),
65 AttrKind::Synthetic(..) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
66 AttrKind::DocComment(comment_kind, _)
69 if self.span_to_snippet(attr.span).ok().is_some_and(
70 |snippet| match comment_kind {
71 token::CommentKind::Line => snippet.starts_with("//!"),
72 token::CommentKind::Block => snippet.starts_with("/*!"),
73 },
74 ) => {}
75 AttrKind::DocComment(..) => spans.doc_comments.push(attr.span),
76 }
77 }
78
79 Ok(Some(spans))
80 }
81}