Skip to content

Commit 79f3fd0

Browse files
committed
Streamline NamedMatch.
This commit combines `MatchedTokenTree` and `MatchedNonterminal`, which are often considered together, into a single `MatchedSingle`. It shares a representation with the newly-parameterized `ParseNtResult`. This will also make things much simpler if/when variants from `Interpolated` start being moved to `ParseNtResult`.
1 parent 7fabdea commit 79f3fd0

File tree

5 files changed

+42
-31
lines changed

5 files changed

+42
-31
lines changed

compiler/rustc_expand/src/mbe/macro_parser.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -392,12 +392,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
392392
#[derive(Debug, Clone)]
393393
pub(crate) enum NamedMatch {
394394
MatchedSeq(Vec<NamedMatch>),
395-
396-
// A metavar match of type `tt`.
397-
MatchedTokenTree(rustc_ast::tokenstream::TokenTree),
398-
399-
// A metavar match of any type other than `tt`.
400-
MatchedNonterminal(Lrc<(Nonterminal, rustc_span::Span)>),
395+
MatchedSingle(ParseNtResult<Lrc<(Nonterminal, Span)>>),
401396
}
402397

403398
/// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison)
@@ -691,11 +686,11 @@ impl TtParser {
691686
}
692687
Ok(nt) => nt,
693688
};
694-
let m = match nt {
695-
ParseNtResult::Nt(nt) => MatchedNonterminal(Lrc::new((nt, span))),
696-
ParseNtResult::Tt(tt) => MatchedTokenTree(tt),
697-
};
698-
mp.push_match(next_metavar, seq_depth, m);
689+
mp.push_match(
690+
next_metavar,
691+
seq_depth,
692+
MatchedSingle(nt.map_nt(|nt| (Lrc::new((nt, span))))),
693+
);
699694
mp.idx += 1;
700695
} else {
701696
unreachable!()

compiler/rustc_expand/src/mbe/macro_rules.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::mbe;
55
use crate::mbe::diagnostics::{annotate_doc_comment, parse_failure_msg};
66
use crate::mbe::macro_check;
77
use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success, TtParser};
8-
use crate::mbe::macro_parser::{MatchedSeq, MatchedTokenTree, MatcherLoc};
8+
use crate::mbe::macro_parser::{MatcherLoc, NamedMatch::*};
99
use crate::mbe::transcribe::transcribe;
1010

1111
use ast::token::IdentIsRaw;
@@ -22,7 +22,7 @@ use rustc_lint_defs::builtin::{
2222
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
2323
};
2424
use rustc_lint_defs::BuiltinLintDiag;
25-
use rustc_parse::parser::{Parser, Recovery};
25+
use rustc_parse::parser::{ParseNtResult, Parser, Recovery};
2626
use rustc_session::parse::ParseSess;
2727
use rustc_session::Session;
2828
use rustc_span::edition::Edition;
@@ -479,7 +479,7 @@ pub fn compile_declarative_macro(
479479
MatchedSeq(s) => s
480480
.iter()
481481
.map(|m| {
482-
if let MatchedTokenTree(tt) = m {
482+
if let MatchedSingle(ParseNtResult::Tt(tt)) = m {
483483
let tt = mbe::quoted::parse(
484484
&TokenStream::new(vec![tt.clone()]),
485485
true,
@@ -505,7 +505,7 @@ pub fn compile_declarative_macro(
505505
MatchedSeq(s) => s
506506
.iter()
507507
.map(|m| {
508-
if let MatchedTokenTree(tt) = m {
508+
if let MatchedSingle(ParseNtResult::Tt(tt)) = m {
509509
return mbe::quoted::parse(
510510
&TokenStream::new(vec![tt.clone()]),
511511
false,

compiler/rustc_expand/src/mbe/transcribe.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use crate::errors::{
33
CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce,
44
NoSyntaxVarsExprRepeat, VarStillRepeating,
55
};
6-
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch};
6+
use crate::mbe::macro_parser::{NamedMatch, NamedMatch::*};
77
use crate::mbe::{self, KleeneOp, MetaVarExpr};
88
use rustc_ast::mut_visit::{self, MutVisitor};
99
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
1010
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
1111
use rustc_data_structures::fx::FxHashMap;
12-
use rustc_errors::Diag;
13-
use rustc_errors::{pluralize, PResult};
12+
use rustc_errors::{pluralize, Diag, PResult};
13+
use rustc_parse::parser::ParseNtResult;
1414
use rustc_span::hygiene::{LocalExpnId, Transparency};
1515
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
1616
use rustc_span::{with_metavar_spans, Span, SyntaxContext};
@@ -251,12 +251,12 @@ pub(super) fn transcribe<'a>(
251251
let ident = MacroRulesNormalizedIdent::new(original_ident);
252252
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
253253
let tt = match cur_matched {
254-
MatchedTokenTree(tt) => {
254+
MatchedSingle(ParseNtResult::Tt(tt)) => {
255255
// `tt`s are emitted into the output stream directly as "raw tokens",
256256
// without wrapping them into groups.
257257
maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker)
258258
}
259-
MatchedNonterminal(nt) => {
259+
MatchedSingle(ParseNtResult::Nt(nt)) => {
260260
// Other variables are emitted into the output stream as groups with
261261
// `Delimiter::Invisible` to maintain parsing priorities.
262262
// `Interpolated` is currently used for such groups in rustc parser.
@@ -423,7 +423,7 @@ fn lookup_cur_matched<'a>(
423423
interpolations.get(&ident).map(|mut matched| {
424424
for &(idx, _) in repeats {
425425
match matched {
426-
MatchedTokenTree(_) | MatchedNonterminal(_) => break,
426+
MatchedSingle(_) => break,
427427
MatchedSeq(ads) => matched = ads.get(idx).unwrap(),
428428
}
429429
}
@@ -513,7 +513,7 @@ fn lockstep_iter_size(
513513
let name = MacroRulesNormalizedIdent::new(*name);
514514
match lookup_cur_matched(name, interpolations, repeats) {
515515
Some(matched) => match matched {
516-
MatchedTokenTree(_) | MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
516+
MatchedSingle(_) => LockstepIterSize::Unconstrained,
517517
MatchedSeq(ads) => LockstepIterSize::Constraint(ads.len(), name),
518518
},
519519
_ => LockstepIterSize::Unconstrained,
@@ -556,7 +556,7 @@ fn count_repetitions<'a>(
556556
// (or at the top-level of `matched` if no depth is given).
557557
fn count<'a>(depth_curr: usize, depth_max: usize, matched: &NamedMatch) -> PResult<'a, usize> {
558558
match matched {
559-
MatchedTokenTree(_) | MatchedNonterminal(_) => Ok(1),
559+
MatchedSingle(_) => Ok(1),
560560
MatchedSeq(named_matches) => {
561561
if depth_curr == depth_max {
562562
Ok(named_matches.len())
@@ -570,7 +570,7 @@ fn count_repetitions<'a>(
570570
/// Maximum depth
571571
fn depth(counter: usize, matched: &NamedMatch) -> usize {
572572
match matched {
573-
MatchedTokenTree(_) | MatchedNonterminal(_) => counter,
573+
MatchedSingle(_) => counter,
574574
MatchedSeq(named_matches) => {
575575
let rslt = counter + 1;
576576
if let Some(elem) = named_matches.first() { depth(rslt, elem) } else { rslt }
@@ -598,7 +598,7 @@ fn count_repetitions<'a>(
598598
}
599599
}
600600

601-
if let MatchedTokenTree(_) | MatchedNonterminal(_) = matched {
601+
if let MatchedSingle(_) = matched {
602602
return Err(cx.dcx().create_err(CountRepetitionMisplaced { span: sp.entire() }));
603603
}
604604

compiler/rustc_parse/src/parser/mod.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
2020
pub use path::PathStyle;
2121

2222
use rustc_ast::ptr::P;
23-
use rustc_ast::token::{self, Delimiter, Nonterminal, Token, TokenKind};
23+
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
2424
use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing};
2525
use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor};
2626
use rustc_ast::util::case::Case;
@@ -1570,8 +1570,21 @@ pub enum FlatToken {
15701570
Empty,
15711571
}
15721572

1573-
#[derive(Debug)]
1574-
pub enum ParseNtResult {
1575-
Nt(Nonterminal),
1573+
// Metavar captures of various kinds.
1574+
#[derive(Clone, Debug)]
1575+
pub enum ParseNtResult<NtType> {
15761576
Tt(TokenTree),
1577+
Nt(NtType),
1578+
}
1579+
1580+
impl<T> ParseNtResult<T> {
1581+
pub fn map_nt<F, U>(self, mut f: F) -> ParseNtResult<U>
1582+
where
1583+
F: FnMut(T) -> U,
1584+
{
1585+
match self {
1586+
ParseNtResult::Tt(tt) => ParseNtResult::Tt(tt),
1587+
ParseNtResult::Nt(nt) => ParseNtResult::Nt(f(nt)),
1588+
}
1589+
}
15771590
}

compiler/rustc_parse/src/parser/nonterminal.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_ast::ptr::P;
2-
use rustc_ast::token::{self, Delimiter, Nonterminal::*, NonterminalKind, Token};
2+
use rustc_ast::token::{self, Delimiter, Nonterminal, Nonterminal::*, NonterminalKind, Token};
33
use rustc_ast::HasTokens;
44
use rustc_ast_pretty::pprust;
55
use rustc_errors::PResult;
@@ -100,7 +100,10 @@ impl<'a> Parser<'a> {
100100
/// Parse a non-terminal (e.g. MBE `:pat` or `:ident`). Inlined because there is only one call
101101
/// site.
102102
#[inline]
103-
pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, ParseNtResult> {
103+
pub fn parse_nonterminal(
104+
&mut self,
105+
kind: NonterminalKind,
106+
) -> PResult<'a, ParseNtResult<Nonterminal>> {
104107
// A `macro_rules!` invocation may pass a captured item/expr to a proc-macro,
105108
// which requires having captured tokens available. Since we cannot determine
106109
// in advance whether or not a proc-macro will be (transitively) invoked,

0 commit comments

Comments
 (0)