Skip to content

Commit 557c1e3

Browse files
Merge #7494
7494: Simpilfy mbe parsing r=edwin0cheng a=edwin0cheng bors r+ Co-authored-by: Edwin Cheng <[email protected]>
2 parents 715dade + 438b34d commit 557c1e3

File tree

4 files changed

+71
-74
lines changed

4 files changed

+71
-74
lines changed

crates/mbe/src/expander/matcher.rs

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub(super) struct Match {
7070
}
7171

7272
impl Match {
73-
pub(super) fn add_err(&mut self, err: ExpandError) {
73+
fn add_err(&mut self, err: ExpandError) {
7474
let prev_err = self.err.take();
7575
self.err = prev_err.or(Some(err));
7676
self.err_count += 1;
@@ -79,12 +79,10 @@ impl Match {
7979

8080
/// Matching errors are added to the `Match`.
8181
pub(super) fn match_(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
82-
assert!(pattern.delimiter == None);
83-
8482
let mut res = Match::default();
8583
let mut src = TtIter::new(src);
8684

87-
match_subtree(&mut res, pattern, &mut src);
85+
match_tokens(&mut res, pattern, &mut src);
8886

8987
if src.len() > 0 {
9088
res.unmatched_tts += src.len();
@@ -94,49 +92,29 @@ pub(super) fn match_(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
9492
res
9593
}
9694

97-
fn match_subtree(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) {
95+
fn match_tokens(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) {
9896
for op in pattern.iter() {
9997
match op {
10098
Op::Leaf(lhs) => {
101-
let rhs = match src.expect_leaf() {
102-
Ok(l) => l,
103-
Err(()) => {
104-
res.add_err(err!("expected leaf: `{}`", lhs));
105-
continue;
106-
}
107-
};
108-
match (lhs, rhs) {
109-
(
110-
tt::Leaf::Punct(tt::Punct { char: lhs, .. }),
111-
tt::Leaf::Punct(tt::Punct { char: rhs, .. }),
112-
) if lhs == rhs => (),
113-
(
114-
tt::Leaf::Ident(tt::Ident { text: lhs, .. }),
115-
tt::Leaf::Ident(tt::Ident { text: rhs, .. }),
116-
) if lhs == rhs => (),
117-
(
118-
tt::Leaf::Literal(tt::Literal { text: lhs, .. }),
119-
tt::Leaf::Literal(tt::Literal { text: rhs, .. }),
120-
) if lhs == rhs => (),
121-
_ => {
122-
res.add_err(ExpandError::UnexpectedToken);
123-
}
99+
if let Err(err) = match_leaf(lhs, src) {
100+
res.add_err(err);
101+
continue;
124102
}
125103
}
126-
Op::Subtree(lhs) => {
104+
Op::Subtree { tokens, delimiter: delim } => {
127105
let rhs = match src.expect_subtree() {
128106
Ok(s) => s,
129107
Err(()) => {
130108
res.add_err(err!("expected subtree"));
131109
continue;
132110
}
133111
};
134-
if lhs.delimiter_kind() != rhs.delimiter_kind() {
112+
if delim.map(|it| it.kind) != rhs.delimiter_kind() {
135113
res.add_err(err!("mismatched delimiter"));
136114
continue;
137115
}
138116
let mut src = TtIter::new(rhs);
139-
match_subtree(res, lhs, &mut src);
117+
match_tokens(res, tokens, &mut src);
140118
if src.len() > 0 {
141119
res.add_err(err!("leftover tokens"));
142120
}
@@ -162,14 +140,42 @@ fn match_subtree(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) {
162140
res.add_err(err);
163141
}
164142
}
165-
Op::Repeat { subtree, kind, separator } => {
143+
Op::Repeat { tokens: subtree, kind, separator } => {
166144
match_repeat(res, subtree, *kind, separator, src);
167145
}
168146
}
169147
}
170148
}
171149

172-
pub(super) fn match_repeat(
150+
fn match_leaf(lhs: &tt::Leaf, src: &mut TtIter) -> Result<(), ExpandError> {
151+
let rhs = match src.expect_leaf() {
152+
Ok(l) => l,
153+
Err(()) => {
154+
return Err(err!("expected leaf: `{}`", lhs));
155+
}
156+
};
157+
match (lhs, rhs) {
158+
(
159+
tt::Leaf::Punct(tt::Punct { char: lhs, .. }),
160+
tt::Leaf::Punct(tt::Punct { char: rhs, .. }),
161+
) if lhs == rhs => (),
162+
(
163+
tt::Leaf::Ident(tt::Ident { text: lhs, .. }),
164+
tt::Leaf::Ident(tt::Ident { text: rhs, .. }),
165+
) if lhs == rhs => (),
166+
(
167+
tt::Leaf::Literal(tt::Literal { text: lhs, .. }),
168+
tt::Leaf::Literal(tt::Literal { text: rhs, .. }),
169+
) if lhs == rhs => (),
170+
_ => {
171+
return Err(ExpandError::UnexpectedToken);
172+
}
173+
}
174+
175+
Ok(())
176+
}
177+
178+
fn match_repeat(
173179
res: &mut Match,
174180
pattern: &MetaTemplate,
175181
kind: RepeatKind,
@@ -191,7 +197,7 @@ pub(super) fn match_repeat(
191197
}
192198

193199
let mut nested = Match::default();
194-
match_subtree(&mut nested, pattern, &mut fork);
200+
match_tokens(&mut nested, pattern, &mut fork);
195201
if nested.err.is_none() {
196202
limit -= 1;
197203
if limit == 0 {
@@ -292,8 +298,8 @@ fn collect_vars(buf: &mut Vec<SmolStr>, pattern: &MetaTemplate) {
292298
match op {
293299
Op::Var { name, .. } => buf.push(name.clone()),
294300
Op::Leaf(_) => (),
295-
Op::Subtree(subtree) => collect_vars(buf, subtree),
296-
Op::Repeat { subtree, .. } => collect_vars(buf, subtree),
301+
Op::Subtree { tokens, .. } => collect_vars(buf, tokens),
302+
Op::Repeat { tokens, .. } => collect_vars(buf, tokens),
297303
}
298304
}
299305
}
@@ -325,7 +331,7 @@ impl<'a> TtIter<'a> {
325331
ok
326332
}
327333

328-
pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> {
334+
fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> {
329335
match self.peek_n(0) {
330336
Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '\'' => {
331337
return self.expect_lifetime();
@@ -386,7 +392,7 @@ impl<'a> TtIter<'a> {
386392
}
387393
}
388394

389-
pub(crate) fn expect_lifetime(&mut self) -> Result<tt::TokenTree, ()> {
395+
fn expect_lifetime(&mut self) -> Result<tt::TokenTree, ()> {
390396
let punct = self.expect_punct()?;
391397
if punct.char != '\'' {
392398
return Err(());
@@ -403,13 +409,13 @@ impl<'a> TtIter<'a> {
403409
.into())
404410
}
405411

406-
pub(crate) fn expect_fragment(
412+
fn expect_fragment(
407413
&mut self,
408414
fragment_kind: parser::FragmentKind,
409415
) -> ExpandResult<Option<tt::TokenTree>> {
410-
pub(crate) struct OffsetTokenSink<'a> {
411-
pub(crate) cursor: Cursor<'a>,
412-
pub(crate) error: bool,
416+
struct OffsetTokenSink<'a> {
417+
cursor: Cursor<'a>,
418+
error: bool,
413419
}
414420

415421
impl<'a> TreeSink for OffsetTokenSink<'a> {
@@ -465,7 +471,7 @@ impl<'a> TtIter<'a> {
465471
ExpandResult { value: res, err }
466472
}
467473

468-
pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> {
474+
fn eat_vis(&mut self) -> Option<tt::TokenTree> {
469475
let mut fork = self.clone();
470476
match fork.expect_fragment(Visibility) {
471477
ExpandResult { value: tt, err: None } => {
@@ -476,7 +482,7 @@ impl<'a> TtIter<'a> {
476482
}
477483
}
478484

479-
pub(crate) fn eat_char(&mut self, c: char) -> Option<tt::TokenTree> {
485+
fn eat_char(&mut self, c: char) -> Option<tt::TokenTree> {
480486
let mut fork = self.clone();
481487
match fork.expect_char(c) {
482488
Ok(_) => {

crates/mbe/src/expander/transcriber.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! `$ident => foo`, interpolates variables in the template, to get `fn foo() {}`
33
44
use syntax::SmolStr;
5+
use tt::Delimiter;
56

67
use super::ExpandResult;
78
use crate::{
@@ -54,10 +55,9 @@ pub(super) fn transcribe(
5455
template: &MetaTemplate,
5556
bindings: &Bindings,
5657
) -> ExpandResult<tt::Subtree> {
57-
assert!(template.delimiter == None);
5858
let mut ctx = ExpandCtx { bindings: &bindings, nesting: Vec::new() };
5959
let mut arena: Vec<tt::TokenTree> = Vec::new();
60-
expand_subtree(&mut ctx, template, &mut arena)
60+
expand_subtree(&mut ctx, template, None, &mut arena)
6161
}
6262

6363
#[derive(Debug)]
@@ -80,6 +80,7 @@ struct ExpandCtx<'a> {
8080
fn expand_subtree(
8181
ctx: &mut ExpandCtx,
8282
template: &MetaTemplate,
83+
delimiter: Option<Delimiter>,
8384
arena: &mut Vec<tt::TokenTree>,
8485
) -> ExpandResult<tt::Subtree> {
8586
// remember how many elements are in the arena now - when returning, we want to drain exactly how many elements we added. This way, the recursive uses of the arena get their own "view" of the arena, but will reuse the allocation
@@ -88,8 +89,9 @@ fn expand_subtree(
8889
for op in template.iter() {
8990
match op {
9091
Op::Leaf(tt) => arena.push(tt.clone().into()),
91-
Op::Subtree(tt) => {
92-
let ExpandResult { value: tt, err: e } = expand_subtree(ctx, &tt, arena);
92+
Op::Subtree { tokens, delimiter } => {
93+
let ExpandResult { value: tt, err: e } =
94+
expand_subtree(ctx, &tokens, *delimiter, arena);
9395
err = err.or(e);
9496
arena.push(tt.into());
9597
}
@@ -98,7 +100,7 @@ fn expand_subtree(
98100
err = err.or(e);
99101
push_fragment(arena, fragment);
100102
}
101-
Op::Repeat { subtree, kind, separator } => {
103+
Op::Repeat { tokens: subtree, kind, separator } => {
102104
let ExpandResult { value: fragment, err: e } =
103105
expand_repeat(ctx, subtree, *kind, separator, arena);
104106
err = err.or(e);
@@ -108,7 +110,7 @@ fn expand_subtree(
108110
}
109111
// drain the elements added in this instance of expand_subtree
110112
let tts = arena.drain(start_elements..arena.len()).collect();
111-
ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err }
113+
ExpandResult { value: tt::Subtree { delimiter, token_trees: tts }, err }
112114
}
113115

114116
fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> {
@@ -162,7 +164,7 @@ fn expand_repeat(
162164
let mut counter = 0;
163165

164166
loop {
165-
let ExpandResult { value: mut t, err: e } = expand_subtree(ctx, template, arena);
167+
let ExpandResult { value: mut t, err: e } = expand_subtree(ctx, template, None, arena);
166168
let nesting_state = ctx.nesting.last_mut().unwrap();
167169
if nesting_state.at_end || !nesting_state.hit {
168170
break;

crates/mbe/src/lib.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,11 @@ struct Rule {
9292
}
9393

9494
#[derive(Clone, Debug, PartialEq, Eq)]
95-
struct MetaTemplate {
96-
delimiter: Option<Delimiter>,
97-
tokens: Vec<Op>,
98-
}
95+
struct MetaTemplate(Vec<Op>);
9996

10097
impl<'a> MetaTemplate {
10198
fn iter(&self) -> impl Iterator<Item = &Op> {
102-
self.tokens.iter()
103-
}
104-
105-
fn delimiter_kind(&self) -> Option<DelimiterKind> {
106-
self.delimiter.map(|it| it.kind)
99+
self.0.iter()
107100
}
108101
}
109102

@@ -288,8 +281,8 @@ impl Rule {
288281
.expect_subtree()
289282
.map_err(|()| ParseError::Expected("expected subtree".to_string()))?;
290283

291-
let lhs = MetaTemplate { tokens: parse_pattern(&lhs)?, delimiter: None };
292-
let rhs = MetaTemplate { tokens: parse_template(&rhs)?, delimiter: None };
284+
let lhs = MetaTemplate(parse_pattern(&lhs)?);
285+
let rhs = MetaTemplate(parse_template(&rhs)?);
293286

294287
Ok(crate::Rule { lhs, rhs })
295288
}
@@ -298,8 +291,8 @@ impl Rule {
298291
fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> {
299292
for op in pattern.iter() {
300293
match op {
301-
Op::Subtree(subtree) => validate(&subtree)?,
302-
Op::Repeat { subtree, separator, .. } => {
294+
Op::Subtree { tokens, .. } => validate(&tokens)?,
295+
Op::Repeat { tokens: subtree, separator, .. } => {
303296
// Checks that no repetition which could match an empty token
304297
// https://github.com/rust-lang/rust/blob/a58b1ed44f5e06976de2bdc4d7dc81c36a96934f/src/librustc_expand/mbe/macro_rules.rs#L558
305298

@@ -319,7 +312,7 @@ fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> {
319312
)
320313
}
321314
Op::Leaf(_) => {}
322-
Op::Subtree(_) => {}
315+
Op::Subtree { .. } => {}
323316
}
324317
false
325318
}) {

crates/mbe/src/parser.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
44
use smallvec::SmallVec;
55
use syntax::SmolStr;
6+
use tt::Delimiter;
67

78
use crate::{tt_iter::TtIter, MetaTemplate, ParseError};
89

910
#[derive(Clone, Debug, PartialEq, Eq)]
1011
pub(crate) enum Op {
1112
Var { name: SmolStr, kind: Option<SmolStr>, id: tt::TokenId },
12-
Repeat { subtree: MetaTemplate, kind: RepeatKind, separator: Option<Separator> },
13+
Repeat { tokens: MetaTemplate, kind: RepeatKind, separator: Option<Separator> },
1314
Leaf(tt::Leaf),
14-
Subtree(MetaTemplate),
15+
Subtree { tokens: MetaTemplate, delimiter: Option<Delimiter> },
1516
}
1617

1718
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -92,12 +93,10 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
9293
match second {
9394
tt::TokenTree::Subtree(subtree) => {
9495
let (separator, kind) = parse_repeat(src)?;
95-
let delimiter = subtree.delimiter;
9696
let tokens = parse_inner(&subtree, mode)
9797
.into_iter()
9898
.collect::<Result<Vec<Op>, ParseError>>()?;
99-
let subtree = MetaTemplate { tokens, delimiter };
100-
Op::Repeat { subtree, separator, kind }
99+
Op::Repeat { tokens: MetaTemplate(tokens), separator, kind }
101100
}
102101
tt::TokenTree::Leaf(leaf) => match leaf {
103102
tt::Leaf::Punct(punct) => {
@@ -136,12 +135,9 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
136135
}
137136
tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()),
138137
tt::TokenTree::Subtree(subtree) => {
139-
let delimiter = subtree.delimiter;
140138
let tokens =
141139
parse_inner(&subtree, mode).into_iter().collect::<Result<Vec<Op>, ParseError>>()?;
142-
143-
let subtree = MetaTemplate { tokens, delimiter };
144-
Op::Subtree(subtree)
140+
Op::Subtree { tokens: MetaTemplate(tokens), delimiter: subtree.delimiter }
145141
}
146142
};
147143
Ok(res)

0 commit comments

Comments
 (0)