Stabilize expr_2021 fragment in all editions

Co-authored-by: Michael Goulet <michael@errs.io>
Co-authored-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
This commit is contained in:
Eric Holk 2024-09-04 17:15:13 -07:00 committed by Vincenzo Palazzo
parent f79ef02e4b
commit c7cd55f7c5
21 changed files with 44 additions and 95 deletions

View File

@ -119,7 +119,7 @@
use rustc_span::{ErrorGuaranteed, Span}; use rustc_span::{ErrorGuaranteed, Span};
use smallvec::SmallVec; use smallvec::SmallVec;
use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021; use super::quoted::VALID_FRAGMENT_NAMES_MSG;
use crate::errors; use crate::errors;
use crate::mbe::{KleeneToken, TokenTree}; use crate::mbe::{KleeneToken, TokenTree};
@ -274,7 +274,7 @@ fn check_binders(
psess.dcx().emit_err(errors::MissingFragmentSpecifier { psess.dcx().emit_err(errors::MissingFragmentSpecifier {
span, span,
add_span: span.shrink_to_hi(), add_span: span.shrink_to_hi(),
valid: VALID_FRAGMENT_NAMES_MSG_2021, valid: VALID_FRAGMENT_NAMES_MSG,
}); });
} else { } else {
psess.buffer_lint( psess.buffer_lint(

View File

@ -1,4 +1,3 @@
use rustc_ast::token::NtExprKind::*;
use rustc_ast::token::{self, Delimiter, IdentIsRaw, NonterminalKind, Token}; use rustc_ast::token::{self, Delimiter, IdentIsRaw, NonterminalKind, Token};
use rustc_ast::{NodeId, tokenstream}; use rustc_ast::{NodeId, tokenstream};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
@ -13,12 +12,9 @@
use crate::mbe::macro_parser::count_metavar_decls; use crate::mbe::macro_parser::count_metavar_decls;
use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree}; use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ pub(crate) const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \ `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, \
`item` and `vis`"; `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility";
pub(crate) 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 `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 /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
@ -92,39 +88,13 @@ pub(super) fn parse(
}; };
let kind = NonterminalKind::from_symbol(fragment.name, edition) let kind = NonterminalKind::from_symbol(fragment.name, edition)
.unwrap_or_else(|| { .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 { sess.dcx().emit_err(errors::InvalidFragmentSpecifier {
span, span,
fragment, fragment,
help, help: VALID_FRAGMENT_NAMES_MSG.into(),
}); });
NonterminalKind::Ident NonterminalKind::Ident
}); });
if kind == NonterminalKind::Expr(Expr2021 { inferred: false })
&& !features.expr_fragment_specifier_2024
{
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))); result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
continue; continue;
} }

View File

@ -189,6 +189,8 @@ macro_rules! declare_features {
(accepted, exhaustive_integer_patterns, "1.33.0", Some(50907)), (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907)),
/// Allows explicit generic arguments specification with `impl Trait` present. /// Allows explicit generic arguments specification with `impl Trait` present.
(accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701)), (accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701)),
/// Uses 2024 rules for matching `expr` fragments in macros. Also enables `expr_2021` fragment.
(accepted, expr_fragment_specifier_2024, "CURRENT_RUSTC_VERSION", Some(123742)),
/// Allows arbitrary expressions in key-value attributes at parse time. /// Allows arbitrary expressions in key-value attributes at parse time.
(accepted, extended_key_value_attributes, "1.54.0", Some(78835)), (accepted, extended_key_value_attributes, "1.54.0", Some(78835)),
/// Allows resolving absolute paths as paths from other crates. /// Allows resolving absolute paths as paths from other crates.

View File

@ -450,8 +450,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
(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, "1.80.0", 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

@ -4,7 +4,7 @@ error: invalid fragment specifier `t_ty`
LL | ($wrong:t_ty) => () LL | ($wrong:t_ty) => ()
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -0,0 +1,14 @@
//@ check-pass
//@ edition: 2015
// Ensures expr_2021 fragment specifier is accepted in old editions
macro_rules! my_macro {
($x:expr_2021) => {
println!("Hello, {}!", $x);
};
}
fn main() {
my_macro!("world");
}

View File

@ -1,8 +1,6 @@
//@ run-rustfix //@ run-rustfix
//@ check-pass //@ check-pass
//@ compile-flags: --edition=2021 //@ compile-flags: --edition=2021
#![allow(incomplete_features)]
#![feature(expr_fragment_specifier_2024)]
#![warn(edition_2024_expr_fragment_specifier)] #![warn(edition_2024_expr_fragment_specifier)]
macro_rules! m { macro_rules! m {

View File

@ -1,8 +1,6 @@
//@ run-rustfix //@ run-rustfix
//@ check-pass //@ check-pass
//@ compile-flags: --edition=2021 //@ compile-flags: --edition=2021
#![allow(incomplete_features)]
#![feature(expr_fragment_specifier_2024)]
#![warn(edition_2024_expr_fragment_specifier)] #![warn(edition_2024_expr_fragment_specifier)]
macro_rules! m { macro_rules! m {

View File

@ -1,5 +1,5 @@
warning: the `expr` fragment specifier will accept more expressions in the 2024 edition warning: the `expr` fragment specifier will accept more expressions in the 2024 edition
--> $DIR/expr_2021_cargo_fix_edition.rs:9:9 --> $DIR/expr_2021_cargo_fix_edition.rs:7:9
| |
LL | ($e:expr) => { LL | ($e:expr) => {
| ^^^^ | ^^^^
@ -7,7 +7,7 @@ LL | ($e:expr) => {
= warning: this changes meaning in Rust 2024 = warning: this changes meaning in Rust 2024
= note: for more information, see Migration Guide <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html> = note: for more information, see Migration Guide <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html>
note: the lint level is defined here note: the lint level is defined here
--> $DIR/expr_2021_cargo_fix_edition.rs:6:9 --> $DIR/expr_2021_cargo_fix_edition.rs:4:9
| |
LL | #![warn(edition_2024_expr_fragment_specifier)] LL | #![warn(edition_2024_expr_fragment_specifier)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | ($e:expr_2021) => {
| ~~~~~~~~~ | ~~~~~~~~~
warning: the `expr` fragment specifier will accept more expressions in the 2024 edition warning: the `expr` fragment specifier will accept more expressions in the 2024 edition
--> $DIR/expr_2021_cargo_fix_edition.rs:13:11 --> $DIR/expr_2021_cargo_fix_edition.rs:11:11
| |
LL | ($($i:expr)*) => { }; LL | ($($i:expr)*) => { };
| ^^^^ | ^^^^

View File

@ -1,5 +1,5 @@
error: no rules expected the token `const` error: no rules expected the token `const`
--> $DIR/expr_2021_inline_const.rs:26:12 --> $DIR/expr_2021_inline_const.rs:23:12
| |
LL | macro_rules! m2021 { LL | macro_rules! m2021 {
| ------------------ when calling this macro | ------------------ when calling this macro
@ -8,13 +8,13 @@ LL | m2021!(const { 1 });
| ^^^^^ no rules expected this token in macro call | ^^^^^ no rules expected this token in macro call
| |
note: while trying to match meta-variable `$e:expr_2021` note: while trying to match meta-variable `$e:expr_2021`
--> $DIR/expr_2021_inline_const.rs:10:6 --> $DIR/expr_2021_inline_const.rs:7:6
| |
LL | ($e:expr_2021) => { LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: no rules expected the token `const` error: no rules expected the token `const`
--> $DIR/expr_2021_inline_const.rs:27:12 --> $DIR/expr_2021_inline_const.rs:24:12
| |
LL | macro_rules! m2024 { LL | macro_rules! m2024 {
| ------------------ when calling this macro | ------------------ when calling this macro
@ -23,7 +23,7 @@ LL | m2024!(const { 1 });
| ^^^^^ no rules expected this token in macro call | ^^^^^ no rules expected this token in macro call
| |
note: while trying to match meta-variable `$e:expr` note: while trying to match meta-variable `$e:expr`
--> $DIR/expr_2021_inline_const.rs:16:6 --> $DIR/expr_2021_inline_const.rs:13:6
| |
LL | ($e:expr) => { LL | ($e:expr) => {
| ^^^^^^^ | ^^^^^^^

View File

@ -1,5 +1,5 @@
error: no rules expected the token `const` error: no rules expected the token `const`
--> $DIR/expr_2021_inline_const.rs:26:12 --> $DIR/expr_2021_inline_const.rs:23:12
| |
LL | macro_rules! m2021 { LL | macro_rules! m2021 {
| ------------------ when calling this macro | ------------------ when calling this macro
@ -8,7 +8,7 @@ LL | m2021!(const { 1 });
| ^^^^^ no rules expected this token in macro call | ^^^^^ no rules expected this token in macro call
| |
note: while trying to match meta-variable `$e:expr_2021` note: while trying to match meta-variable `$e:expr_2021`
--> $DIR/expr_2021_inline_const.rs:10:6 --> $DIR/expr_2021_inline_const.rs:7:6
| |
LL | ($e:expr_2021) => { LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^

View File

@ -3,9 +3,6 @@
//@[edi2021]compile-flags: --edition=2021 //@[edi2021]compile-flags: --edition=2021
// This test ensures that the inline const match only on edition 2024 // This test ensures that the inline const match only on edition 2024
#![feature(expr_fragment_specifier_2024)]
#![allow(incomplete_features)]
macro_rules! m2021 { macro_rules! m2021 {
($e:expr_2021) => { ($e:expr_2021) => {
$e $e

View File

@ -1,5 +1,5 @@
error: no rules expected the token `_` error: no rules expected the token `_`
--> $DIR/expr_2024_underscore_expr.rs:22:12 --> $DIR/expr_2024_underscore_expr.rs:19:12
| |
LL | macro_rules! m2021 { LL | macro_rules! m2021 {
| ------------------ when calling this macro | ------------------ when calling this macro
@ -8,13 +8,13 @@ LL | m2021!(_);
| ^ no rules expected this token in macro call | ^ no rules expected this token in macro call
| |
note: while trying to match meta-variable `$e:expr_2021` note: while trying to match meta-variable `$e:expr_2021`
--> $DIR/expr_2024_underscore_expr.rs:10:6 --> $DIR/expr_2024_underscore_expr.rs:7:6
| |
LL | ($e:expr_2021) => { LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: no rules expected the token `_` error: no rules expected the token `_`
--> $DIR/expr_2024_underscore_expr.rs:23:12 --> $DIR/expr_2024_underscore_expr.rs:20:12
| |
LL | macro_rules! m2024 { LL | macro_rules! m2024 {
| ------------------ when calling this macro | ------------------ when calling this macro
@ -23,7 +23,7 @@ LL | m2024!(_);
| ^ no rules expected this token in macro call | ^ no rules expected this token in macro call
| |
note: while trying to match meta-variable `$e:expr` note: while trying to match meta-variable `$e:expr`
--> $DIR/expr_2024_underscore_expr.rs:16:6 --> $DIR/expr_2024_underscore_expr.rs:13:6
| |
LL | ($e:expr) => { LL | ($e:expr) => {
| ^^^^^^^ | ^^^^^^^

View File

@ -1,5 +1,5 @@
error: no rules expected the token `_` error: no rules expected the token `_`
--> $DIR/expr_2024_underscore_expr.rs:22:12 --> $DIR/expr_2024_underscore_expr.rs:19:12
| |
LL | macro_rules! m2021 { LL | macro_rules! m2021 {
| ------------------ when calling this macro | ------------------ when calling this macro
@ -8,7 +8,7 @@ LL | m2021!(_);
| ^ no rules expected this token in macro call | ^ no rules expected this token in macro call
| |
note: while trying to match meta-variable `$e:expr_2021` note: while trying to match meta-variable `$e:expr_2021`
--> $DIR/expr_2024_underscore_expr.rs:10:6 --> $DIR/expr_2024_underscore_expr.rs:7:6
| |
LL | ($e:expr_2021) => { LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^

View File

@ -3,9 +3,6 @@
//@[edi2021]compile-flags: --edition=2021 //@[edi2021]compile-flags: --edition=2021
// This test ensures that the `_` tok is considered an // This test ensures that the `_` tok is considered an
// expression on edition 2024. // expression on edition 2024.
#![feature(expr_fragment_specifier_2024)]
#![allow(incomplete_features)]
macro_rules! m2021 { macro_rules! m2021 {
($e:expr_2021) => { ($e:expr_2021) => {
$e = 1; $e = 1;

View File

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

View File

@ -1,13 +0,0 @@
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`.

View File

@ -4,7 +4,7 @@ error: invalid fragment specifier `id`
LL | ($wrong:id) => {}; LL | ($wrong:id) => {};
| ^^^^^^^^^ | ^^^^^^^^^
| |
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
error: invalid fragment specifier `r#if` error: invalid fragment specifier `r#if`
--> $DIR/invalid-fragment-specifier.rs:7:6 --> $DIR/invalid-fragment-specifier.rs:7:6
@ -12,7 +12,7 @@ error: invalid fragment specifier `r#if`
LL | ($wrong:r#if) => {}; LL | ($wrong:r#if) => {};
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -4,7 +4,7 @@ error: invalid fragment specifier `t_ty`
LL | macro_rules! test { ($wrong:t_ty ..) => () } LL | macro_rules! test { ($wrong:t_ty ..) => () }
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -5,7 +5,7 @@ LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= note: fragment specifiers must be specified in the 2024 edition = note: fragment specifiers must be specified in the 2024 edition
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
help: try adding a specifier here help: try adding a specifier here
| |
LL | ( $( any_token $field_rust_type:spec )* ) => {}; LL | ( $( any_token $field_rust_type:spec )* ) => {};
@ -18,7 +18,7 @@ LL | ( $name ) => {};
| ^^^^^ | ^^^^^
| |
= note: fragment specifiers must be specified in the 2024 edition = note: fragment specifiers must be specified in the 2024 edition
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
help: try adding a specifier here help: try adding a specifier here
| |
LL | ( $name:spec ) => {}; LL | ( $name:spec ) => {};
@ -31,7 +31,7 @@ LL | ( $name ) => {};
| ^^^^^ | ^^^^^
| |
= note: fragment specifiers must be specified in the 2024 edition = note: fragment specifiers must be specified in the 2024 edition
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility
help: try adding a specifier here help: try adding a specifier here
| |
LL | ( $name:spec ) => {}; LL | ( $name:spec ) => {};

View File

@ -6,7 +6,6 @@
// This test captures the behavior of macro-generating-macros with fragment // This test captures the behavior of macro-generating-macros with fragment
// specifiers across edition boundaries. // specifiers across edition boundaries.
#![feature(expr_fragment_specifier_2024)]
#![feature(macro_metavar_expr)] #![feature(macro_metavar_expr)]
#![allow(incomplete_features)] #![allow(incomplete_features)]