Skip to content

Commit 68d7597

Browse files
committed
Introduce InvisibleSource::MetaVar.
Token sequences delimited with these invisible delimiters will eventually replace `Token::Interpolated` for declarative macro expansions. There are no uses yet, but this commit does modify `nonterminal_may_begin_with` so that every `Interpolated` test is now mirrored with a `InvisibleSource::MetaVar` test. This means that `Nt*` cases can now be removed from that function one at a time without any other changes required.
1 parent fcce5dd commit 68d7597

File tree

2 files changed

+71
-7
lines changed

2 files changed

+71
-7
lines changed

compiler/rustc_ast/src/token.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pub enum Delimiter {
6060

6161
#[derive(Copy, Clone, Debug, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
6262
pub enum InvisibleSource {
63+
// From the expansion of a metavariable in a declarative macro.
64+
MetaVar(NonterminalKind),
65+
6366
// Converted from `proc_macro::Delimiter` in
6467
// `proc_macro::Delimiter::to_internal`, i.e. returned by a proc macro.
6568
ProcMacro,
@@ -78,6 +81,7 @@ impl Delimiter {
7881
match self {
7982
Delimiter::Invisible(src) => match src {
8083
InvisibleSource::FlattenToken | InvisibleSource::ProcMacro => true,
84+
InvisibleSource::MetaVar(_) => false,
8185
},
8286
Delimiter::Parenthesis | Delimiter::Bracket | Delimiter::Brace => false,
8387
}
@@ -758,6 +762,15 @@ impl Token {
758762
}
759763
}
760764

765+
/// Is this an invisible open delimiter at the start of a token sequence
766+
/// from an expanded metavar?
767+
pub fn is_metavar_seq(&self) -> Option<NonterminalKind> {
768+
match self.kind {
769+
OpenDelim(Delimiter::Invisible(InvisibleSource::MetaVar(kind))) => Some(kind),
770+
_ => None,
771+
}
772+
}
773+
761774
pub fn glue(&self, joint: &Token) -> Option<Token> {
762775
let kind = match self.kind {
763776
Eq => match joint.kind {
@@ -843,7 +856,7 @@ pub enum Nonterminal {
843856
NtVis(P<ast::Visibility>),
844857
}
845858

846-
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
859+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
847860
pub enum NonterminalKind {
848861
Item,
849862
Block,

compiler/rustc_parse/src/parser/nonterminal.rs

Lines changed: 57 additions & 6 deletions
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, InvisibleSource, Nonterminal::*, NonterminalKind, Token};
33
use rustc_ast::HasTokens;
44
use rustc_ast_pretty::pprust;
55
use rustc_data_structures::sync::Lrc;
@@ -20,7 +20,30 @@ impl<'a> Parser<'a> {
2020
#[inline]
2121
pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool {
2222
/// Checks whether the non-terminal may contain a single (non-keyword) identifier.
23-
fn may_be_ident(nt: &token::Nonterminal) -> bool {
23+
fn may_be_ident(kind: NonterminalKind) -> bool {
24+
use NonterminalKind::*;
25+
match kind {
26+
Stmt
27+
| PatParam { .. }
28+
| PatWithOr
29+
| Expr
30+
| Ty
31+
| Ident
32+
| Literal // `true`, `false`
33+
| Meta
34+
| Path => true,
35+
36+
Item
37+
| Block
38+
| Vis
39+
| Lifetime => false,
40+
41+
TT => unreachable!(),
42+
}
43+
}
44+
45+
/// Old variant of `may_be_ident`, being phased out.
46+
fn nt_may_be_ident(nt: &token::Nonterminal) -> bool {
2447
match nt {
2548
NtStmt(_)
2649
| NtPat(_)
@@ -50,8 +73,11 @@ impl<'a> Parser<'a> {
5073
NonterminalKind::Ident => get_macro_ident(token).is_some(),
5174
NonterminalKind::Literal => token.can_begin_literal_maybe_minus(),
5275
NonterminalKind::Vis => match token.kind {
53-
// The follow-set of :vis + "priv" keyword + interpolated
54-
token::Comma | token::Ident(..) | token::Interpolated(..) => true,
76+
// The follow-set of :vis + "priv" keyword + interpolated/metavar-expansion
77+
token::Comma
78+
| token::Ident(..)
79+
| token::Interpolated(..)
80+
| token::OpenDelim(Delimiter::Invisible(InvisibleSource::MetaVar(_))) => true,
5581
_ => token.can_begin_type(),
5682
},
5783
NonterminalKind::Block => match &token.kind {
@@ -61,11 +87,30 @@ impl<'a> Parser<'a> {
6187
NtItem(_) | NtPat(_) | NtTy(_) | NtIdent(..) | NtMeta(_) | NtPath(_)
6288
| NtVis(_) => false,
6389
},
90+
token::OpenDelim(Delimiter::Invisible(InvisibleSource::MetaVar(k))) => match k {
91+
NonterminalKind::Block
92+
| NonterminalKind::Lifetime
93+
| NonterminalKind::Stmt
94+
| NonterminalKind::Expr
95+
| NonterminalKind::Literal => true,
96+
NonterminalKind::Item
97+
| NonterminalKind::PatParam { .. }
98+
| NonterminalKind::PatWithOr
99+
| NonterminalKind::Ty
100+
| NonterminalKind::Ident
101+
| NonterminalKind::Meta
102+
| NonterminalKind::Path
103+
| NonterminalKind::Vis => false,
104+
NonterminalKind::TT => unreachable!(),
105+
},
64106
_ => false,
65107
},
66108
NonterminalKind::Path | NonterminalKind::Meta => match &token.kind {
67109
token::ModSep | token::Ident(..) => true,
68-
token::Interpolated(nt) => may_be_ident(nt),
110+
token::Interpolated(nt) => nt_may_be_ident(nt),
111+
token::OpenDelim(Delimiter::Invisible(InvisibleSource::MetaVar(kind))) => {
112+
may_be_ident(*kind)
113+
}
69114
_ => false,
70115
},
71116
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => {
@@ -84,7 +129,10 @@ impl<'a> Parser<'a> {
84129
token::BinOp(token::Shl) => true, // path (double UFCS)
85130
// leading vert `|` or-pattern
86131
token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr),
87-
token::Interpolated(nt) => may_be_ident(nt),
132+
token::Interpolated(nt) => nt_may_be_ident(nt),
133+
token::OpenDelim(Delimiter::Invisible(InvisibleSource::MetaVar(kind))) => {
134+
may_be_ident(*kind)
135+
}
88136
_ => false,
89137
}
90138
}
@@ -93,6 +141,9 @@ impl<'a> Parser<'a> {
93141
token::Interpolated(nt) => {
94142
matches!(**nt, NtLifetime(_))
95143
}
144+
token::OpenDelim(Delimiter::Invisible(InvisibleSource::MetaVar(
145+
NonterminalKind::Lifetime,
146+
))) => true,
96147
_ => false,
97148
},
98149
NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => {

0 commit comments

Comments
 (0)