@@ -16,15 +16,36 @@ pub(crate) const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are
16
16
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, \
17
17
`meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility";
18
18
19
+ /// Which part of a macro rule we're parsing
20
+ #[ derive( Copy , Clone ) ]
21
+ pub ( crate ) enum RulePart {
22
+ /// The left-hand side, with patterns and metavar definitions with types
23
+ Pattern ,
24
+ /// The right-hand side body, with metavar references and metavar expressions
25
+ Body ,
26
+ }
27
+
28
+ impl RulePart {
29
+ #[ inline( always) ]
30
+ fn is_pattern ( & self ) -> bool {
31
+ matches ! ( self , Self :: Pattern )
32
+ }
33
+
34
+ #[ inline( always) ]
35
+ fn is_body ( & self ) -> bool {
36
+ matches ! ( self , Self :: Body )
37
+ }
38
+ }
39
+
19
40
/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
20
41
/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
21
42
/// collection of `TokenTree` for use in parsing a macro.
22
43
///
23
44
/// # Parameters
24
45
///
25
46
/// - `input`: a token stream to read from, the contents of which we are parsing.
26
- /// - `parsing_patterns `: `parse` can be used to parse either the " patterns" or the " body" of a
27
- /// macro. Both take roughly the same form _except_ that:
47
+ /// - `part `: whether we're parsing the patterns or the body of a macro. Both take roughly the same
48
+ /// form _except_ that:
28
49
/// - In a pattern, metavars are declared with their "matcher" type. For example `$var:expr` or
29
50
/// `$id:ident`. In this example, `expr` and `ident` are "matchers". They are not present in the
30
51
/// body of a macro rule -- just in the pattern.
@@ -38,7 +59,7 @@ pub(crate) const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are
38
59
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
39
60
pub ( super ) fn parse (
40
61
input : & tokenstream:: TokenStream ,
41
- parsing_patterns : bool ,
62
+ part : RulePart ,
42
63
sess : & Session ,
43
64
node_id : NodeId ,
44
65
features : & Features ,
@@ -53,9 +74,9 @@ pub(super) fn parse(
53
74
while let Some ( tree) = iter. next ( ) {
54
75
// Given the parsed tree, if there is a metavar and we are expecting matchers, actually
55
76
// parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
56
- let tree = parse_tree ( tree, & mut iter, parsing_patterns , sess, node_id, features, edition) ;
77
+ let tree = parse_tree ( tree, & mut iter, part , sess, node_id, features, edition) ;
57
78
58
- if !parsing_patterns {
79
+ if part . is_body ( ) {
59
80
// No matchers allowed, nothing to process here
60
81
result. push ( tree) ;
61
82
continue ;
@@ -157,13 +178,13 @@ fn maybe_emit_macro_metavar_expr_concat_feature(features: &Features, sess: &Sess
157
178
/// - `tree`: the tree we wish to convert.
158
179
/// - `outer_iter`: an iterator over trees. We may need to read more tokens from it in order to finish
159
180
/// converting `tree`
160
- /// - `parsing_patterns `: same as [parse].
181
+ /// - `part `: same as [parse].
161
182
/// - `sess`: the parsing session. Any errors will be emitted to this session.
162
183
/// - `features`: language features so we can do feature gating.
163
184
fn parse_tree < ' a > (
164
185
tree : & ' a tokenstream:: TokenTree ,
165
186
outer_iter : & mut TokenStreamIter < ' a > ,
166
- parsing_patterns : bool ,
187
+ part : RulePart ,
167
188
sess : & Session ,
168
189
node_id : NodeId ,
169
190
features : & Features ,
@@ -189,7 +210,7 @@ fn parse_tree<'a>(
189
210
match next {
190
211
// `tree` is followed by a delimited set of token trees.
191
212
Some ( & tokenstream:: TokenTree :: Delimited ( delim_span, _, delim, ref tts) ) => {
192
- if parsing_patterns {
213
+ if part . is_pattern ( ) {
193
214
if delim != Delimiter :: Parenthesis {
194
215
span_dollar_dollar_or_metavar_in_the_lhs_err (
195
216
sess,
@@ -244,13 +265,13 @@ fn parse_tree<'a>(
244
265
// If we didn't find a metavar expression above, then we must have a
245
266
// repetition sequence in the macro (e.g. `$(pat)*`). Parse the
246
267
// contents of the sequence itself
247
- let sequence = parse ( tts, parsing_patterns , sess, node_id, features, edition) ;
268
+ let sequence = parse ( tts, part , sess, node_id, features, edition) ;
248
269
// Get the Kleene operator and optional separator
249
270
let ( separator, kleene) =
250
271
parse_sep_and_kleene_op ( & mut iter, delim_span. entire ( ) , sess) ;
251
272
// Count the number of captured "names" (i.e., named metavars)
252
273
let num_captures =
253
- if parsing_patterns { count_metavar_decls ( & sequence) } else { 0 } ;
274
+ if part . is_pattern ( ) { count_metavar_decls ( & sequence) } else { 0 } ;
254
275
TokenTree :: Sequence (
255
276
delim_span,
256
277
SequenceRepetition { tts : sequence, separator, kleene, num_captures } ,
@@ -274,7 +295,7 @@ fn parse_tree<'a>(
274
295
Token { kind : token:: Dollar , span : dollar_span2 } ,
275
296
_,
276
297
) ) => {
277
- if parsing_patterns {
298
+ if part . is_pattern ( ) {
278
299
span_dollar_dollar_or_metavar_in_the_lhs_err (
279
300
sess,
280
301
& Token { kind : token:: Dollar , span : dollar_span2 } ,
@@ -306,10 +327,7 @@ fn parse_tree<'a>(
306
327
& tokenstream:: TokenTree :: Delimited ( span, spacing, delim, ref tts) => TokenTree :: Delimited (
307
328
span,
308
329
spacing,
309
- Delimited {
310
- delim,
311
- tts : parse ( tts, parsing_patterns, sess, node_id, features, edition) ,
312
- } ,
330
+ Delimited { delim, tts : parse ( tts, part, sess, node_id, features, edition) } ,
313
331
) ,
314
332
}
315
333
}
0 commit comments