Skip to content

Commit c854779

Browse files
Move parse_cfg_select to rustc_builtin_macros
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
1 parent 87f9dcd commit c854779

File tree

2 files changed

+79
-72
lines changed

2 files changed

+79
-72
lines changed

compiler/rustc_builtin_macros/src/cfg_select.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
1+
use rustc_ast::token::Token;
12
use rustc_ast::tokenstream::TokenStream;
3+
use rustc_ast::{MetaItemInner, token};
24
use rustc_attr_parsing as attr;
5+
use rustc_errors::PResult;
36
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
4-
use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectPredicate, parse_cfg_select};
7+
use rustc_parse::exp;
8+
use rustc_parse::parser::Parser;
59
use rustc_span::{Ident, Span, sym};
610

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

13+
enum CfgSelectPredicate {
14+
Cfg(MetaItemInner),
15+
Wildcard(Token),
16+
}
17+
18+
#[derive(Default)]
19+
struct CfgSelectBranches {
20+
/// All the conditional branches.
21+
pub reachable: Vec<(MetaItemInner, TokenStream, Span)>,
22+
/// The first wildcard `_ => { ... }` branch.
23+
pub wildcard: Option<(Token, TokenStream, Span)>,
24+
/// All branches after the first wildcard, including further wildcards.
25+
/// These branches are kept for formatting.
26+
pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>,
27+
}
28+
929
/// Selects the first arm whose predicate evaluates to true.
1030
fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
1131
for (cfg, tt, arm_span) in branches.reachable {
@@ -61,3 +81,39 @@ pub(super) fn expand_cfg_select<'cx>(
6181
}
6282
})
6383
}
84+
85+
fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> {
86+
let mut branches = CfgSelectBranches::default();
87+
88+
while p.token != token::Eof {
89+
if p.eat_keyword(exp!(Underscore)) {
90+
let underscore = p.prev_token;
91+
p.expect(exp!(FatArrow))?;
92+
93+
let tts = p.parse_delimited_token_tree()?;
94+
let span = underscore.span.to(p.token.span);
95+
96+
match branches.wildcard {
97+
None => branches.wildcard = Some((underscore, tts, span)),
98+
Some(_) => {
99+
branches.unreachable.push((CfgSelectPredicate::Wildcard(underscore), tts, span))
100+
}
101+
}
102+
} else {
103+
let meta_item = p.parse_meta_item_inner()?;
104+
p.expect(exp!(FatArrow))?;
105+
106+
let tts = p.parse_delimited_token_tree()?;
107+
let span = meta_item.span().to(p.token.span);
108+
109+
match branches.wildcard {
110+
None => branches.reachable.push((meta_item, tts, span)),
111+
Some(_) => {
112+
branches.unreachable.push((CfgSelectPredicate::Cfg(meta_item), tts, span))
113+
}
114+
}
115+
}
116+
}
117+
118+
Ok(branches)
119+
}
Lines changed: 22 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,34 @@
1-
use rustc_ast::token::Token;
1+
use rustc_ast::token;
22
use rustc_ast::tokenstream::{TokenStream, TokenTree};
33
use rustc_ast::util::classify;
4-
use rustc_ast::{MetaItemInner, token};
54
use rustc_errors::PResult;
6-
use rustc_span::Span;
75

86
use crate::exp;
97
use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos};
108

11-
pub enum CfgSelectPredicate {
12-
Cfg(MetaItemInner),
13-
Wildcard(Token),
14-
}
15-
16-
#[derive(Default)]
17-
pub struct CfgSelectBranches {
18-
/// All the conditional branches.
19-
pub reachable: Vec<(MetaItemInner, TokenStream, Span)>,
20-
/// The first wildcard `_ => { ... }` branch.
21-
pub wildcard: Option<(Token, TokenStream, Span)>,
22-
/// All branches after the first wildcard, including further wildcards.
23-
/// These branches are kept for formatting.
24-
pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>,
25-
}
26-
27-
/// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an
28-
/// expression followed by a comma (and strip the comma).
29-
fn parse_token_tree<'a>(p: &mut Parser<'a>) -> PResult<'a, TokenStream> {
30-
if p.token == token::OpenBrace {
31-
// Strip the outer '{' and '}'.
32-
match p.parse_token_tree() {
33-
TokenTree::Token(..) => unreachable!("because of the expect above"),
34-
TokenTree::Delimited(.., tts) => return Ok(tts),
35-
}
36-
}
37-
let expr = p.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| {
38-
p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty())
39-
.map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No))
40-
})?;
41-
if !classify::expr_is_complete(&expr) && p.token != token::CloseBrace && p.token != token::Eof {
42-
p.expect(exp!(Comma))?;
43-
} else {
44-
let _ = p.eat(exp!(Comma));
45-
}
46-
Ok(TokenStream::from_ast(&expr))
47-
}
48-
49-
pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> {
50-
let mut branches = CfgSelectBranches::default();
51-
52-
while p.token != token::Eof {
53-
if p.eat_keyword(exp!(Underscore)) {
54-
let underscore = p.prev_token;
55-
p.expect(exp!(FatArrow))?;
56-
57-
let tts = parse_token_tree(p)?;
58-
let span = underscore.span.to(p.token.span);
59-
60-
match branches.wildcard {
61-
None => branches.wildcard = Some((underscore, tts, span)),
62-
Some(_) => {
63-
branches.unreachable.push((CfgSelectPredicate::Wildcard(underscore), tts, span))
64-
}
9+
impl<'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),
6518
}
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))?;
6629
} else {
67-
let meta_item = p.parse_meta_item_inner()?;
68-
p.expect(exp!(FatArrow))?;
69-
70-
let tts = parse_token_tree(p)?;
71-
let span = meta_item.span().to(p.token.span);
72-
73-
match branches.wildcard {
74-
None => branches.reachable.push((meta_item, tts, span)),
75-
Some(_) => {
76-
branches.unreachable.push((CfgSelectPredicate::Cfg(meta_item), tts, span))
77-
}
78-
}
30+
let _ = self.eat(exp!(Comma));
7931
}
32+
Ok(TokenStream::from_ast(&expr))
8033
}
81-
82-
Ok(branches)
8334
}

0 commit comments

Comments
 (0)