Skip to content

Commit e027ac0

Browse files
committed
fix: don't let mbe expr fragments match let exprs and inline consts
1 parent ffedfc6 commit e027ac0

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

Diff for: crates/hir-def/src/macro_expansion_tests/mbe/matching.rs

+49
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,52 @@ macro_rules! m { ($($i:ident)? $vis:vis) => () }
136136
"#]],
137137
)
138138
}
139+
140+
// For this test and the one below, see rust-lang/rust#86730.
141+
#[test]
142+
fn expr_dont_match_let_expr() {
143+
check(
144+
r#"
145+
macro_rules! foo {
146+
($e:expr) => { $e }
147+
}
148+
149+
fn test() {
150+
foo!(let a = 3);
151+
}
152+
"#,
153+
expect![[r#"
154+
macro_rules! foo {
155+
($e:expr) => { $e }
156+
}
157+
158+
fn test() {
159+
/* error: no rule matches input tokens */missing;
160+
}
161+
"#]],
162+
);
163+
}
164+
165+
#[test]
166+
fn expr_dont_match_inline_const() {
167+
check(
168+
r#"
169+
macro_rules! foo {
170+
($e:expr) => { $e }
171+
}
172+
173+
fn test() {
174+
foo!(const { 3 });
175+
}
176+
"#,
177+
expect![[r#"
178+
macro_rules! foo {
179+
($e:expr) => { $e }
180+
}
181+
182+
fn test() {
183+
/* error: no rule matches input tokens */missing;
184+
}
185+
"#]],
186+
);
187+
}

Diff for: crates/mbe/src/expander/matcher.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -698,12 +698,16 @@ fn match_meta_var(kind: MetaVarKind, input: &mut TtIter<'_>) -> ExpandResult<Opt
698698
MetaVarKind::Item => parser::PrefixEntryPoint::Item,
699699
MetaVarKind::Vis => parser::PrefixEntryPoint::Vis,
700700
MetaVarKind::Expr => {
701-
// `expr` should not match underscores.
701+
// `expr` should not match underscores, let expressions, or inline const. The latter
702+
// two are for [backwards compatibility][0].
702703
// HACK: Macro expansion should not be done using "rollback and try another alternative".
703-
// rustc [explicitly checks the next token][0].
704-
// [0]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
704+
// rustc [explicitly checks the next token][1].
705+
// [0]: https://github.com/rust-lang/rust/issues/86730
706+
// [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
705707
match input.peek_n(0) {
706-
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) if it.text == "_" => {
708+
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it)))
709+
if it.text == "_" || it.text == "let" || it.text == "const" =>
710+
{
707711
return ExpandResult::only_err(ExpandError::NoMatchingRule)
708712
}
709713
_ => {}

0 commit comments

Comments
 (0)