Skip to content

Commit 6b71399

Browse files
committed
mbe: Introduce an enum for which part of a rule we're parsing
Rather than a `bool` that's `true` for the LHS and `false` for the RHS, use a self-documenting enum.
1 parent f0b67dd commit 6b71399

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use crate::base::{
3636
};
3737
use crate::expand::{AstFragment, AstFragmentKind, ensure_complete_parse, parse_ast_fragment};
3838
use crate::mbe::macro_parser::{Error, ErrorReported, Failure, MatcherLoc, Success, TtParser};
39+
use crate::mbe::quoted::RulePart;
3940
use crate::mbe::transcribe::transcribe;
4041
use crate::mbe::{self, KleeneOp, macro_check};
4142

@@ -396,7 +397,7 @@ pub fn compile_declarative_macro(
396397
let lhs_tt = p.parse_token_tree();
397398
let lhs_tt = mbe::quoted::parse(
398399
&TokenStream::new(vec![lhs_tt]),
399-
true, // LHS
400+
RulePart::Pattern,
400401
sess,
401402
node_id,
402403
features,
@@ -423,7 +424,7 @@ pub fn compile_declarative_macro(
423424
let rhs_tt = p.parse_token_tree();
424425
let rhs_tt = mbe::quoted::parse(
425426
&TokenStream::new(vec![rhs_tt]),
426-
false, // RHS
427+
RulePart::Body,
427428
sess,
428429
node_id,
429430
features,

compiler/rustc_expand/src/mbe/quoted.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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`.
3960
pub(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.
163184
fn 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

Comments
 (0)