From c927743b7b7bd382836dcce2d1140a7e829dc3d0 Mon Sep 17 00:00:00 2001 From: bohan Date: Tue, 6 Jun 2023 23:11:08 +0800 Subject: [PATCH] fix(expand): prevent infinity loop in macro containing only "///" --- compiler/rustc_expand/src/mbe/macro_parser.rs | 1 + compiler/rustc_expand/src/mbe/macro_rules.rs | 1 + tests/ui/macros/issue-112342-1.rs | 36 +++++++++++++++++++ tests/ui/macros/issue-112342-1.stderr | 29 +++++++++++++++ tests/ui/macros/issue-112342-2.rs | 28 +++++++++++++++ 5 files changed, 95 insertions(+) create mode 100644 tests/ui/macros/issue-112342-1.rs create mode 100644 tests/ui/macros/issue-112342-1.stderr create mode 100644 tests/ui/macros/issue-112342-2.rs diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 1c222fb4a89..f0e67cfd50e 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -249,6 +249,7 @@ pub(super) fn compute_locs(matcher: &[TokenTree]) -> Vec { } /// A single matcher position, representing the state of matching. +#[derive(Debug)] struct MatcherPos { /// The index into `TtParser::locs`, which represents the "dot". idx: usize, diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index e4c65a2049b..576d636d489 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -647,6 +647,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { 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 diff --git a/tests/ui/macros/issue-112342-1.rs b/tests/ui/macros/issue-112342-1.rs new file mode 100644 index 00000000000..14fe9bbd97a --- /dev/null +++ b/tests/ui/macros/issue-112342-1.rs @@ -0,0 +1,36 @@ +// same as #95267, ignore doc comment although it's a bug. + +macro_rules! m1 { + ( + $( + /// + )* + //~^^^ERROR repetition matches empty token tree + ) => {}; +} + +m1! {} + +macro_rules! m2 { + ( + $( + /// + )+ + //~^^^ERROR repetition matches empty token tree + ) => {}; +} + +m2! {} + +macro_rules! m3 { + ( + $( + /// + )? + //~^^^ERROR repetition matches empty token tree + ) => {}; +} + +m3! {} + +fn main() {} diff --git a/tests/ui/macros/issue-112342-1.stderr b/tests/ui/macros/issue-112342-1.stderr new file mode 100644 index 00000000000..1ba7c0ffd3b --- /dev/null +++ b/tests/ui/macros/issue-112342-1.stderr @@ -0,0 +1,29 @@ +error: repetition matches empty token tree + --> $DIR/issue-112342-1.rs:5:10 + | +LL | $( + | __________^ +LL | | /// +LL | | )* + | |_________^ + +error: repetition matches empty token tree + --> $DIR/issue-112342-1.rs:16:10 + | +LL | $( + | __________^ +LL | | /// +LL | | )+ + | |_________^ + +error: repetition matches empty token tree + --> $DIR/issue-112342-1.rs:27:10 + | +LL | $( + | __________^ +LL | | /// +LL | | )? + | |_________^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/macros/issue-112342-2.rs b/tests/ui/macros/issue-112342-2.rs new file mode 100644 index 00000000000..1e1d953fa52 --- /dev/null +++ b/tests/ui/macros/issue-112342-2.rs @@ -0,0 +1,28 @@ +// check-pass + +// same as #95267, ignore doc comment although it's a bug. + +macro_rules! m1 { + ( + $( + /// + $expr: expr, + )* + ) => {}; +} + +m1! {} + +macro_rules! m2 { + ( + $( + /// + $expr: expr, + /// + )* + ) => {}; +} + +m2! {} + +fn main() {}