about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eric@theincredibleholk.org>2024-04-30 16:32:26 -0700
committerEric Holk <ericholk@microsoft.com>2024-05-13 11:55:38 -0700
commitf364011955f8316f897cc0a2a930b8665d918177 (patch)
treebf14565de4601995b9592ae3f742874dd24bf01e
parenta55d06323aef19040aba222b7ede790291e08468 (diff)
downloadrust-f364011955f8316f897cc0a2a930b8665d918177.tar.gz
rust-f364011955f8316f897cc0a2a930b8665d918177.zip
Apply code review suggestions
- use feature_err to report unstable expr_2021
- Update downlevel expr_2021 diagnostics

Co-authored-by: León Orell Valerian Liehr <me@fmease.dev>
-rw-r--r--compiler/rustc_ast/src/token.rs2
-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/quoted.rs69
-rw-r--r--tests/ui/macros/expr_2021_old_edition.rs2
-rw-r--r--tests/ui/macros/expr_2021_old_edition.stderr3
-rw-r--r--tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs2
-rw-r--r--tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr7
8 files changed, 57 insertions, 38 deletions
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index bbab13221d3..e44725e7f15 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -909,7 +909,7 @@ impl NonterminalKind {
             },
             sym::pat_param => NonterminalKind::PatParam { inferred: false },
             sym::expr => NonterminalKind::Expr,
-            sym::expr_2021 if edition() >= Edition::Edition2021 => NonterminalKind::Expr2021,
+            sym::expr_2021 if edition().at_least_rust_2021() => NonterminalKind::Expr2021,
             sym::ty => NonterminalKind::Ty,
             sym::ident => NonterminalKind::Ident,
             sym::lifetime => NonterminalKind::Lifetime,
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index 73babf5d324..b7aae2af9ef 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -39,9 +39,6 @@ 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 bc91dfe7a88..b0563bfdea7 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -433,10 +433,3 @@ 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/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 5508c0d0503..e67955be3d6 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -16,6 +16,10 @@ use rustc_span::Span;
 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
                                         `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
                                         `literal`, `path`, `meta`, `tt`, `item` and `vis`";
+const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
+                                             `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \
+                                             `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
+                                             `item` and `vis`";
 
 /// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
 /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
@@ -63,40 +67,59 @@ pub(super) fn parse(
                             Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() {
                                 Some((fragment, _)) => {
                                     let span = token.span.with_lo(start_sp.lo());
-
+                                    let edition = || {
+                                        // FIXME(#85708) - once we properly decode a foreign
+                                        // crate's `SyntaxContext::root`, then we can replace
+                                        // this with just `span.edition()`. A
+                                        // `SyntaxContext::root()` from the current crate will
+                                        // have the edition of the current crate, and a
+                                        // `SyntaxContext::root()` from a foreign crate will
+                                        // have the edition of that crate (which we manually
+                                        // retrieve via the `edition` parameter).
+                                        if !span.from_expansion() {
+                                            edition
+                                        } else {
+                                            span.edition()
+                                        }
+                                    };
                                     let kind =
-                                        token::NonterminalKind::from_symbol(fragment.name, || {
-                                            // FIXME(#85708) - once we properly decode a foreign
-                                            // crate's `SyntaxContext::root`, then we can replace
-                                            // this with just `span.edition()`. A
-                                            // `SyntaxContext::root()` from the current crate will
-                                            // have the edition of the current crate, and a
-                                            // `SyntaxContext::root()` from a foreign crate will
-                                            // have the edition of that crate (which we manually
-                                            // retrieve via the `edition` parameter).
-                                            if !span.from_expansion() {
-                                                edition
-                                            } else {
-                                                span.edition()
-                                            }
-                                        })
-                                        .unwrap_or_else(
-                                            || {
+                                        token::NonterminalKind::from_symbol(fragment.name, edition)
+                                            .unwrap_or_else(|| {
+                                                let help = match fragment.name {
+                                                    sym::expr_2021 => {
+                                                        format!(
+                                                            "fragment specifier `expr_2021` \
+                                                             requires Rust 2021 or later\n\
+                                                             {VALID_FRAGMENT_NAMES_MSG}"
+                                                        )
+                                                    }
+                                                    _ if edition().at_least_rust_2021()
+                                                        && features
+                                                            .expr_fragment_specifier_2024 =>
+                                                    {
+                                                        VALID_FRAGMENT_NAMES_MSG_2021.into()
+                                                    }
+                                                    _ => VALID_FRAGMENT_NAMES_MSG.into(),
+                                                };
                                                 sess.dcx().emit_err(
                                                     errors::InvalidFragmentSpecifier {
                                                         span,
                                                         fragment,
-                                                        help: VALID_FRAGMENT_NAMES_MSG.into(),
+                                                        help,
                                                     },
                                                 );
                                                 token::NonterminalKind::Ident
-                                            },
-                                        );
+                                            });
                                     if kind == token::NonterminalKind::Expr2021
                                         && !features.expr_fragment_specifier_2024
                                     {
-                                        sess.dcx()
-                                            .emit_err(errors::Expr2021IsExperimental { span });
+                                        rustc_session::parse::feature_err(
+                                            sess,
+                                            sym::expr_fragment_specifier_2024,
+                                            span,
+                                            "fragment specifier `expr_2021` is unstable",
+                                        )
+                                        .emit();
                                     }
                                     result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
                                     continue;
diff --git a/tests/ui/macros/expr_2021_old_edition.rs b/tests/ui/macros/expr_2021_old_edition.rs
index ab7999ab373..a7711266106 100644
--- a/tests/ui/macros/expr_2021_old_edition.rs
+++ b/tests/ui/macros/expr_2021_old_edition.rs
@@ -1,6 +1,6 @@
 //@  compile-flags: --edition=2018
 
-// This test ensures that expr_2021 is not allowed on pre-2024 editions
+// This test ensures that expr_2021 is not allowed on pre-2021 editions
 
 macro_rules! m {
     ($e:expr_2021) => { //~ ERROR: invalid fragment specifier `expr_2021`
diff --git a/tests/ui/macros/expr_2021_old_edition.stderr b/tests/ui/macros/expr_2021_old_edition.stderr
index b5934fb3361..bffa8a1ca17 100644
--- a/tests/ui/macros/expr_2021_old_edition.stderr
+++ b/tests/ui/macros/expr_2021_old_edition.stderr
@@ -4,7 +4,8 @@ error: invalid fragment specifier `expr_2021`
 LL |     ($e:expr_2021) => {
    |      ^^^^^^^^^^^^
    |
-   = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
+   = help: fragment specifier `expr_2021` requires Rust 2021 or later
+           valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
 
 error: no rules expected the token `(`
   --> $DIR/expr_2021_old_edition.rs:12:8
diff --git a/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs
index fff1ea34d83..5a737b29821 100644
--- a/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs
+++ b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs
@@ -1,7 +1,7 @@
 //@  compile-flags: --edition=2024 -Z unstable-options
 
 macro_rules! m {
-    ($e:expr_2021) => { //~ ERROR: expr_2021 is experimental
+    ($e:expr_2021) => { //~ ERROR: fragment specifier `expr_2021` is unstable
         $e
     };
 }
diff --git a/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr
index 078ff57a971..273a93877ce 100644
--- a/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr
+++ b/tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr
@@ -1,8 +1,13 @@
-error: expr_2021 is experimental
+error[E0658]: fragment specifier `expr_2021` is unstable
   --> $DIR/feature-gate-expr_fragment_specifier_2024.rs:4:6
    |
 LL |     ($e:expr_2021) => {
    |      ^^^^^^^^^^^^
+   |
+   = note: see issue #123742 <https://github.com/rust-lang/rust/issues/123742> for more information
+   = help: add `#![feature(expr_fragment_specifier_2024)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0658`.