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
|
@ -10,7 +10,9 @@ use crate::mbe::transcribe::transcribe;
|
|||
|
||||
use ast::token::IdentIsRaw;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, NonterminalKind, NtPatKind::*, Token, TokenKind, TokenKind::*,
|
||||
};
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
||||
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
||||
use rustc_ast_pretty::pprust;
|
||||
|
@ -1145,7 +1147,7 @@ fn check_matcher_core<'tt>(
|
|||
// Macros defined in the current crate have a real node id,
|
||||
// whereas macros from an external crate have a dummy id.
|
||||
if def.id != DUMMY_NODE_ID
|
||||
&& matches!(kind, NonterminalKind::PatParam { inferred: true })
|
||||
&& matches!(kind, NonterminalKind::Pat(PatParam { inferred: true }))
|
||||
&& matches!(
|
||||
next_token,
|
||||
TokenTree::Token(token) if token.kind == BinOp(token::BinOpToken::Or)
|
||||
|
@ -1155,7 +1157,7 @@ fn check_matcher_core<'tt>(
|
|||
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
|
||||
span,
|
||||
name,
|
||||
Some(NonterminalKind::PatParam { inferred: false }),
|
||||
Some(NonterminalKind::Pat(PatParam { inferred: false })),
|
||||
));
|
||||
sess.psess.buffer_lint(
|
||||
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
|
||||
|
@ -1188,14 +1190,14 @@ fn check_matcher_core<'tt>(
|
|||
);
|
||||
err.span_label(sp, format!("not allowed after `{kind}` fragments"));
|
||||
|
||||
if kind == NonterminalKind::PatWithOr
|
||||
if kind == NonterminalKind::Pat(PatWithOr)
|
||||
&& sess.psess.edition.at_least_rust_2021()
|
||||
&& next_token.is_token(&BinOp(token::BinOpToken::Or))
|
||||
{
|
||||
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
|
||||
span,
|
||||
name,
|
||||
Some(NonterminalKind::PatParam { inferred: false }),
|
||||
Some(NonterminalKind::Pat(PatParam { inferred: false })),
|
||||
));
|
||||
err.span_suggestion(
|
||||
span,
|
||||
|
@ -1295,9 +1297,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
// maintain
|
||||
IsInFollow::Yes
|
||||
}
|
||||
NonterminalKind::Stmt
|
||||
| NonterminalKind::Expr
|
||||
| NonterminalKind::Expr2021 { inferred: _ } => {
|
||||
NonterminalKind::Stmt | NonterminalKind::Expr(_) => {
|
||||
const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
|
||||
match tok {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
|
@ -1307,7 +1307,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
}
|
||||
NonterminalKind::PatParam { .. } => {
|
||||
NonterminalKind::Pat(PatParam { .. }) => {
|
||||
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
|
||||
match tok {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
|
@ -1320,7 +1320,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
|||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
}
|
||||
NonterminalKind::PatWithOr => {
|
||||
NonterminalKind::Pat(PatWithOr) => {
|
||||
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`in`"];
|
||||
match tok {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::errors;
|
|||
use crate::mbe::macro_parser::count_metavar_decls;
|
||||
use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};
|
||||
|
||||
use rustc_ast::token::{self, Delimiter, IdentIsRaw, NonterminalKind, Token};
|
||||
use rustc_ast::token::{self, Delimiter, IdentIsRaw, NonterminalKind, NtExprKind::*, Token};
|
||||
use rustc_ast::{tokenstream, NodeId};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_feature::Features;
|
||||
|
@ -109,7 +109,7 @@ pub(super) fn parse(
|
|||
});
|
||||
NonterminalKind::Ident
|
||||
});
|
||||
if kind == (NonterminalKind::Expr2021 { inferred: false })
|
||||
if kind == NonterminalKind::Expr(Expr2021 { inferred: false })
|
||||
&& !features.expr_fragment_specifier_2024
|
||||
{
|
||||
rustc_session::parse::feature_err(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue