macro_rules: no repetition and no tt fragment, so a variadic macro cannot be written
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 14
- Forks
- 2
- Avg merge
- 13h 13m
- Merged PRs (30d)
- 70
Description
What is missing
A macro_rules matcher cannot describe a list. Two limits together cause this.
No repetition operator. $(...),* is not supported:
macro_rules count { ($($x : expr),*) => {
0
}; }
fn main() -> i32 {
return count!(1, 2, 3);
}
Macro expansion failed: No matching rule found for macro count
Three fragment kinds. src/parser/macro_expand.rs:189 accepts expr, ty, and ident. There
is no tt, so a rule cannot capture an arbitrary token and pass the rest along, which is how a
recursive macro walks a list.
A macro can take a fixed number of arguments, and macros can nest and recurse -- item-position
expansion drains a worklist with a 64-round cap. What cannot be written is a rule whose shape
depends on how many arguments arrived.
Why it matters
vec! is the proof. It accepts any number of elements, and it is hardcoded in the expander
(src/parser/macro_expand.rs:538) rather than written in the macro language. A user cannot write
their own vec!, or any variadic builder, or a println!-shaped macro over a list of arguments.
It also closes the last route to compile-time repetition. Recursion through the const evaluator has
its own blockers (#560), const generic recursion does not parse (#564), and a macro that decomposes
a list one element at a time needs the two things above.
What needs to exist
- Repetition in matchers and in transcribers:
$( ... )sep*and$( ... )sep+, with the captured
fragments bound per repetition and expanded in the transcriber. - A
ttfragment kind, so a rule can capture one token tree and recurse on the remainder. - A recursion limit with a message, which item-position expansion already has and which the
expression-position path should share.
Once these exist, vec! should move out of the expander and into the macro language, as the test
that they are enough.
Tests to add
- A user-written variadic macro over zero, one, and several arguments.
- A recursive macro that consumes a list one
ttat a time and terminates on the empty rule. - A macro whose expansion depends on the argument count, so a rule matching the wrong arity goes
red. - A fail fixture for a macro that recurses without terminating, checking the message.
Related: #560, #564.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/parser/macro_expand.rs, especially the fragment handling at line 189, the hardcoded vec! expansion around line 538, and the existing item-position worklist and recursion limit. Add the requested repetition, tt handling, expression-position limit behavior, and tests for empty and variadic inputs, recursive termination, arity mismatch, and nontermination diagnostics; done includes moving vec! into the macro language.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100