Code change:
error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:4:8 </del> <ins> --> $DIR/issue-5067.rs:9:8 </ins> | LL |     ( $()* ) => {}; |        ^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:6:8 </del> <ins> --> $DIR/issue-5067.rs:11:8 </ins> | LL |     ( $()+ ) => {}; |        ^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:12:9 </del> <ins> --> $DIR/issue-5067.rs:13:8 | LL |     ( $()? ) => {}; |        ^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:18:9 </ins> | LL |     ( [$()*] ) => {}; |         ^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:14:9 </del> <ins> --> $DIR/issue-5067.rs:20:9 </ins> | LL |     ( [$()+] ) => {}; |         ^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:20:8 </del> <ins> --> $DIR/issue-5067.rs:22:9 | LL |     ( [$()?] ) => {}; |         ^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:27:8 </ins> | LL |     ( $($()* $(),* $(a)* $(a),* )* ) => {}; |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:22:8 </del> <ins> --> $DIR/issue-5067.rs:29:8 </ins> | LL |     ( $($()* $(),* $(a)* $(a),* )+ ) => {}; |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:28:12 </del> <ins> --> $DIR/issue-5067.rs:31:8 | LL |     ( $($()* $(),* $(a)* $(a),* )? ) => {}; |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:33:8 | LL |     ( $($()? $(),* $(a)? $(a),* )* ) => {}; |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:35:8 | LL |     ( $($()? $(),* $(a)? $(a),* )+ ) => {}; |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:37:8 | LL |     ( $($()? $(),* $(a)? $(a),* )? ) => {}; |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:47:12 </ins> | LL |     ( $(a $()+)* ) => {}; |            ^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:30:12 </del> <ins> --> $DIR/issue-5067.rs:49:12 </ins> | LL |     ( $(a $()*)+ ) => {}; |            ^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:38:18 </del> <ins> --> $DIR/issue-5067.rs:51:12 | LL |     ( $(a $()+)? ) => {}; |            ^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:53:12 | LL |     ( $(a $()?)+ ) => {}; |            ^^ error: repetition matches empty token tree --> $DIR/issue-5067.rs:60:18 </ins> | LL |     (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]); |                  ^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree <del> --> $DIR/issue-5067.rs:50:8 </del> <ins> --> $DIR/issue-5067.rs:71:8 </ins> | <del> LL |     ( $()* ) => {} </del> <ins> LL |     ( $()* ) => {}; </ins> |        ^^ <del> error: aborting due to 10 previous errors </del> <ins> error: aborting due to 18 previous errors </ins>

Related discussion:
text: The following code will cause the compiler to fail: Playground link: It should error that the inner matcher can match an empty string and reject it, just as it does if is used in place of .
The fix should be very easy, since this was already fixed for repetitions in (original bug: ): Looks like just needs to be checked against , too.
cc
Note that with on the outside, this errors properly, although with inconsistent error messages: if the inner repetition uses only, the error is "repetition matches empty token tree", but it seems that if any of the repetitions are , then the error is "multiple successful parses".
The behaviour in my previous comment is because the check for "repetition matches empty token tree" is done at definition time, but does not catch ; this is caught at expansion time however. Ideally all of this will be moved to definition time and the expansion-time check should probably be a) corrected to address the first comment and b) possibly become an ICE, since it should never be encountered since the RFC 550 rules should eliminate all ambiguity at definition time?
Hmm... I don't really remember how most of this code works... Just grepping, but it looks like there are a couple of other places we might want to look at:
I've opened