Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I provide optional generics as macro_rules arguments?

I want to use macro_rules to create an implementation for a trait. The types should be given as macro arguments. However, some of those types may contain lifetimes, so I need them. I also have a generic type from inside the macro. The result should look like

impl<T> Foo<T> for MyType { .. }
// Or with lifetime:
impl<'a, 'b, T> Foo<T> for LifetimeType<'a, 'b> { .. }

How do I structure the macro and how do I call it?

like image 771
llogiq Avatar asked Oct 15 '25 18:10

llogiq


1 Answers

You can use the lifetime specifier to match lifetimes in macro arguments:

trait Foo{}

macro_rules!impl_foo {
    ($($l:lifetime),*; $t:tt) => { impl<$($l),*> Foo for $t<$($l),*> {} };
    ($t:ty) => { impl Foo for $t {} };
}

And call it like this:

impl_foo!(A);
impl_foo!('a, 'b; B);

Playground

Note that the only place I could find that talked of the lifetime specifier for captures is the associated RFC. It is in particular conspicuously missing from The little book of Rust macros, even though it was merged in 2016…

like image 121
Jmb Avatar answered Oct 18 '25 16:10

Jmb