Skip to content

Commit 250a3e5

Browse files
authored
Rollup merge of rust-lang#126700 - compiler-errors:fragment, r=fmease
Make edition dependent `:expr` macro fragment act like the edition-dependent `:pat` fragment does Parse the `:expr` fragment as `:expr_2021` in editions <=2021, and as `:expr` in edition 2024. This is similar to how we parse `:pat` as `:pat_param` in edition <=2018 and `:pat_with_or` in >=2021, and means we can get rid of a span dependency from `nonterminal_may_begin_with`. Specifically, this fixes a theoretical regression since the `expr_2021` macro fragment previously would allow `const {}` if the *caller* is edition 2024. This is inconsistent with the way that the `pat` macro fragment was upgraded, and also leads to surprising behavior when a macro *caller* crate upgrades to edtion 2024, since they may have parsing changes that they never asked for (with no way of opting out of it). This PR also allows using `expr_2021` in all editions. Why was this was disallowed in the first place? It's purely additive, and also it's still feature gated? r? `@fmease` `@eholk` cc `@vincenzopalazzo` cc rust-lang#123865 Tracking: - rust-lang#123742
2 parents 2700fc8 + 3e8898a commit 250a3e5

File tree

8 files changed

+42
-49
lines changed

8 files changed

+42
-49
lines changed

Diff for: compiler/rustc_ast/src/token.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,11 @@ pub enum NonterminalKind {
900900
PatWithOr,
901901
Expr,
902902
/// Matches an expression using the rules from edition 2021 and earlier.
903-
Expr2021,
903+
Expr2021 {
904+
/// Keep track of whether the user used `:expr` or `:expr_2021` and we inferred it from the
905+
/// edition of the span. This is used for diagnostics AND feature gating.
906+
inferred: bool,
907+
},
904908
Ty,
905909
Ident,
906910
Lifetime,
@@ -929,8 +933,13 @@ impl NonterminalKind {
929933
Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
930934
},
931935
sym::pat_param => NonterminalKind::PatParam { inferred: false },
932-
sym::expr => NonterminalKind::Expr,
933-
sym::expr_2021 if edition().at_least_rust_2021() => NonterminalKind::Expr2021,
936+
sym::expr => match edition() {
937+
Edition::Edition2015 | Edition::Edition2018 | Edition::Edition2021 => {
938+
NonterminalKind::Expr2021 { inferred: true }
939+
}
940+
Edition::Edition2024 => NonterminalKind::Expr,
941+
},
942+
sym::expr_2021 => NonterminalKind::Expr2021 { inferred: false },
934943
sym::ty => NonterminalKind::Ty,
935944
sym::ident => NonterminalKind::Ident,
936945
sym::lifetime => NonterminalKind::Lifetime,
@@ -949,8 +958,8 @@ impl NonterminalKind {
949958
NonterminalKind::Stmt => sym::stmt,
950959
NonterminalKind::PatParam { inferred: false } => sym::pat_param,
951960
NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat,
952-
NonterminalKind::Expr => sym::expr,
953-
NonterminalKind::Expr2021 => sym::expr_2021,
961+
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: true } => sym::expr,
962+
NonterminalKind::Expr2021 { inferred: false } => sym::expr_2021,
954963
NonterminalKind::Ty => sym::ty,
955964
NonterminalKind::Ident => sym::ident,
956965
NonterminalKind::Lifetime => sym::lifetime,

Diff for: compiler/rustc_expand/src/mbe/macro_rules.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,9 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
12921292
// maintain
12931293
IsInFollow::Yes
12941294
}
1295-
NonterminalKind::Stmt | NonterminalKind::Expr | NonterminalKind::Expr2021 => {
1295+
NonterminalKind::Stmt
1296+
| NonterminalKind::Expr
1297+
| NonterminalKind::Expr2021 { inferred: _ } => {
12961298
const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
12971299
match tok {
12981300
TokenTree::Token(token) => match token.kind {

Diff for: compiler/rustc_expand/src/mbe/quoted.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ pub(super) fn parse(
113113
);
114114
token::NonterminalKind::Ident
115115
});
116-
if kind == token::NonterminalKind::Expr2021
116+
if kind
117+
== (token::NonterminalKind::Expr2021 { inferred: false })
117118
&& !features.expr_fragment_specifier_2024
118119
{
119120
rustc_session::parse::feature_err(

Diff for: compiler/rustc_parse/src/parser/nonterminal.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<'a> Parser<'a> {
3636
}
3737

3838
match kind {
39-
NonterminalKind::Expr2021 => {
39+
NonterminalKind::Expr2021 { inferred: _ } => {
4040
token.can_begin_expr()
4141
// This exception is here for backwards compatibility.
4242
&& !token.is_keyword(kw::Let)
@@ -47,7 +47,6 @@ impl<'a> Parser<'a> {
4747
token.can_begin_expr()
4848
// This exception is here for backwards compatibility.
4949
&& !token.is_keyword(kw::Let)
50-
&& (!token.is_keyword(kw::Const) || token.span.edition().at_least_rust_2024())
5150
}
5251
NonterminalKind::Ty => token.can_begin_type(),
5352
NonterminalKind::Ident => get_macro_ident(token).is_some(),
@@ -149,7 +148,7 @@ impl<'a> Parser<'a> {
149148
})?)
150149
}
151150

152-
NonterminalKind::Expr | NonterminalKind::Expr2021 => {
151+
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: _ } => {
153152
NtExpr(self.parse_expr_force_collect()?)
154153
}
155154
NonterminalKind::Literal => {

Diff for: tests/ui/macros/auxiliary/expr_2021_implicit.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@ edition:2021
2+
3+
#[macro_export]
4+
macro_rules! m {
5+
($expr:expr) => {
6+
compile_error!("did not expect an expression to be parsed");
7+
};
8+
(const { }) => {};
9+
}

Diff for: tests/ui/macros/expr_2021_implicit_in_2024.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ compile-flags: --edition=2024 -Zunstable-options
2+
//@ aux-build:expr_2021_implicit.rs
3+
4+
//@ check-pass
5+
6+
extern crate expr_2021_implicit;
7+
8+
// Makes sure that a `:expr` fragment matcher defined in a edition 2021 crate
9+
// still parses like an `expr_2021` fragment matcher in a 2024 user crate.
10+
expr_2021_implicit::m!(const {});
11+
12+
fn main() {}

Diff for: tests/ui/macros/expr_2021_old_edition.rs

-13
This file was deleted.

Diff for: tests/ui/macros/expr_2021_old_edition.stderr

-26
This file was deleted.

0 commit comments

Comments
 (0)