Skip to content

Commit

Permalink
Auto merge of rust-lang#129972 - eholk:stabilize-expr_2021, r=compile…
Browse files Browse the repository at this point in the history
…r-errors,traviscross

Stabilize expr_2021 fragment specifier in all editions

This is part of the `expr`/`expr_2021` fragment specifier for Edition 2024 (rust-lang#123742). The RFC says we can support expr_2021 in as many editions as is practical, and there's nothing particularly hard about supporting it all the way back to 2015.

In editions 2021 and earlier, `expr` and `expr_2021` are synonyms. Their behavior diverges starting in Edition 2024. This is checked by the `expr_2021_inline_const.rs` test.

cc `@vincenzopalazzo` `@rust-lang/wg-macros` `@traviscross`
  • Loading branch information
bors committed Oct 1, 2024
2 parents 07f08ff + c7cd55f commit 21aa500
Show file tree
Hide file tree
Showing 21 changed files with 44 additions and 95 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/mbe/macro_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ use rustc_span::symbol::{MacroRulesNormalizedIdent, kw};
use rustc_span::{ErrorGuaranteed, Span};
use smallvec::SmallVec;

use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021;
use super::quoted::VALID_FRAGMENT_NAMES_MSG;
use crate::errors;
use crate::mbe::{KleeneToken, TokenTree};

Expand Down Expand Up @@ -274,7 +274,7 @@ fn check_binders(
psess.dcx().emit_err(errors::MissingFragmentSpecifier {
span,
add_span: span.shrink_to_hi(),
valid: VALID_FRAGMENT_NAMES_MSG_2021,
valid: VALID_FRAGMENT_NAMES_MSG,
});
} else {
psess.buffer_lint(
Expand Down
38 changes: 4 additions & 34 deletions compiler/rustc_expand/src/mbe/quoted.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use rustc_ast::token::NtExprKind::*;
use rustc_ast::token::{self, Delimiter, IdentIsRaw, NonterminalKind, Token};
use rustc_ast::{NodeId, tokenstream};
use rustc_ast_pretty::pprust;
Expand All @@ -13,12 +12,9 @@ use crate::errors;
use crate::mbe::macro_parser::count_metavar_decls;
use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};

const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
`item` and `vis`";
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`";
pub(crate) const VALID_FRAGMENT_NAMES_MSG: &str = "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";

/// 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
Expand Down Expand Up @@ -92,39 +88,13 @@ pub(super) fn parse(
};
let kind = 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,
help: VALID_FRAGMENT_NAMES_MSG.into(),
});
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)));
continue;
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ declare_features! (
(accepted, exhaustive_integer_patterns, "1.33.0", Some(50907)),
/// Allows explicit generic arguments specification with `impl Trait` present.
(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.
(accepted, extended_key_value_attributes, "1.54.0", Some(78835)),
/// Allows resolving absolute paths as paths from other crates.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,6 @@ 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, "1.80.0", 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)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error: invalid fragment specifier `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

14 changes: 14 additions & 0 deletions tests/ui/macros/expr_2021.rs
Original file line number Diff line number Diff line change
@@ -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");
}
2 changes: 0 additions & 2 deletions tests/ui/macros/expr_2021_cargo_fix_edition.fixed
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//@ run-rustfix
//@ check-pass
//@ compile-flags: --edition=2021
#![allow(incomplete_features)]
#![feature(expr_fragment_specifier_2024)]
#![warn(edition_2024_expr_fragment_specifier)]

macro_rules! m {
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/macros/expr_2021_cargo_fix_edition.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//@ run-rustfix
//@ check-pass
//@ compile-flags: --edition=2021
#![allow(incomplete_features)]
#![feature(expr_fragment_specifier_2024)]
#![warn(edition_2024_expr_fragment_specifier)]

macro_rules! m {
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/macros/expr_2021_cargo_fix_edition.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
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) => {
| ^^^^
|
= 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: 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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -17,7 +17,7 @@ LL | ($e:expr_2021) => {
| ~~~~~~~~~

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)*) => { };
| ^^^^
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/macros/expr_2021_inline_const.edi2021.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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 {
| ------------------ when calling this macro
Expand All @@ -8,13 +8,13 @@ LL | m2021!(const { 1 });
| ^^^^^ no rules expected this token in macro call
|
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) => {
| ^^^^^^^^^^^^

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 {
| ------------------ when calling this macro
Expand All @@ -23,7 +23,7 @@ LL | m2024!(const { 1 });
| ^^^^^ no rules expected this token in macro call
|
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) => {
| ^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/macros/expr_2021_inline_const.edi2024.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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 {
| ------------------ when calling this macro
Expand All @@ -8,7 +8,7 @@ LL | m2021!(const { 1 });
| ^^^^^ no rules expected this token in macro call
|
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) => {
| ^^^^^^^^^^^^
Expand Down
3 changes: 0 additions & 3 deletions tests/ui/macros/expr_2021_inline_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
//@[edi2021]compile-flags: --edition=2021

// This test ensures that the inline const match only on edition 2024
#![feature(expr_fragment_specifier_2024)]
#![allow(incomplete_features)]

macro_rules! m2021 {
($e:expr_2021) => {
$e
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/macros/expr_2024_underscore_expr.edi2021.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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 {
| ------------------ when calling this macro
Expand All @@ -8,13 +8,13 @@ LL | m2021!(_);
| ^ no rules expected this token in macro call
|
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) => {
| ^^^^^^^^^^^^

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 {
| ------------------ when calling this macro
Expand All @@ -23,7 +23,7 @@ LL | m2024!(_);
| ^ no rules expected this token in macro call
|
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) => {
| ^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/macros/expr_2024_underscore_expr.edi2024.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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 {
| ------------------ when calling this macro
Expand All @@ -8,7 +8,7 @@ LL | m2021!(_);
| ^ no rules expected this token in macro call
|
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) => {
| ^^^^^^^^^^^^
Expand Down
3 changes: 0 additions & 3 deletions tests/ui/macros/expr_2024_underscore_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
//@[edi2021]compile-flags: --edition=2021
// This test ensures that the `_` tok is considered an
// expression on edition 2024.
#![feature(expr_fragment_specifier_2024)]
#![allow(incomplete_features)]

macro_rules! m2021 {
($e:expr_2021) => {
$e = 1;
Expand Down
11 changes: 0 additions & 11 deletions tests/ui/macros/feature-gate-expr_fragment_specifier_2024.rs

This file was deleted.

13 changes: 0 additions & 13 deletions tests/ui/macros/feature-gate-expr_fragment_specifier_2024.stderr

This file was deleted.

4 changes: 2 additions & 2 deletions tests/ui/macros/invalid-fragment-specifier.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ error: invalid fragment specifier `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`
--> $DIR/invalid-fragment-specifier.rs:7:6
|
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

2 changes: 1 addition & 1 deletion tests/ui/macros/issue-21356.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error: invalid fragment specifier `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

6 changes: 3 additions & 3 deletions tests/ui/macros/macro-missing-fragment.e2024.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | ( $( any_token $field_rust_type )* ) => {};
| ^^^^^^^^^^^^^^^^
|
= 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
|
LL | ( $( any_token $field_rust_type:spec )* ) => {};
Expand All @@ -18,7 +18,7 @@ LL | ( $name ) => {};
| ^^^^^
|
= 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
|
LL | ( $name:spec ) => {};
Expand All @@ -31,7 +31,7 @@ LL | ( $name ) => {};
| ^^^^^
|
= 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
|
LL | ( $name:spec ) => {};
Expand Down
1 change: 0 additions & 1 deletion tests/ui/macros/metavar_cross_edition_recursive_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// This test captures the behavior of macro-generating-macros with fragment
// specifiers across edition boundaries.

#![feature(expr_fragment_specifier_2024)]
#![feature(macro_metavar_expr)]
#![allow(incomplete_features)]

Expand Down

0 comments on commit 21aa500

Please sign in to comment.