about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <ericholk@microsoft.com>2024-04-12 10:19:23 -0700
committerEric Holk <ericholk@microsoft.com>2024-05-13 11:27:26 -0700
commitef6478ba5fde1a1ed6db27fc7f558bc26e38d781 (patch)
tree5aa3810b035d94d717ce85e1c0010f2e2d566b06
parent030a12ce2b1ee42f2d8837b1b500fd9cf12ea191 (diff)
downloadrust-ef6478ba5fde1a1ed6db27fc7f558bc26e38d781.tar.gz
rust-ef6478ba5fde1a1ed6db27fc7f558bc26e38d781.zip
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>
-rw-r--r--compiler/rustc_ast/src/token.rs4
-rw-r--r--compiler/rustc_expand/messages.ftl3
-rw-r--r--compiler/rustc_expand/src/errors.rs7
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs6
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs11
-rw-r--r--tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr8
10 files changed, 48 insertions, 3 deletions
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 72f89737f99..0b741c2cc40 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -878,6 +878,8 @@ pub enum NonterminalKind {
     },
     PatWithOr,
     Expr,
+    /// Matches an expression using the rules from edition 2021 and earlier.
+    Expr2021,
     Ty,
     Ident,
     Lifetime,
@@ -907,6 +909,7 @@ impl NonterminalKind {
             },
             sym::pat_param => NonterminalKind::PatParam { inferred: false },
             sym::expr => NonterminalKind::Expr,
+            sym::expr_2021 if edition() >= Edition::Edition2024 => NonterminalKind::Expr2021,
             sym::ty => NonterminalKind::Ty,
             sym::ident => NonterminalKind::Ident,
             sym::lifetime => NonterminalKind::Lifetime,
@@ -926,6 +929,7 @@ impl NonterminalKind {
             NonterminalKind::PatParam { inferred: false } => sym::pat_param,
             NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat,
             NonterminalKind::Expr => sym::expr,
+            NonterminalKind::Expr2021 => sym::expr_2021,
             NonterminalKind::Ty => sym::ty,
             NonterminalKind::Ident => sym::ident,
             NonterminalKind::Lifetime => sym::lifetime,
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index b7aae2af9ef..73babf5d324 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -39,6 +39,9 @@ expand_explain_doc_comment_inner =
 expand_explain_doc_comment_outer =
     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 =
     attempted to repeat an expression containing no syntax variables matched as repeating at this depth
 
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index b0563bfdea7..bc91dfe7a88 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -433,3 +433,10 @@ pub struct ExpectedParenOrBrace<'a> {
     pub span: Span,
     pub token: Cow<'a, str>,
 }
+
+#[derive(Diagnostic)]
+#[diag(expand_expr_2021_is_experimental)]
+pub struct Expr2021IsExperimental {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 470bde232d7..71daaacd056 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -1290,7 +1290,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
                 // maintain
                 IsInFollow::Yes
             }
-            NonterminalKind::Stmt | NonterminalKind::Expr => {
+            NonterminalKind::Stmt | NonterminalKind::Expr | NonterminalKind::Expr2021 => {
                 const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
                 match tok {
                     TokenTree::Token(token) => match token.kind {
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 06c1612ddba..5508c0d0503 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -92,6 +92,12 @@ pub(super) fn parse(
                                                 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)));
                                     continue;
                                 }
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 60b386acf91..c6fc9de119d 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -458,6 +458,8 @@ declare_features! (
     (unstable, exhaustive_patterns, "1.13.0", Some(51085)),
     /// Allows explicit tail calls via `become` expression.
     (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
     /// for functions with varargs.
     (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 73b17353ac9..dc51d85792c 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -37,7 +37,7 @@ impl<'a> Parser<'a> {
         }
 
         match kind {
-            NonterminalKind::Expr => {
+            NonterminalKind::Expr | NonterminalKind::Expr2021 => {
                 token.can_begin_expr()
                 // This exception is here for backwards compatibility.
                 && !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 => {
                 // The `:literal` matcher does not support attributes
                 NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?)
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d41059e8c24..68b1b32baf2 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -782,6 +782,8 @@ symbols! {
         explicit_tail_calls,
         export_name,
         expr,
+        expr_2021,
+        expr_fragment_specifier_2024,
         extended_key_value_attributes,
         extended_varargs_abi_support,
         extern_absolute_paths,
diff --git a/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs
new file mode 100644
index 00000000000..fff1ea34d83
--- /dev/null
+++ b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs
@@ -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!(());
+}
diff --git a/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr
new file mode 100644
index 00000000000..078ff57a971
--- /dev/null
+++ b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr
@@ -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
+