Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement expr_2021 #18137

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/mbe/src/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ fn invocation_fixtures(
Some(MetaVarKind::Pat) => token_trees.push(make_ident("foo")),
Some(MetaVarKind::Path) => token_trees.push(make_ident("foo")),
Some(MetaVarKind::Literal) => token_trees.push(make_literal("1")),
Some(MetaVarKind::Expr) => token_trees.push(make_ident("foo")),
Some(MetaVarKind::Expr(_)) => token_trees.push(make_ident("foo")),
Some(MetaVarKind::Lifetime) => {
token_trees.push(make_punct('\''));
token_trees.push(make_ident("a"));
Expand Down
31 changes: 18 additions & 13 deletions crates/mbe/src/expander/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ use tt::{iter::TtIter, DelimSpan};
use crate::{
expander::{Binding, Bindings, ExpandResult, Fragment},
expect_fragment,
parser::{MetaVarKind, Op, RepeatKind, Separator},
parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator},
ExpandError, ExpandErrorKind, MetaTemplate, ValueResult,
};

Expand Down Expand Up @@ -769,23 +769,28 @@ fn match_meta_var(
it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
});
}
MetaVarKind::Expr => {
// `expr` should not match underscores, let expressions, or inline const. The latter
// two are for [backwards compatibility][0].
MetaVarKind::Expr(expr) => {
// `expr_2021` should not match underscores, let expressions, or inline const.
// The latter two are for [backwards compatibility][0].
// And `expr` also should not contain let expressions but may contain the other two
// since `Edition2024`.
// HACK: Macro expansion should not be done using "rollback and try another alternative".
// rustc [explicitly checks the next token][1].
// [0]: https://github.com/rust-lang/rust/issues/86730
// [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
match input.peek_n(0) {
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it)))
if it.sym == sym::underscore
|| it.sym == sym::let_
|| it.sym == sym::const_ =>
{
return ExpandResult::only_err(ExpandError::new(
it.span,
ExpandErrorKind::NoMatchingRule,
))
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) => {
let is_err = if matches!(expr, ExprKind::Expr2021) {
it.sym == sym::underscore || it.sym == sym::let_ || it.sym == sym::const_
} else {
it.sym == sym::let_
};
if is_err {
return ExpandResult::only_err(ExpandError::new(
it.span,
ExpandErrorKind::NoMatchingRule,
));
}
}
_ => {}
};
Expand Down
2 changes: 1 addition & 1 deletion crates/mbe/src/expander/transcriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Bindings {
| MetaVarKind::Ty
| MetaVarKind::Pat
| MetaVarKind::PatParam
| MetaVarKind::Expr
| MetaVarKind::Expr(_)
| MetaVarKind::Ident => {
Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
sym: sym::missing.clone(),
Expand Down
32 changes: 26 additions & 6 deletions crates/mbe/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ pub(crate) enum RepeatKind {
ZeroOrOne,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum ExprKind {
// Matches expressions using the post-edition 2024. Was written using
// `expr` in edition 2024 or later.
Expr,
// Matches expressions using the pre-edition 2024 rules.
// Either written using `expr` in edition 2021 or earlier or.was written using `expr_2021`.
Expr2021,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum MetaVarKind {
Path,
Expand All @@ -116,7 +126,7 @@ pub(crate) enum MetaVarKind {
Meta,
Item,
Vis,
Expr,
Expr(ExprKind),
Ident,
Tt,
Lifetime,
Expand Down Expand Up @@ -277,17 +287,27 @@ fn eat_fragment_kind(
let kind = match ident.sym.as_str() {
"path" => MetaVarKind::Path,
"ty" => MetaVarKind::Ty,
"pat" => match edition(ident.span.ctx) {
Edition::Edition2015 | Edition::Edition2018 => MetaVarKind::PatParam,
Edition::Edition2021 | Edition::Edition2024 => MetaVarKind::Pat,
},
"pat" => {
if edition(ident.span.ctx).at_least_2021() {
MetaVarKind::Pat
} else {
MetaVarKind::PatParam
}
}
"pat_param" => MetaVarKind::PatParam,
"stmt" => MetaVarKind::Stmt,
"block" => MetaVarKind::Block,
"meta" => MetaVarKind::Meta,
"item" => MetaVarKind::Item,
"vis" => MetaVarKind::Vis,
"expr" => MetaVarKind::Expr,
"expr" => {
if edition(ident.span.ctx).at_least_2024() {
MetaVarKind::Expr(ExprKind::Expr)
} else {
MetaVarKind::Expr(ExprKind::Expr2021)
}
}
"expr_2021" => MetaVarKind::Expr(ExprKind::Expr2021),
"ident" => MetaVarKind::Ident,
"tt" => MetaVarKind::Tt,
"lifetime" => MetaVarKind::Lifetime,
Expand Down
146 changes: 146 additions & 0 deletions crates/mbe/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,149 @@ fn main() {
}"#]],
);
}

#[test]
fn expr_2021() {
check(
Edition::Edition2024,
Edition::Edition2024,
r#"
($($e:expr),* $(,)?) => {
$($e);* ;
};
"#,
r#"
_,
const { 1 },
"#,
expect![[r#"
SUBTREE $$ 1:[email protected]#0 1:[email protected]#0
IDENT _ 1:[email protected]#0
PUNCH ; [joint] 0:[email protected]#0
SUBTREE () 0:[email protected]#0 0:[email protected]#0
IDENT const 1:[email protected]#0
SUBTREE {} 1:[email protected]#0 1:[email protected]#0
LITERAL Integer 1 1:[email protected]#0
PUNCH ; [alone] 0:[email protected]#0

_;
(const {
1
});"#]],
);
check(
Edition::Edition2021,
Edition::Edition2024,
r#"
($($e:expr),* $(,)?) => {
$($e);* ;
};
"#,
r#"
_,
"#,
expect![[r#"
ExpandError {
inner: (
1:[email protected]#0,
NoMatchingRule,
),
}

SUBTREE $$ 1:[email protected]#0 1:[email protected]#0
PUNCH ; [alone] 0:[email protected]#0

;"#]],
);
check(
Edition::Edition2021,
Edition::Edition2024,
r#"
($($e:expr),* $(,)?) => {
$($e);* ;
};
"#,
r#"
const { 1 },
"#,
expect![[r#"
ExpandError {
inner: (
1:[email protected]#0,
NoMatchingRule,
),
}

SUBTREE $$ 1:[email protected]#0 1:[email protected]#0
PUNCH ; [alone] 0:[email protected]#0

;"#]],
);
check(
Edition::Edition2024,
Edition::Edition2024,
r#"
($($e:expr_2021),* $(,)?) => {
$($e);* ;
};
"#,
r#"
4,
"literal",
funcall(),
future.await,
break 'foo bar,
"#,
expect![[r#"
SUBTREE $$ 1:[email protected]#0 1:[email protected]#0
LITERAL Integer 4 1:[email protected]#0
PUNCH ; [joint] 0:[email protected]#0
LITERAL Str literal 1:[email protected]#0
PUNCH ; [joint] 0:[email protected]#0
SUBTREE () 0:[email protected]#0 0:[email protected]#0
IDENT funcall 1:[email protected]#0
SUBTREE () 1:[email protected]#0 1:[email protected]#0
PUNCH ; [joint] 0:[email protected]#0
SUBTREE () 0:[email protected]#0 0:[email protected]#0
IDENT future 1:[email protected]#0
PUNCH . [alone] 1:[email protected]#0
IDENT await 1:[email protected]#0
PUNCH ; [joint] 0:[email protected]#0
SUBTREE () 0:[email protected]#0 0:[email protected]#0
IDENT break 1:[email protected]#0
PUNCH ' [joint] 1:[email protected]#0
IDENT foo 1:[email protected]#0
IDENT bar 1:[email protected]#0
PUNCH ; [alone] 0:[email protected]#0

4;
"literal";
(funcall());
(future.await);
(break 'foo bar);"#]],
);
check(
Edition::Edition2024,
Edition::Edition2024,
r#"
($($e:expr_2021),* $(,)?) => {
$($e);* ;
};
"#,
r#"
_,
"#,
expect![[r#"
ExpandError {
inner: (
1:[email protected]#0,
NoMatchingRule,
),
}

SUBTREE $$ 1:[email protected]#0 1:[email protected]#0
PUNCH ; [alone] 0:[email protected]#0

;"#]],
);
}