Scala 3's scala.deriving.Mirror
has a type member MirroredElemLabels
which is a tuple of string literals. What's the standard way to get that type as a value?
EDIT: here's the code that produces a compiler error from trying to use summonAll
case class Test(a: Int, b: String)
val mirror = implicitly[Mirror.ProductOf[Test]]
val labels = summonAll[mirror.MirroredElemLabels]
println(labels)
cannot reduce inline match with
scrutinee: compiletime.erasedValue[App.mirror.MirroredElemLabels] : App.mirror.MirroredElemLabels
patterns : case _:EmptyTuple
case _:*:[t @ _, ts @ _]
Try to use scala.ValueOf
case class A(i: Int, s: String)
import scala.deriving.Mirror
import scala.compiletime.summonAll
val mirror = summon[Mirror.Of[A]]
type ValueOfs = Tuple.Map[mirror.MirroredElemLabels, ValueOf]
val valueOfs = summonAll[ValueOfs]
def values(t: Tuple): Tuple = t match
case (h: ValueOf[_]) *: t1 => h.value *: values(t1)
case EmptyTuple => EmptyTuple
values(valueOfs) // (i,s)
We can now use scala.compiletime.constValueTuple
inline def constValueTuple[T <: Tuple]: T =
(inline erasedValue[T] match
case _: EmptyTuple => EmptyTuple
case _: (t *: ts) => constValue[t] *: constValueTuple[ts]
).asInstanceOf[T]
and the return type will be precise
case class A(i: Int, s: String)
val mirror = summon[Mirror.Of[A]]
val res = constValueTuple[mirror.MirroredElemLabels] // (i,s)
res: ("i", "s") // compiles
Tested in 3.2.0
https://docs.scala-lang.org/scala3/reference/contextual/derivation.html
https://docs.scala-lang.org/scala3/reference/metaprogramming/compiletime-ops.html