Note: I'm not sure whether you should do this, but here's a way to anyway. (Feels hacky to me, and that may be because I don't know how to make a better macro.)
Homogeneous tuples (T, T)
The way you've described it:
impl<T> Foo for (T, T) where T: Foo
Here, the entire tuple must be homogeneous (i.e. (MyType, MyType2).do_something()
will not work because of monomorphization).
This raises a flag because tuples are for heterogeneous data.
If implementing the trait only one homogeneous tuples is still what you want, we can implement a macro the way the standard library does to implement traits for varied length tuples, with some modifications. (Click src
on the right of an impl
to see it's source.)
macro_rules! replace_expr {
($_t:tt $sub:ty) => {$sub};
}
macro_rules! tuple_impls {
( $( $name:ident )+ ) => {
impl<T: Foo> Foo for ($(replace_expr!(($name) T),)+)
{
fn do_something(self) -> Self {
let ($($name,)+) = self;
($($name.do_something(),)+)
}
}
};
}
tuple_impls! { A }
tuple_impls! { A B }
tuple_impls! { A B C }
tuple_impls! { A B C D }
tuple_impls! { A B C D E }
tuple_impls! { A B C D E F }
tuple_impls! { A B C D E F G }
tuple_impls! { A B C D E F G H }
tuple_impls! { A B C D E F G H I }
tuple_impls! { A B C D E F G H I J }
tuple_impls! { A B C D E F G H I J K }
tuple_impls! { A B C D E F G H I J K L }
Playground
Heterogeneous tuples (T1, T2)
If you're okay with (MyType, MyType2).do_something()
working (where both implement the Foo
trait), you can try this simpler macro:
macro_rules! tuple_impls {
( $( $name:ident )+ ) => {
impl<$($name: Foo),+> Foo for ($($name,)+)
{
fn do_something(self) -> Self {
let ($($name,)+) = self;
($($name.do_something(),)+)
}
}
};
}
tuple_impls! { A }
tuple_impls! { A B }
tuple_impls! { A B C }
tuple_impls! { A B C D }
tuple_impls! { A B C D E }
tuple_impls! { A B C D E F }
tuple_impls! { A B C D E F G }
tuple_impls! { A B C D E F G H }
tuple_impls! { A B C D E F G H I }
tuple_impls! { A B C D E F G H I J }
tuple_impls! { A B C D E F G H I J K }
tuple_impls! { A B C D E F G H I J K L }
Playground