mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
Auto merge of #13800 - lowr:fix/mbe-expr-backwards-compat, r=Veykril
fix: don't let mbe expr fragments match let exprs and inline consts Fixes #11729 `expr` fragment in mbe should not match let expressions and inline consts for backwards compatibility. See rust-lang/rust#86730 for details. This patch is porting [this logic in rustc](f0c4da4998/compiler/rustc_parse/src/parser/nonterminal.rs (L28-L34)
) (which is called [here in rustc's mbe engine](f0c4da4998/compiler/rustc_expand/src/mbe/macro_parser.rs (L576)
)) to our mbe engine.
This commit is contained in:
commit
ccbf8fef9b
@ -136,3 +136,52 @@ macro_rules! m { ($($i:ident)? $vis:vis) => () }
|
|||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For this test and the one below, see rust-lang/rust#86730.
|
||||||
|
#[test]
|
||||||
|
fn expr_dont_match_let_expr() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
($e:expr) => { $e }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
foo!(let a = 3);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
($e:expr) => { $e }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
/* error: no rule matches input tokens */missing;
|
||||||
|
}
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expr_dont_match_inline_const() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
($e:expr) => { $e }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
foo!(const { 3 });
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
($e:expr) => { $e }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
/* error: no rule matches input tokens */missing;
|
||||||
|
}
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -698,12 +698,16 @@ fn match_meta_var(kind: MetaVarKind, input: &mut TtIter<'_>) -> ExpandResult<Opt
|
|||||||
MetaVarKind::Item => parser::PrefixEntryPoint::Item,
|
MetaVarKind::Item => parser::PrefixEntryPoint::Item,
|
||||||
MetaVarKind::Vis => parser::PrefixEntryPoint::Vis,
|
MetaVarKind::Vis => parser::PrefixEntryPoint::Vis,
|
||||||
MetaVarKind::Expr => {
|
MetaVarKind::Expr => {
|
||||||
// `expr` should not match underscores.
|
// `expr` should not match underscores, let expressions, or inline const. The latter
|
||||||
|
// two are for [backwards compatibility][0].
|
||||||
// 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][0].
|
// rustc [explicitly checks the next token][1].
|
||||||
// [0]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
|
// [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) {
|
match input.peek_n(0) {
|
||||||
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) if it.text == "_" => {
|
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it)))
|
||||||
|
if it.text == "_" || it.text == "let" || it.text == "const" =>
|
||||||
|
{
|
||||||
return ExpandResult::only_err(ExpandError::NoMatchingRule)
|
return ExpandResult::only_err(ExpandError::NoMatchingRule)
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
Loading…
Reference in New Issue
Block a user