rust-lang / rust-lang/rfcs

Macro pattern matching with repeated terms

Open
#2,222 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

T-lang
Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

Unless I've missed some workaround, a macro-by-example definition is unable to check any of its inputs for equality. That means that such a macro cannot perform any reasoning about its inputs beyond their form and whether they are equal to the given constants. Most of the time, this restriction is not a problem, or at least can be worked around, but there are some cases where it forces the programmer to write a procedural macro instead. I've made an example of such a case on the playground, where the goal is to map an element from one list of tokens to the corresponding element in another list. Another example is a hypothetical if_eq!(a, b, c, d), which would return c if a and b were equal and d if not.

I propose allowing terms in the macro's pattern to be repeated as often as needed in order to specify that different parts of the pattern should be identical. It might look like this (taken from the playground example above, in case that ever changes):

($token:tt, ($token $(, $others_map1:tt)*), ($result:tt $(, $others_map2:tt)*)) => {
    $result
};

Notice that $token appears twice in the pattern. I would disallow adding another :tt after the first appearance, in order to avoid a conflict and to make sure the programmer actually meant to say that those tokens should be equal.

The same rules for lock-step evaluation of tokens would apply here as when the tokens appear on the right-hand side of the => operator. If $token:tt in the above example were replaced with $($token:tt)*, then the second $token would have to be some variation on $($token)*.

As for what exactly constitutes equality, I think it should be exact: numeric literals should be represented with the same strings (so 5, 5i32, and 5i64 would all be different), identifiers should have the same contexts as well as the same names, etc. But I may be missing something that could be a useful about inexact equality checking, so comments on this part are especially welcome.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked Rust playground example and the macro-by-example behavior described in the issue. Investigate how repeated pattern terms and repeated metavariables are currently parsed and matched, then define exact token equality and repetition rules. Done means the proposed matching behavior is specified and supported without requiring a procedural macro.

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
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.