Skip to content

Commit 5eafab3

Browse files
committed
feat(expand): emit note for doc comment in macro matcher
1 parent c927743 commit 5eafab3

File tree

5 files changed

+119
-12
lines changed

5 files changed

+119
-12
lines changed

compiler/rustc_expand/src/mbe/macro_rules.rs

+35-11
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,40 @@ fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree)
628628
// after parsing/expansion. we can report every error in every macro this way.
629629
}
630630

631+
fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool {
632+
if seq.separator.is_some() {
633+
false
634+
} else {
635+
let mut is_empty = true;
636+
let mut iter = seq.tts.iter().peekable();
637+
while let Some(tt) = iter.next() {
638+
match tt {
639+
mbe::TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => {}
640+
mbe::TokenTree::Token(t @ Token { kind: DocComment(..), .. }) => {
641+
let mut now = t;
642+
while let Some(&mbe::TokenTree::Token(
643+
next @ Token { kind: DocComment(..), .. },
644+
)) = iter.peek()
645+
{
646+
now = next;
647+
iter.next();
648+
}
649+
let span = t.span.to(now.span);
650+
sess.span_diagnostic.span_note_without_error(
651+
span,
652+
"doc comments are ignored in matcher position",
653+
);
654+
}
655+
mbe::TokenTree::Sequence(_, sub_seq)
656+
if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
657+
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne) => {}
658+
_ => is_empty = false,
659+
}
660+
}
661+
is_empty
662+
}
663+
}
664+
631665
/// Checks that the lhs contains no repetition which could match an empty token
632666
/// tree, because then the matcher would hang indefinitely.
633667
fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
@@ -644,17 +678,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
644678
}
645679
}
646680
TokenTree::Sequence(span, seq) => {
647-
if seq.separator.is_none()
648-
&& seq.tts.iter().all(|seq_tt| match seq_tt {
649-
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
650-
TokenTree::Token(t) => matches!(t, Token { kind: DocComment(..), .. }),
651-
TokenTree::Sequence(_, sub_seq) => {
652-
sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
653-
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
654-
}
655-
_ => false,
656-
})
657-
{
681+
if is_empty_token_tree(sess, seq) {
658682
let sp = span.entire();
659683
sess.span_diagnostic.span_err(sp, "repetition matches empty token tree");
660684
return false;

tests/ui/macros/issue-112342-1.rs

+13
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,17 @@ macro_rules! m3 {
3333

3434
m3! {}
3535

36+
37+
macro_rules! m4 {
38+
(
39+
$(
40+
///
41+
///
42+
)*
43+
//~^^^^ERROR repetition matches empty token tree
44+
) => {};
45+
}
46+
47+
m4! {}
48+
3649
fn main() {}

tests/ui/macros/issue-112342-1.stderr

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
note: doc comments are ignored in matcher position
2+
--> $DIR/issue-112342-1.rs:6:13
3+
|
4+
LL | ///
5+
| ^^^
6+
17
error: repetition matches empty token tree
28
--> $DIR/issue-112342-1.rs:5:10
39
|
@@ -7,6 +13,12 @@ LL | | ///
713
LL | | )*
814
| |_________^
915

16+
note: doc comments are ignored in matcher position
17+
--> $DIR/issue-112342-1.rs:17:13
18+
|
19+
LL | ///
20+
| ^^^
21+
1022
error: repetition matches empty token tree
1123
--> $DIR/issue-112342-1.rs:16:10
1224
|
@@ -16,6 +28,12 @@ LL | | ///
1628
LL | | )+
1729
| |_________^
1830

31+
note: doc comments are ignored in matcher position
32+
--> $DIR/issue-112342-1.rs:28:13
33+
|
34+
LL | ///
35+
| ^^^
36+
1937
error: repetition matches empty token tree
2038
--> $DIR/issue-112342-1.rs:27:10
2139
|
@@ -25,5 +43,22 @@ LL | | ///
2543
LL | | )?
2644
| |_________^
2745

28-
error: aborting due to 3 previous errors
46+
note: doc comments are ignored in matcher position
47+
--> $DIR/issue-112342-1.rs:40:13
48+
|
49+
LL | / ///
50+
LL | | ///
51+
| |_______________^
52+
53+
error: repetition matches empty token tree
54+
--> $DIR/issue-112342-1.rs:39:10
55+
|
56+
LL | $(
57+
| __________^
58+
LL | | ///
59+
LL | | ///
60+
LL | | )*
61+
| |_________^
62+
63+
error: aborting due to 4 previous errors
2964

tests/ui/macros/issue-112342-2.rs

+11
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,15 @@ macro_rules! m2 {
2525

2626
m2! {}
2727

28+
macro_rules! m3 {
29+
(
30+
$(
31+
///
32+
$tt: tt,
33+
)*
34+
) => {};
35+
}
36+
37+
m3! {}
38+
2839
fn main() {}

tests/ui/macros/issue-112342-2.stderr

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
note: doc comments are ignored in matcher position
2+
--> $DIR/issue-112342-2.rs:8:13
3+
|
4+
LL | ///
5+
| ^^^
6+
7+
note: doc comments are ignored in matcher position
8+
--> $DIR/issue-112342-2.rs:19:13
9+
|
10+
LL | ///
11+
| ^^^
12+
13+
note: doc comments are ignored in matcher position
14+
--> $DIR/issue-112342-2.rs:21:13
15+
|
16+
LL | ///
17+
| ^^^
18+
19+
note: doc comments are ignored in matcher position
20+
--> $DIR/issue-112342-2.rs:31:13
21+
|
22+
LL | ///
23+
| ^^^
24+

0 commit comments

Comments
 (0)