I am trying to generate a compile-time tuple type out of a case class. I think, I am doing exactly the same thing shapeless does with generics:
class TupleProvider[T <: Product] {
type Repr
def provide(t: T): Repr = ???
}
object TupleProvider {
type Aux[T <: Product, R] = TupleProvider[T] {type Repr = R}
def apply[T <: Product](implicit tp: TupleProvider[T]): Aux[T, tp.Repr] = tp
implicit def materialize[T, R]: Aux[T, R] = macro TypeProviderMacros.repr1[T, R]
def instance[T <: Product, R <: Product]: Aux[T, R] = new TupleProvider[T] { type Repr = R }
}
class TypeProviderMacros(val c: whitebox.Context) {
import c.universe._
def repr1[T: WeakTypeTag, R: WeakTypeTag] = {
q"TupleProvider.instance[${weakTypeOf[T]}, ${typeOf[Tuple2[String, Int]]}]"
}
}
However, if I do something like
case class Foo(x: Int, y: String)
val p = TupleProvider[Foo]
p ends up having type TupleProvider.Aux[Foo, Nothing]
I can't figure out what specifically am I doing differently from shapless.Generic, which seems to be implemented in exactly the same way, but gives me this:
val g: Aux[Foo, Int :: String :: HNil] = Generic[Foo]
Any ideas?