I'm trying to write a macro that will output trait implementations for tuples of different sizes with generic constraints. I've simplified my case to the essentials (This is made to bind functions of unknown signature to a context, from which the arguments would be taken for the function invocation).
Given:
trait TestTrait<T, U>
{
fn func(&self, _:T) -> U;
}
trait OtherTrait<T> {}
I want to get:
impl<Func, T, P1, P2, ...> TestTrait<T, (P1, P2, ...)> for Func
where
Func : Fn((P1, P2, ...)) -> T,
T : OtherTrait<P1> + OtherTrait<P2> + ...
{
fn func(&self, _:T) -> (P1, P2, ...)
{
unimplemented!()
}
}
I wrote a macro for that, but a nested macro is not expanded:
macro_rules! constraint {
( $head:ident, $( $tail:ident, )* ) => {
+ OtherTrait<$head> constraint!($tail)
};
() => {};
}
macro_rules! test {
( $head:ident, $( $tail:ident, )* ) => {
impl<Func, T, $head, $( $tail ),* > TestTrait<T, $head, ( $( $tail ),* )> for Func
where
Func : Fn(( $head, $( $tail ),* )) -> T,
T : constraint!($head, $( $tail ),* )
// ^ expected one of `(`, `+`, `,`, `::`, `<`, or `{`, found `!`
{
fn func(&self, _:T) -> ( $head, $( $tail )*, )
{
unimplemented!()
}
}
};
() => {};
}
test!(P1, P2, P3, );
I also tried including T :
part in the macro and writing a list of T : OtherTrait<T?>,
but got other errors. Is it impossible to do that or am I missing something?