1
Fork 0

Allow naming expr_2021 in all editions

This commit is contained in:
Michael Goulet 2024-06-19 12:21:09 -04:00
parent 50d1efa3e2
commit 3e8898a4e1
8 changed files with 23 additions and 59 deletions

View file

@ -884,7 +884,11 @@ pub enum NonterminalKind {
PatWithOr, PatWithOr,
Expr, Expr,
/// Matches an expression using the rules from edition 2021 and earlier. /// Matches an expression using the rules from edition 2021 and earlier.
Expr2021, Expr2021 {
/// Keep track of whether the user used `:expr` or `:expr_2021` and we inferred it from the
/// edition of the span. This is used for diagnostics AND feature gating.
inferred: bool,
},
Ty, Ty,
Ident, Ident,
Lifetime, Lifetime,
@ -913,8 +917,13 @@ impl NonterminalKind {
Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr, Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
}, },
sym::pat_param => NonterminalKind::PatParam { inferred: false }, sym::pat_param => NonterminalKind::PatParam { inferred: false },
sym::expr => NonterminalKind::Expr, sym::expr => match edition() {
sym::expr_2021 if edition().at_least_rust_2021() => NonterminalKind::Expr2021, Edition::Edition2015 | Edition::Edition2018 | Edition::Edition2021 => {
NonterminalKind::Expr2021 { inferred: true }
}
Edition::Edition2024 => NonterminalKind::Expr,
},
sym::expr_2021 => NonterminalKind::Expr2021 { inferred: false },
sym::ty => NonterminalKind::Ty, sym::ty => NonterminalKind::Ty,
sym::ident => NonterminalKind::Ident, sym::ident => NonterminalKind::Ident,
sym::lifetime => NonterminalKind::Lifetime, sym::lifetime => NonterminalKind::Lifetime,
@ -933,8 +942,8 @@ impl NonterminalKind {
NonterminalKind::Stmt => sym::stmt, NonterminalKind::Stmt => sym::stmt,
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 | NonterminalKind::Expr2021 { inferred: true } => sym::expr,
NonterminalKind::Expr2021 => sym::expr_2021, NonterminalKind::Expr2021 { inferred: false } => 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

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

View file

@ -113,7 +113,8 @@ pub(super) fn parse(
); );
token::NonterminalKind::Ident token::NonterminalKind::Ident
}); });
if kind == token::NonterminalKind::Expr2021 if kind
== (token::NonterminalKind::Expr2021 { inferred: false })
&& !features.expr_fragment_specifier_2024 && !features.expr_fragment_specifier_2024
{ {
rustc_session::parse::feature_err( rustc_session::parse::feature_err(

View file

@ -36,7 +36,7 @@ impl<'a> Parser<'a> {
} }
match kind { match kind {
NonterminalKind::Expr2021 => { NonterminalKind::Expr2021 { inferred: _ } => {
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)
@ -47,7 +47,6 @@ impl<'a> Parser<'a> {
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)
&& (!token.is_keyword(kw::Const) || token.span.edition().at_least_rust_2024())
} }
NonterminalKind::Ty => token.can_begin_type(), NonterminalKind::Ty => token.can_begin_type(),
NonterminalKind::Ident => get_macro_ident(token).is_some(), NonterminalKind::Ident => get_macro_ident(token).is_some(),
@ -149,7 +148,7 @@ impl<'a> Parser<'a> {
})?) })?)
} }
NonterminalKind::Expr | NonterminalKind::Expr2021 => { NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: _ } => {
NtExpr(self.parse_expr_force_collect()?) NtExpr(self.parse_expr_force_collect()?)
} }
NonterminalKind::Literal => { NonterminalKind::Literal => {

View file

@ -1,6 +1,8 @@
//@ compile-flags: --edition=2024 -Zunstable-options //@ compile-flags: --edition=2024 -Zunstable-options
//@ aux-build:expr_2021_implicit.rs //@ aux-build:expr_2021_implicit.rs
//@ check-pass
extern crate expr_2021_implicit; extern crate expr_2021_implicit;
// Makes sure that a `:expr` fragment matcher defined in a edition 2021 crate // Makes sure that a `:expr` fragment matcher defined in a edition 2021 crate

View file

@ -1,10 +0,0 @@
error: did not expect an expression to be parsed
--> $DIR/expr_2021_implicit_in_2024.rs:8:1
|
LL | expr_2021_implicit::m!(const {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `expr_2021_implicit::m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error

View file

@ -1,13 +0,0 @@
//@ compile-flags: --edition=2018
// 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`
$e
};
}
fn main() {
m!(()); //~ ERROR: no rules expected the token `(`
}

View file

@ -1,26 +0,0 @@
error: invalid fragment specifier `expr_2021`
--> $DIR/expr_2021_old_edition.rs:6:6
|
LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^
|
= 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
|
LL | macro_rules! m {
| -------------- when calling this macro
...
LL | m!(());
| ^ no rules expected this token in macro call
|
note: while trying to match meta-variable `$e:ident`
--> $DIR/expr_2021_old_edition.rs:6:6
|
LL | ($e:expr_2021) => {
| ^^^^^^^^^^^^
error: aborting due to 2 previous errors