Add expr_2021 nonterminal and feature flag

This commit adds a new nonterminal `expr_2021` in macro patterns, and
`expr_fragment_specifier_2024` feature flag. For now, `expr` and
`expr_2021` are treated the same, but in future PRs we will update
`expr` to match to new grammar.

Co-authored-by: Vincezo Palazzo <vincenzopalazzodev@gmail.com>
This commit is contained in:
Eric Holk 2024-04-12 10:19:23 -07:00
parent 030a12ce2b
commit ef6478ba5f
No known key found for this signature in database
GPG Key ID: 8EA6B43ED4CE0911
10 changed files with 48 additions and 3 deletions

View File

@ -878,6 +878,8 @@ pub enum NonterminalKind {
}, },
PatWithOr, PatWithOr,
Expr, Expr,
/// Matches an expression using the rules from edition 2021 and earlier.
Expr2021,
Ty, Ty,
Ident, Ident,
Lifetime, Lifetime,
@ -907,6 +909,7 @@ impl NonterminalKind {
}, },
sym::pat_param => NonterminalKind::PatParam { inferred: false }, sym::pat_param => NonterminalKind::PatParam { inferred: false },
sym::expr => NonterminalKind::Expr, sym::expr => NonterminalKind::Expr,
sym::expr_2021 if edition() >= Edition::Edition2024 => NonterminalKind::Expr2021,
sym::ty => NonterminalKind::Ty, sym::ty => NonterminalKind::Ty,
sym::ident => NonterminalKind::Ident, sym::ident => NonterminalKind::Ident,
sym::lifetime => NonterminalKind::Lifetime, sym::lifetime => NonterminalKind::Lifetime,
@ -926,6 +929,7 @@ impl NonterminalKind {
NonterminalKind::PatParam { inferred: false } => sym::pat_param, NonterminalKind::PatParam { inferred: false } => sym::pat_param,
NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat, NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat,
NonterminalKind::Expr => sym::expr, NonterminalKind::Expr => sym::expr,
NonterminalKind::Expr2021 => sym::expr_2021,
NonterminalKind::Ty => sym::ty, NonterminalKind::Ty => sym::ty,
NonterminalKind::Ident => sym::ident, NonterminalKind::Ident => sym::ident,
NonterminalKind::Lifetime => sym::lifetime, NonterminalKind::Lifetime => sym::lifetime,

View File

@ -39,6 +39,9 @@ expand_explain_doc_comment_inner =
expand_explain_doc_comment_outer = expand_explain_doc_comment_outer =
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
expand_expr_2021_is_experimental =
expr_2021 is experimental
expand_expr_repeat_no_syntax_vars = expand_expr_repeat_no_syntax_vars =
attempted to repeat an expression containing no syntax variables matched as repeating at this depth attempted to repeat an expression containing no syntax variables matched as repeating at this depth

View File

@ -433,3 +433,10 @@ pub struct ExpectedParenOrBrace<'a> {
pub span: Span, pub span: Span,
pub token: Cow<'a, str>, pub token: Cow<'a, str>,
} }
#[derive(Diagnostic)]
#[diag(expand_expr_2021_is_experimental)]
pub struct Expr2021IsExperimental {
#[primary_span]
pub span: Span,
}

View File

@ -1290,7 +1290,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
// maintain // maintain
IsInFollow::Yes IsInFollow::Yes
} }
NonterminalKind::Stmt | NonterminalKind::Expr => { NonterminalKind::Stmt | NonterminalKind::Expr | NonterminalKind::Expr2021 => {
const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"]; const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
match tok { match tok {
TokenTree::Token(token) => match token.kind { TokenTree::Token(token) => match token.kind {

View File

@ -92,6 +92,12 @@ pub(super) fn parse(
token::NonterminalKind::Ident token::NonterminalKind::Ident
}, },
); );
if kind == token::NonterminalKind::Expr2021
&& !features.expr_fragment_specifier_2024
{
sess.dcx()
.emit_err(errors::Expr2021IsExperimental { span });
}
result.push(TokenTree::MetaVarDecl(span, ident, Some(kind))); result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
continue; continue;
} }

View File

@ -458,6 +458,8 @@ declare_features! (
(unstable, exhaustive_patterns, "1.13.0", Some(51085)), (unstable, exhaustive_patterns, "1.13.0", Some(51085)),
/// Allows explicit tail calls via `become` expression. /// Allows explicit tail calls via `become` expression.
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)), (incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
/// Uses 2024 rules for matching `expr` fragments in macros. Also enables `expr_2021` fragment.
(incomplete, expr_fragment_specifier_2024, "CURRENT_RUSTC_VERSION", Some(123742)),
/// Allows using `efiapi`, `sysv64` and `win64` as calling convention /// Allows using `efiapi`, `sysv64` and `win64` as calling convention
/// for functions with varargs. /// for functions with varargs.
(unstable, extended_varargs_abi_support, "1.65.0", Some(100189)), (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),

View File

@ -37,7 +37,7 @@ impl<'a> Parser<'a> {
} }
match kind { match kind {
NonterminalKind::Expr => { NonterminalKind::Expr | NonterminalKind::Expr2021 => {
token.can_begin_expr() token.can_begin_expr()
// This exception is here for backwards compatibility. // This exception is here for backwards compatibility.
&& !token.is_keyword(kw::Let) && !token.is_keyword(kw::Let)
@ -145,7 +145,9 @@ impl<'a> Parser<'a> {
})?) })?)
} }
NonterminalKind::Expr => NtExpr(self.parse_expr_force_collect()?), NonterminalKind::Expr | NonterminalKind::Expr2021 => {
NtExpr(self.parse_expr_force_collect()?)
}
NonterminalKind::Literal => { NonterminalKind::Literal => {
// The `:literal` matcher does not support attributes // The `:literal` matcher does not support attributes
NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?) NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?)

View File

@ -782,6 +782,8 @@ symbols! {
explicit_tail_calls, explicit_tail_calls,
export_name, export_name,
expr, expr,
expr_2021,
expr_fragment_specifier_2024,
extended_key_value_attributes, extended_key_value_attributes,
extended_varargs_abi_support, extended_varargs_abi_support,
extern_absolute_paths, extern_absolute_paths,

View File

@ -0,0 +1,11 @@
//@ compile-flags: --edition=2024 -Z unstable-options
macro_rules! m {
($e:expr_2021) => { //~ ERROR: expr_2021 is experimental
$e
};
}
fn main() {
m!(());
}

View File

@ -0,0 +1,8 @@
error: expr_2021 is experimental
--> $DIR/feature-gate-expr_fragment_specifier_2024.rs:4:6
|
LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^
error: aborting due to 1 previous error