feat(expand): emit note for doc comment in macro matcher
This commit is contained in:
parent
c927743b7b
commit
5eafab30ba
@ -628,6 +628,40 @@ fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree)
|
||||
// after parsing/expansion. we can report every error in every macro this way.
|
||||
}
|
||||
|
||||
fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool {
|
||||
if seq.separator.is_some() {
|
||||
false
|
||||
} else {
|
||||
let mut is_empty = true;
|
||||
let mut iter = seq.tts.iter().peekable();
|
||||
while let Some(tt) = iter.next() {
|
||||
match tt {
|
||||
mbe::TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => {}
|
||||
mbe::TokenTree::Token(t @ Token { kind: DocComment(..), .. }) => {
|
||||
let mut now = t;
|
||||
while let Some(&mbe::TokenTree::Token(
|
||||
next @ Token { kind: DocComment(..), .. },
|
||||
)) = iter.peek()
|
||||
{
|
||||
now = next;
|
||||
iter.next();
|
||||
}
|
||||
let span = t.span.to(now.span);
|
||||
sess.span_diagnostic.span_note_without_error(
|
||||
span,
|
||||
"doc comments are ignored in matcher position",
|
||||
);
|
||||
}
|
||||
mbe::TokenTree::Sequence(_, sub_seq)
|
||||
if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|
||||
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne) => {}
|
||||
_ => is_empty = false,
|
||||
}
|
||||
}
|
||||
is_empty
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that the lhs contains no repetition which could match an empty token
|
||||
/// tree, because then the matcher would hang indefinitely.
|
||||
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 {
|
||||
}
|
||||
}
|
||||
TokenTree::Sequence(span, seq) => {
|
||||
if seq.separator.is_none()
|
||||
&& seq.tts.iter().all(|seq_tt| match seq_tt {
|
||||
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
|
||||
TokenTree::Token(t) => matches!(t, Token { kind: DocComment(..), .. }),
|
||||
TokenTree::Sequence(_, sub_seq) => {
|
||||
sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|
||||
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
{
|
||||
if is_empty_token_tree(sess, seq) {
|
||||
let sp = span.entire();
|
||||
sess.span_diagnostic.span_err(sp, "repetition matches empty token tree");
|
||||
return false;
|
||||
|
@ -33,4 +33,17 @@ macro_rules! m3 {
|
||||
|
||||
m3! {}
|
||||
|
||||
|
||||
macro_rules! m4 {
|
||||
(
|
||||
$(
|
||||
///
|
||||
///
|
||||
)*
|
||||
//~^^^^ERROR repetition matches empty token tree
|
||||
) => {};
|
||||
}
|
||||
|
||||
m4! {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,3 +1,9 @@
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-1.rs:6:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
||||
error: repetition matches empty token tree
|
||||
--> $DIR/issue-112342-1.rs:5:10
|
||||
|
|
||||
@ -7,6 +13,12 @@ LL | | ///
|
||||
LL | | )*
|
||||
| |_________^
|
||||
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-1.rs:17:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
||||
error: repetition matches empty token tree
|
||||
--> $DIR/issue-112342-1.rs:16:10
|
||||
|
|
||||
@ -16,6 +28,12 @@ LL | | ///
|
||||
LL | | )+
|
||||
| |_________^
|
||||
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-1.rs:28:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
||||
error: repetition matches empty token tree
|
||||
--> $DIR/issue-112342-1.rs:27:10
|
||||
|
|
||||
@ -25,5 +43,22 @@ LL | | ///
|
||||
LL | | )?
|
||||
| |_________^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-1.rs:40:13
|
||||
|
|
||||
LL | / ///
|
||||
LL | | ///
|
||||
| |_______________^
|
||||
|
||||
error: repetition matches empty token tree
|
||||
--> $DIR/issue-112342-1.rs:39:10
|
||||
|
|
||||
LL | $(
|
||||
| __________^
|
||||
LL | | ///
|
||||
LL | | ///
|
||||
LL | | )*
|
||||
| |_________^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -25,4 +25,15 @@ macro_rules! m2 {
|
||||
|
||||
m2! {}
|
||||
|
||||
macro_rules! m3 {
|
||||
(
|
||||
$(
|
||||
///
|
||||
$tt: tt,
|
||||
)*
|
||||
) => {};
|
||||
}
|
||||
|
||||
m3! {}
|
||||
|
||||
fn main() {}
|
||||
|
24
tests/ui/macros/issue-112342-2.stderr
Normal file
24
tests/ui/macros/issue-112342-2.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-2.rs:8:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-2.rs:19:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-2.rs:21:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
||||
note: doc comments are ignored in matcher position
|
||||
--> $DIR/issue-112342-2.rs:31:13
|
||||
|
|
||||
LL | ///
|
||||
| ^^^
|
||||
|
Loading…
x
Reference in New Issue
Block a user