Auto merge of #18137 - ShoyuVanilla:expr-2021, r=Veykril
feat: Implement `expr_2021` Resolves #18062
This commit is contained in:
commit
44f8545b3c
@ -146,7 +146,7 @@ fn invocation_fixtures(
|
|||||||
Some(MetaVarKind::Pat) => token_trees.push(make_ident("foo")),
|
Some(MetaVarKind::Pat) => token_trees.push(make_ident("foo")),
|
||||||
Some(MetaVarKind::Path) => 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::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) => {
|
Some(MetaVarKind::Lifetime) => {
|
||||||
token_trees.push(make_punct('\''));
|
token_trees.push(make_punct('\''));
|
||||||
token_trees.push(make_ident("a"));
|
token_trees.push(make_ident("a"));
|
||||||
|
@ -69,7 +69,7 @@ use tt::{iter::TtIter, DelimSpan};
|
|||||||
use crate::{
|
use crate::{
|
||||||
expander::{Binding, Bindings, ExpandResult, Fragment},
|
expander::{Binding, Bindings, ExpandResult, Fragment},
|
||||||
expect_fragment,
|
expect_fragment,
|
||||||
parser::{MetaVarKind, Op, RepeatKind, Separator},
|
parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator},
|
||||||
ExpandError, ExpandErrorKind, MetaTemplate, ValueResult,
|
ExpandError, ExpandErrorKind, MetaTemplate, ValueResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -769,23 +769,28 @@ fn match_meta_var(
|
|||||||
it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
|
it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
MetaVarKind::Expr => {
|
MetaVarKind::Expr(expr) => {
|
||||||
// `expr` should not match underscores, let expressions, or inline const. The latter
|
// `expr_2021` should not match underscores, let expressions, or inline const.
|
||||||
// two are for [backwards compatibility][0].
|
// 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".
|
// HACK: Macro expansion should not be done using "rollback and try another alternative".
|
||||||
// rustc [explicitly checks the next token][1].
|
// rustc [explicitly checks the next token][1].
|
||||||
// [0]: https://github.com/rust-lang/rust/issues/86730
|
// [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
|
// [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
|
||||||
match input.peek_n(0) {
|
match input.peek_n(0) {
|
||||||
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it)))
|
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) => {
|
||||||
if it.sym == sym::underscore
|
let is_err = if matches!(expr, ExprKind::Expr2021) {
|
||||||
|| it.sym == sym::let_
|
it.sym == sym::underscore || it.sym == sym::let_ || it.sym == sym::const_
|
||||||
|| it.sym == sym::const_ =>
|
} else {
|
||||||
{
|
it.sym == sym::let_
|
||||||
return ExpandResult::only_err(ExpandError::new(
|
};
|
||||||
it.span,
|
if is_err {
|
||||||
ExpandErrorKind::NoMatchingRule,
|
return ExpandResult::only_err(ExpandError::new(
|
||||||
))
|
it.span,
|
||||||
|
ExpandErrorKind::NoMatchingRule,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
@ -97,7 +97,7 @@ impl Bindings {
|
|||||||
| MetaVarKind::Ty
|
| MetaVarKind::Ty
|
||||||
| MetaVarKind::Pat
|
| MetaVarKind::Pat
|
||||||
| MetaVarKind::PatParam
|
| MetaVarKind::PatParam
|
||||||
| MetaVarKind::Expr
|
| MetaVarKind::Expr(_)
|
||||||
| MetaVarKind::Ident => {
|
| MetaVarKind::Ident => {
|
||||||
Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
||||||
sym: sym::missing.clone(),
|
sym: sym::missing.clone(),
|
||||||
|
@ -105,6 +105,16 @@ pub(crate) enum RepeatKind {
|
|||||||
ZeroOrOne,
|
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)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum MetaVarKind {
|
pub(crate) enum MetaVarKind {
|
||||||
Path,
|
Path,
|
||||||
@ -116,7 +126,7 @@ pub(crate) enum MetaVarKind {
|
|||||||
Meta,
|
Meta,
|
||||||
Item,
|
Item,
|
||||||
Vis,
|
Vis,
|
||||||
Expr,
|
Expr(ExprKind),
|
||||||
Ident,
|
Ident,
|
||||||
Tt,
|
Tt,
|
||||||
Lifetime,
|
Lifetime,
|
||||||
@ -277,17 +287,27 @@ fn eat_fragment_kind(
|
|||||||
let kind = match ident.sym.as_str() {
|
let kind = match ident.sym.as_str() {
|
||||||
"path" => MetaVarKind::Path,
|
"path" => MetaVarKind::Path,
|
||||||
"ty" => MetaVarKind::Ty,
|
"ty" => MetaVarKind::Ty,
|
||||||
"pat" => match edition(ident.span.ctx) {
|
"pat" => {
|
||||||
Edition::Edition2015 | Edition::Edition2018 => MetaVarKind::PatParam,
|
if edition(ident.span.ctx).at_least_2021() {
|
||||||
Edition::Edition2021 | Edition::Edition2024 => MetaVarKind::Pat,
|
MetaVarKind::Pat
|
||||||
},
|
} else {
|
||||||
|
MetaVarKind::PatParam
|
||||||
|
}
|
||||||
|
}
|
||||||
"pat_param" => MetaVarKind::PatParam,
|
"pat_param" => MetaVarKind::PatParam,
|
||||||
"stmt" => MetaVarKind::Stmt,
|
"stmt" => MetaVarKind::Stmt,
|
||||||
"block" => MetaVarKind::Block,
|
"block" => MetaVarKind::Block,
|
||||||
"meta" => MetaVarKind::Meta,
|
"meta" => MetaVarKind::Meta,
|
||||||
"item" => MetaVarKind::Item,
|
"item" => MetaVarKind::Item,
|
||||||
"vis" => MetaVarKind::Vis,
|
"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,
|
"ident" => MetaVarKind::Ident,
|
||||||
"tt" => MetaVarKind::Tt,
|
"tt" => MetaVarKind::Tt,
|
||||||
"lifetime" => MetaVarKind::Lifetime,
|
"lifetime" => MetaVarKind::Lifetime,
|
||||||
|
@ -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:0@0..25#0 1:0@0..25#0
|
||||||
|
IDENT _ 1:0@5..6#0
|
||||||
|
PUNCH ; [joint] 0:0@36..37#0
|
||||||
|
SUBTREE () 0:0@34..35#0 0:0@34..35#0
|
||||||
|
IDENT const 1:0@12..17#0
|
||||||
|
SUBTREE {} 1:0@18..19#0 1:0@22..23#0
|
||||||
|
LITERAL Integer 1 1:0@20..21#0
|
||||||
|
PUNCH ; [alone] 0:0@39..40#0
|
||||||
|
|
||||||
|
_;
|
||||||
|
(const {
|
||||||
|
1
|
||||||
|
});"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
Edition::Edition2021,
|
||||||
|
Edition::Edition2024,
|
||||||
|
r#"
|
||||||
|
($($e:expr),* $(,)?) => {
|
||||||
|
$($e);* ;
|
||||||
|
};
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
_,
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
ExpandError {
|
||||||
|
inner: (
|
||||||
|
1:0@5..6#0,
|
||||||
|
NoMatchingRule,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBTREE $$ 1:0@0..8#0 1:0@0..8#0
|
||||||
|
PUNCH ; [alone] 0:0@39..40#0
|
||||||
|
|
||||||
|
;"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
Edition::Edition2021,
|
||||||
|
Edition::Edition2024,
|
||||||
|
r#"
|
||||||
|
($($e:expr),* $(,)?) => {
|
||||||
|
$($e);* ;
|
||||||
|
};
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
const { 1 },
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
ExpandError {
|
||||||
|
inner: (
|
||||||
|
1:0@5..10#0,
|
||||||
|
NoMatchingRule,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBTREE $$ 1:0@0..18#0 1:0@0..18#0
|
||||||
|
PUNCH ; [alone] 0:0@39..40#0
|
||||||
|
|
||||||
|
;"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
Edition::Edition2024,
|
||||||
|
Edition::Edition2024,
|
||||||
|
r#"
|
||||||
|
($($e:expr_2021),* $(,)?) => {
|
||||||
|
$($e);* ;
|
||||||
|
};
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
4,
|
||||||
|
"literal",
|
||||||
|
funcall(),
|
||||||
|
future.await,
|
||||||
|
break 'foo bar,
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
SUBTREE $$ 1:0@0..76#0 1:0@0..76#0
|
||||||
|
LITERAL Integer 4 1:0@5..6#0
|
||||||
|
PUNCH ; [joint] 0:0@41..42#0
|
||||||
|
LITERAL Str literal 1:0@12..21#0
|
||||||
|
PUNCH ; [joint] 0:0@41..42#0
|
||||||
|
SUBTREE () 0:0@39..40#0 0:0@39..40#0
|
||||||
|
IDENT funcall 1:0@27..34#0
|
||||||
|
SUBTREE () 1:0@34..35#0 1:0@35..36#0
|
||||||
|
PUNCH ; [joint] 0:0@41..42#0
|
||||||
|
SUBTREE () 0:0@39..40#0 0:0@39..40#0
|
||||||
|
IDENT future 1:0@42..48#0
|
||||||
|
PUNCH . [alone] 1:0@48..49#0
|
||||||
|
IDENT await 1:0@49..54#0
|
||||||
|
PUNCH ; [joint] 0:0@41..42#0
|
||||||
|
SUBTREE () 0:0@39..40#0 0:0@39..40#0
|
||||||
|
IDENT break 1:0@60..65#0
|
||||||
|
PUNCH ' [joint] 1:0@66..67#0
|
||||||
|
IDENT foo 1:0@67..70#0
|
||||||
|
IDENT bar 1:0@71..74#0
|
||||||
|
PUNCH ; [alone] 0:0@44..45#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:0@5..6#0,
|
||||||
|
NoMatchingRule,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBTREE $$ 1:0@0..8#0 1:0@0..8#0
|
||||||
|
PUNCH ; [alone] 0:0@44..45#0
|
||||||
|
|
||||||
|
;"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user