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,6 +1,8 @@
|
|||
pub use BinOpToken::*;
|
||||
pub use LitKind::*;
|
||||
pub use Nonterminal::*;
|
||||
pub use NtExprKind::*;
|
||||
pub use NtPatKind::*;
|
||||
pub use TokenKind::*;
|
||||
|
||||
use crate::ast;
|
||||
|
@ -871,6 +873,27 @@ impl PartialEq<TokenKind> for Token {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
|
||||
pub enum NtPatKind {
|
||||
// Matches or-patterns. Was written using `pat` in edition 2021 or later.
|
||||
PatWithOr,
|
||||
// Doesn't match or-patterns.
|
||||
// - `inferred`: was written using `pat` in edition 2015 or 2018.
|
||||
// - `!inferred`: was written using `pat_param`.
|
||||
PatParam { inferred: bool },
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
|
||||
pub enum NtExprKind {
|
||||
// Matches expressions using the post-edition 2024. Was written using
|
||||
// `expr` in edition 2024 or later.
|
||||
Expr,
|
||||
// Matches expressions using the pre-edition 2024 rules.
|
||||
// - `inferred`: was written using `expr` in edition 2021 or earlier.
|
||||
// - `!inferred`: was written using `expr_2021`.
|
||||
Expr2021 { inferred: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable)]
|
||||
/// For interpolation during macro expansion.
|
||||
pub enum Nonterminal {
|
||||
|
@ -892,19 +915,8 @@ pub enum NonterminalKind {
|
|||
Item,
|
||||
Block,
|
||||
Stmt,
|
||||
PatParam {
|
||||
/// Keep track of whether the user used `:pat_param` or `:pat` and we inferred it from the
|
||||
/// edition of the span. This is used for diagnostics.
|
||||
inferred: bool,
|
||||
},
|
||||
PatWithOr,
|
||||
Expr,
|
||||
/// Matches an expression using the rules from edition 2021 and earlier.
|
||||
Expr2021 {
|
||||
/// Keep track of whether the user used `:expr` or `:expr_2021` and we inferred it from the
|
||||
/// edition of the span. This is used for diagnostics AND feature gating.
|
||||
inferred: bool,
|
||||
},
|
||||
Pat(NtPatKind),
|
||||
Expr(NtExprKind),
|
||||
Ty,
|
||||
Ident,
|
||||
Lifetime,
|
||||
|
@ -926,20 +938,22 @@ impl NonterminalKind {
|
|||
sym::item => NonterminalKind::Item,
|
||||
sym::block => NonterminalKind::Block,
|
||||
sym::stmt => NonterminalKind::Stmt,
|
||||
sym::pat => match edition() {
|
||||
Edition::Edition2015 | Edition::Edition2018 => {
|
||||
NonterminalKind::PatParam { inferred: true }
|
||||
sym::pat => {
|
||||
if edition().at_least_rust_2021() {
|
||||
NonterminalKind::Pat(PatWithOr)
|
||||
} else {
|
||||
NonterminalKind::Pat(PatParam { inferred: true })
|
||||
}
|
||||
Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
|
||||
},
|
||||
sym::pat_param => NonterminalKind::PatParam { inferred: false },
|
||||
sym::expr => match edition() {
|
||||
Edition::Edition2015 | Edition::Edition2018 | Edition::Edition2021 => {
|
||||
NonterminalKind::Expr2021 { inferred: true }
|
||||
}
|
||||
sym::pat_param => NonterminalKind::Pat(PatParam { inferred: false }),
|
||||
sym::expr => {
|
||||
if edition().at_least_rust_2024() {
|
||||
NonterminalKind::Expr(Expr)
|
||||
} else {
|
||||
NonterminalKind::Expr(Expr2021 { inferred: true })
|
||||
}
|
||||
Edition::Edition2024 => NonterminalKind::Expr,
|
||||
},
|
||||
sym::expr_2021 => NonterminalKind::Expr2021 { inferred: false },
|
||||
}
|
||||
sym::expr_2021 => NonterminalKind::Expr(Expr2021 { inferred: false }),
|
||||
sym::ty => NonterminalKind::Ty,
|
||||
sym::ident => NonterminalKind::Ident,
|
||||
sym::lifetime => NonterminalKind::Lifetime,
|
||||
|
@ -951,15 +965,16 @@ impl NonterminalKind {
|
|||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
fn symbol(self) -> Symbol {
|
||||
match self {
|
||||
NonterminalKind::Item => sym::item,
|
||||
NonterminalKind::Block => sym::block,
|
||||
NonterminalKind::Stmt => sym::stmt,
|
||||
NonterminalKind::PatParam { inferred: false } => sym::pat_param,
|
||||
NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat,
|
||||
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: true } => sym::expr,
|
||||
NonterminalKind::Expr2021 { inferred: false } => sym::expr_2021,
|
||||
NonterminalKind::Pat(PatParam { inferred: true } | PatWithOr) => sym::pat,
|
||||
NonterminalKind::Pat(PatParam { inferred: false }) => sym::pat_param,
|
||||
NonterminalKind::Expr(Expr2021 { inferred: true } | Expr) => sym::expr,
|
||||
NonterminalKind::Expr(Expr2021 { inferred: false }) => sym::expr_2021,
|
||||
NonterminalKind::Ty => sym::ty,
|
||||
NonterminalKind::Ident => sym::ident,
|
||||
NonterminalKind::Lifetime => sym::lifetime,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue