Rework pattern and expression nonterminal kinds.
Merge `PatParam`/`PatWithOr`, and `Expr`/`Expr2021`, for a few reasons. - It's conceptually nice, because the two pattern kinds and the two expression kinds are very similar. - With expressions in particular, there are several places where both expression kinds get the same treatment. - It removes one unreachable match arm. - Most importantly, for #124141 I will need to introduce a new type `MetaVarKind` that is very similar to `NonterminalKind`, but records a couple of extra fields for expression metavars. It's nicer to have a single `MetaVarKind::Expr` expression variant to hold those extra fields instead of duplicating them across two variants `MetaVarKind::{Expr,Expr2021}`. And then it makes sense for patterns to be treated the same way, and for `NonterminalKind` to also be treated the same way. I also clarified the comments, because I have long found them a little hard to understand.
This commit is contained in:
parent
70fa67c0b2
commit
e2aa38e6ab
5 changed files with 71 additions and 60 deletions
|
@ -1,5 +1,7 @@
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Nonterminal::*, NonterminalKind, Token};
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, Nonterminal::*, NonterminalKind, NtExprKind::*, NtPatKind::*, Token,
|
||||
};
|
||||
use rustc_ast::HasTokens;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -36,14 +38,14 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
match kind {
|
||||
NonterminalKind::Expr2021 { inferred: _ } => {
|
||||
NonterminalKind::Expr(Expr2021 { .. }) => {
|
||||
token.can_begin_expr()
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Let)
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Const)
|
||||
}
|
||||
NonterminalKind::Expr => {
|
||||
NonterminalKind::Expr(Expr) => {
|
||||
token.can_begin_expr()
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Let)
|
||||
|
@ -74,7 +76,7 @@ impl<'a> Parser<'a> {
|
|||
token::Interpolated(nt) => may_be_ident(nt),
|
||||
_ => false,
|
||||
},
|
||||
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => match &token.kind {
|
||||
NonterminalKind::Pat(pat_kind) => match &token.kind {
|
||||
// box, ref, mut, and other identifiers (can stricten)
|
||||
token::Ident(..) | token::NtIdent(..) |
|
||||
token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern
|
||||
|
@ -89,7 +91,7 @@ impl<'a> Parser<'a> {
|
|||
token::Lt | // path (UFCS constant)
|
||||
token::BinOp(token::Shl) => true, // path (double UFCS)
|
||||
// leading vert `|` or-pattern
|
||||
token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr),
|
||||
token::BinOp(token::Or) => matches!(pat_kind, PatWithOr),
|
||||
token::Interpolated(nt) => may_be_ident(nt),
|
||||
_ => false,
|
||||
},
|
||||
|
@ -135,31 +137,25 @@ impl<'a> Parser<'a> {
|
|||
.create_err(UnexpectedNonterminal::Statement(self.token.span)));
|
||||
}
|
||||
},
|
||||
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => {
|
||||
NtPat(self.collect_tokens_no_attrs(|this| match kind {
|
||||
NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None, None),
|
||||
NonterminalKind::PatWithOr => this.parse_pat_allow_top_alt(
|
||||
NonterminalKind::Pat(pat_kind) => {
|
||||
NtPat(self.collect_tokens_no_attrs(|this| match pat_kind {
|
||||
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
|
||||
PatWithOr => this.parse_pat_allow_top_alt(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
})?)
|
||||
}
|
||||
|
||||
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: _ } => {
|
||||
NtExpr(self.parse_expr_force_collect()?)
|
||||
}
|
||||
NonterminalKind::Expr(_) => NtExpr(self.parse_expr_force_collect()?),
|
||||
NonterminalKind::Literal => {
|
||||
// The `:literal` matcher does not support attributes
|
||||
NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?)
|
||||
}
|
||||
|
||||
NonterminalKind::Ty => {
|
||||
NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?)
|
||||
}
|
||||
|
||||
// this could be handled like a token, since it is one
|
||||
NonterminalKind::Ident => {
|
||||
return if let Some((ident, is_raw)) = get_macro_ident(&self.token) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue