Skip to content

Commit 44f8545

Browse files
committed
Auto merge of rust-lang#18137 - ShoyuVanilla:expr-2021, r=Veykril
feat: Implement `expr_2021` Resolves rust-lang#18062
2 parents c47a656 + 65e87e2 commit 44f8545

File tree

5 files changed

+192
-21
lines changed

5 files changed

+192
-21
lines changed

src/tools/rust-analyzer/crates/mbe/src/benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ fn invocation_fixtures(
146146
Some(MetaVarKind::Pat) => token_trees.push(make_ident("foo")),
147147
Some(MetaVarKind::Path) => token_trees.push(make_ident("foo")),
148148
Some(MetaVarKind::Literal) => token_trees.push(make_literal("1")),
149-
Some(MetaVarKind::Expr) => token_trees.push(make_ident("foo")),
149+
Some(MetaVarKind::Expr(_)) => token_trees.push(make_ident("foo")),
150150
Some(MetaVarKind::Lifetime) => {
151151
token_trees.push(make_punct('\''));
152152
token_trees.push(make_ident("a"));

src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use tt::{iter::TtIter, DelimSpan};
6969
use crate::{
7070
expander::{Binding, Bindings, ExpandResult, Fragment},
7171
expect_fragment,
72-
parser::{MetaVarKind, Op, RepeatKind, Separator},
72+
parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator},
7373
ExpandError, ExpandErrorKind, MetaTemplate, ValueResult,
7474
};
7575

@@ -769,23 +769,28 @@ fn match_meta_var(
769769
it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
770770
});
771771
}
772-
MetaVarKind::Expr => {
773-
// `expr` should not match underscores, let expressions, or inline const. The latter
774-
// two are for [backwards compatibility][0].
772+
MetaVarKind::Expr(expr) => {
773+
// `expr_2021` should not match underscores, let expressions, or inline const.
774+
// The latter two are for [backwards compatibility][0].
775+
// And `expr` also should not contain let expressions but may contain the other two
776+
// since `Edition2024`.
775777
// HACK: Macro expansion should not be done using "rollback and try another alternative".
776778
// rustc [explicitly checks the next token][1].
777779
// [0]: https://github.com/rust-lang/rust/issues/86730
778780
// [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
779781
match input.peek_n(0) {
780-
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it)))
781-
if it.sym == sym::underscore
782-
|| it.sym == sym::let_
783-
|| it.sym == sym::const_ =>
784-
{
785-
return ExpandResult::only_err(ExpandError::new(
786-
it.span,
787-
ExpandErrorKind::NoMatchingRule,
788-
))
782+
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) => {
783+
let is_err = if matches!(expr, ExprKind::Expr2021) {
784+
it.sym == sym::underscore || it.sym == sym::let_ || it.sym == sym::const_
785+
} else {
786+
it.sym == sym::let_
787+
};
788+
if is_err {
789+
return ExpandResult::only_err(ExpandError::new(
790+
it.span,
791+
ExpandErrorKind::NoMatchingRule,
792+
));
793+
}
789794
}
790795
_ => {}
791796
};

src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl Bindings {
9797
| MetaVarKind::Ty
9898
| MetaVarKind::Pat
9999
| MetaVarKind::PatParam
100-
| MetaVarKind::Expr
100+
| MetaVarKind::Expr(_)
101101
| MetaVarKind::Ident => {
102102
Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
103103
sym: sym::missing.clone(),

src/tools/rust-analyzer/crates/mbe/src/parser.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ pub(crate) enum RepeatKind {
105105
ZeroOrOne,
106106
}
107107

108+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
109+
pub(crate) enum ExprKind {
110+
// Matches expressions using the post-edition 2024. Was written using
111+
// `expr` in edition 2024 or later.
112+
Expr,
113+
// Matches expressions using the pre-edition 2024 rules.
114+
// Either written using `expr` in edition 2021 or earlier or.was written using `expr_2021`.
115+
Expr2021,
116+
}
117+
108118
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
109119
pub(crate) enum MetaVarKind {
110120
Path,
@@ -116,7 +126,7 @@ pub(crate) enum MetaVarKind {
116126
Meta,
117127
Item,
118128
Vis,
119-
Expr,
129+
Expr(ExprKind),
120130
Ident,
121131
Tt,
122132
Lifetime,
@@ -277,17 +287,27 @@ fn eat_fragment_kind(
277287
let kind = match ident.sym.as_str() {
278288
"path" => MetaVarKind::Path,
279289
"ty" => MetaVarKind::Ty,
280-
"pat" => match edition(ident.span.ctx) {
281-
Edition::Edition2015 | Edition::Edition2018 => MetaVarKind::PatParam,
282-
Edition::Edition2021 | Edition::Edition2024 => MetaVarKind::Pat,
283-
},
290+
"pat" => {
291+
if edition(ident.span.ctx).at_least_2021() {
292+
MetaVarKind::Pat
293+
} else {
294+
MetaVarKind::PatParam
295+
}
296+
}
284297
"pat_param" => MetaVarKind::PatParam,
285298
"stmt" => MetaVarKind::Stmt,
286299
"block" => MetaVarKind::Block,
287300
"meta" => MetaVarKind::Meta,
288301
"item" => MetaVarKind::Item,
289302
"vis" => MetaVarKind::Vis,
290-
"expr" => MetaVarKind::Expr,
303+
"expr" => {
304+
if edition(ident.span.ctx).at_least_2024() {
305+
MetaVarKind::Expr(ExprKind::Expr)
306+
} else {
307+
MetaVarKind::Expr(ExprKind::Expr2021)
308+
}
309+
}
310+
"expr_2021" => MetaVarKind::Expr(ExprKind::Expr2021),
291311
"ident" => MetaVarKind::Ident,
292312
"tt" => MetaVarKind::Tt,
293313
"lifetime" => MetaVarKind::Lifetime,

src/tools/rust-analyzer/crates/mbe/src/tests.rs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,149 @@ fn main() {
177177
}"#]],
178178
);
179179
}
180+
181+
#[test]
182+
fn expr_2021() {
183+
check(
184+
Edition::Edition2024,
185+
Edition::Edition2024,
186+
r#"
187+
($($e:expr),* $(,)?) => {
188+
$($e);* ;
189+
};
190+
"#,
191+
r#"
192+
_,
193+
const { 1 },
194+
"#,
195+
expect![[r#"
196+
197+
IDENT _ 1:[email protected]#0
198+
PUNCH ; [joint] 0:[email protected]#0
199+
200+
IDENT const 1:[email protected]#0
201+
202+
LITERAL Integer 1 1:[email protected]#0
203+
PUNCH ; [alone] 0:[email protected]#0
204+
205+
_;
206+
(const {
207+
1
208+
});"#]],
209+
);
210+
check(
211+
Edition::Edition2021,
212+
Edition::Edition2024,
213+
r#"
214+
($($e:expr),* $(,)?) => {
215+
$($e);* ;
216+
};
217+
"#,
218+
r#"
219+
_,
220+
"#,
221+
expect![[r#"
222+
ExpandError {
223+
inner: (
224+
225+
NoMatchingRule,
226+
),
227+
}
228+
229+
230+
PUNCH ; [alone] 0:[email protected]#0
231+
232+
;"#]],
233+
);
234+
check(
235+
Edition::Edition2021,
236+
Edition::Edition2024,
237+
r#"
238+
($($e:expr),* $(,)?) => {
239+
$($e);* ;
240+
};
241+
"#,
242+
r#"
243+
const { 1 },
244+
"#,
245+
expect![[r#"
246+
ExpandError {
247+
inner: (
248+
249+
NoMatchingRule,
250+
),
251+
}
252+
253+
254+
PUNCH ; [alone] 0:[email protected]#0
255+
256+
;"#]],
257+
);
258+
check(
259+
Edition::Edition2024,
260+
Edition::Edition2024,
261+
r#"
262+
($($e:expr_2021),* $(,)?) => {
263+
$($e);* ;
264+
};
265+
"#,
266+
r#"
267+
4,
268+
"literal",
269+
funcall(),
270+
future.await,
271+
break 'foo bar,
272+
"#,
273+
expect![[r#"
274+
275+
LITERAL Integer 4 1:[email protected]#0
276+
PUNCH ; [joint] 0:[email protected]#0
277+
LITERAL Str literal 1:[email protected]#0
278+
PUNCH ; [joint] 0:[email protected]#0
279+
280+
IDENT funcall 1:[email protected]#0
281+
282+
PUNCH ; [joint] 0:[email protected]#0
283+
284+
IDENT future 1:[email protected]#0
285+
PUNCH . [alone] 1:[email protected]#0
286+
IDENT await 1:[email protected]#0
287+
PUNCH ; [joint] 0:[email protected]#0
288+
289+
IDENT break 1:[email protected]#0
290+
PUNCH ' [joint] 1:[email protected]#0
291+
IDENT foo 1:[email protected]#0
292+
IDENT bar 1:[email protected]#0
293+
PUNCH ; [alone] 0:[email protected]#0
294+
295+
4;
296+
"literal";
297+
(funcall());
298+
(future.await);
299+
(break 'foo bar);"#]],
300+
);
301+
check(
302+
Edition::Edition2024,
303+
Edition::Edition2024,
304+
r#"
305+
($($e:expr_2021),* $(,)?) => {
306+
$($e);* ;
307+
};
308+
"#,
309+
r#"
310+
_,
311+
"#,
312+
expect![[r#"
313+
ExpandError {
314+
inner: (
315+
316+
NoMatchingRule,
317+
),
318+
}
319+
320+
321+
PUNCH ; [alone] 0:[email protected]#0
322+
323+
;"#]],
324+
);
325+
}

0 commit comments

Comments
 (0)