@@ -16,15 +16,36 @@ pub(crate) const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are
1616 `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, \
1717 `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility";
1818
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+
1940/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
2041/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
2142/// collection of `TokenTree` for use in parsing a macro.
2243///
2344/// # Parameters
2445///
2546/// - `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:
2849/// - In a pattern, metavars are declared with their "matcher" type. For example `$var:expr` or
2950/// `$id:ident`. In this example, `expr` and `ident` are "matchers". They are not present in the
3051/// 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
3859/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
3960pub ( super ) fn parse (
4061 input : & tokenstream:: TokenStream ,
41- parsing_patterns : bool ,
62+ part : RulePart ,
4263 sess : & Session ,
4364 node_id : NodeId ,
4465 features : & Features ,
@@ -53,9 +74,9 @@ pub(super) fn parse(
5374 while let Some ( tree) = iter. next ( ) {
5475 // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
5576 // 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) ;
5778
58- if !parsing_patterns {
79+ if part . is_body ( ) {
5980 // No matchers allowed, nothing to process here
6081 result. push ( tree) ;
6182 continue ;
@@ -157,13 +178,13 @@ fn maybe_emit_macro_metavar_expr_concat_feature(features: &Features, sess: &Sess
157178/// - `tree`: the tree we wish to convert.
158179/// - `outer_iter`: an iterator over trees. We may need to read more tokens from it in order to finish
159180/// converting `tree`
160- /// - `parsing_patterns `: same as [parse].
181+ /// - `part `: same as [parse].
161182/// - `sess`: the parsing session. Any errors will be emitted to this session.
162183/// - `features`: language features so we can do feature gating.
163184fn parse_tree < ' a > (
164185 tree : & ' a tokenstream:: TokenTree ,
165186 outer_iter : & mut TokenStreamIter < ' a > ,
166- parsing_patterns : bool ,
187+ part : RulePart ,
167188 sess : & Session ,
168189 node_id : NodeId ,
169190 features : & Features ,
@@ -189,7 +210,7 @@ fn parse_tree<'a>(
189210 match next {
190211 // `tree` is followed by a delimited set of token trees.
191212 Some ( & tokenstream:: TokenTree :: Delimited ( delim_span, _, delim, ref tts) ) => {
192- if parsing_patterns {
213+ if part . is_pattern ( ) {
193214 if delim != Delimiter :: Parenthesis {
194215 span_dollar_dollar_or_metavar_in_the_lhs_err (
195216 sess,
@@ -244,13 +265,13 @@ fn parse_tree<'a>(
244265 // If we didn't find a metavar expression above, then we must have a
245266 // repetition sequence in the macro (e.g. `$(pat)*`). Parse the
246267 // 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) ;
248269 // Get the Kleene operator and optional separator
249270 let ( separator, kleene) =
250271 parse_sep_and_kleene_op ( & mut iter, delim_span. entire ( ) , sess) ;
251272 // Count the number of captured "names" (i.e., named metavars)
252273 let num_captures =
253- if parsing_patterns { count_metavar_decls ( & sequence) } else { 0 } ;
274+ if part . is_pattern ( ) { count_metavar_decls ( & sequence) } else { 0 } ;
254275 TokenTree :: Sequence (
255276 delim_span,
256277 SequenceRepetition { tts : sequence, separator, kleene, num_captures } ,
@@ -274,7 +295,7 @@ fn parse_tree<'a>(
274295 Token { kind : token:: Dollar , span : dollar_span2 } ,
275296 _,
276297 ) ) => {
277- if parsing_patterns {
298+ if part . is_pattern ( ) {
278299 span_dollar_dollar_or_metavar_in_the_lhs_err (
279300 sess,
280301 & Token { kind : token:: Dollar , span : dollar_span2 } ,
@@ -306,10 +327,7 @@ fn parse_tree<'a>(
306327 & tokenstream:: TokenTree :: Delimited ( span, spacing, delim, ref tts) => TokenTree :: Delimited (
307328 span,
308329 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) } ,
313331 ) ,
314332 }
315333}
0 commit comments