`macro_rules!` metavariable for generic

I was working on a macro which implements a trait for a type, which I wanted to be a declarative macro, but this doesn't work if the type has generic arguments that I want to use as generic.

Toy example of what I want to do

This case is simple enough that I could match the generics with $( <$param:tt> )?, but more generally you can produce a knot of lifetimes, types, and const values with potentially quite complicated constraints on them, that is very difficult (maybe impossible?) to parse properly.

So it got me thinking: is there any reason why there isn't a :generic metavariable to use in declarative macros? I looked up and saw a couple of discussions on here that fizzled out without anything coming of them, and nothing in issue tickets or RFCs on GitHub, though it's possible I missed something.

4 Likes

The usual hack for this is to adjust the grammar you give to the macro a bit, and match essentially for [$($For:tt)*] where [$($Where:tt)*], with just declarations in the former with any and all bounds in the latter.

1 Like

I've definitely wanted this on multiple occasions, and would fully support an RFC proposing it.

4 Likes

Another metavariable type that I've wanted a few times is :bound, for opaquely taking lifetime or trait bounds.

I have written a few macro_rules! that need to manually parse generic parameter lists, and parsing bounds is the hardest part of it. Parsing generic parameters opaquely would not have been useful for me because I needed to use them in both the generic parameter list and as generic arguments.

2 Likes

I made this into an RFC: Fragment Specifiers for Generic Arguments by JarredAllen · Pull Request #3442 · rust-lang/rfcs · GitHub

Also thanks to @matt1985 for suggesting taking pieces of the generic parameter list and making them into their own pieces, I've incorporated that idea into the RFC also,

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.