I am trying to implement variadics for fun


#1

The last few days I was thinking if it could be possible to implement variadics in Rust and today I sat down and tried to implement it.

It should be nothing more than a small fun project and I uploaded it on github https://github.com/MaikKlein/variadic

The code is small enough for the playground

Shortly afterwards I discovered a flaw

fn debug_print<T, Args: Variadic<T>>(args: Args)
    where T: std::fmt::Debug
{
    if let (Some(front), rest) = args.pop() {
        println!("{:?}", front);
        debug_print(rest);
    }
}

This doesn’t work if I call debug_print with different types. I know that I probably push the type system too much but the error messages are getting a bit cryptic

error[E0277]: the trait bound `VarArgs2<{integer}, {float}>: Variadic<_>` is not satisfied
  --> <anon>:58:5
   |
58 |     debug_print(VarArgs2(1, 1.0));
   |     ^^^^^^^^^^^ trait `VarArgs2<{integer}, {float}>: Variadic<_>` not satisfied
   |
   = help: the following implementations were found:
   = help:   <VarArgs2<T, A> as Variadic<T, A>>
   = note: required by `debug_print`

The problem is Variadic<_>, which is not very helpful. Maybe any of you know what is going on?


#2

The reason it doesn’t work is that you have Args: Variadic<T> bound on the debug_print function, which by your definition is equal to Args: Variadic<T, T, T, T>, which is not implemented by VarArgs2<{integer}, {float}>, since they are certainly a different types. The quick fix is to change the definition to debug_print<A, B, C, D, Args: Variadic<A, B, C, D>> ....

Regarding the compiler error, my guess would be that Variadic<_> means just Variadic<T> bound (and since the name of the parameter is not important, it’s omitted).