Using deriving.Mirror in a generic method allows you to retrieve the names of members for any case class.
//> using scala 3.3.1
import scala.compiletime.*
import scala.deriving.Mirror
inline def labels[T](using m: Mirror.Of[T]) =
constValueTuple[m.MirroredElemLabels].toList.asInstanceOf[List[Any]]
case class Bbb(id: Int, name: String, value: Double)
println(labels[Bbb]) // => List(id, name, value)
However, attempting the same in a generic class does not seem to work.
For example, the following code results in a compilation error.
//> using scala 3.3.1
import scala.compiletime.*
import scala.deriving.Mirror
class Aaa[T](a: Int)(using m: Mirror.Of[T]):
inline def labels =
constValueTuple[m.MirroredElemLabels].toList.asInstanceOf[List[Any]]
case class Bbb(id: Int, name: String, value: Double)
println(Aaa[Bbb](1).labels)
cannot reduce inline match with
scrutinee: compiletime.erasedValue[deriving.Mirror.Of[Bbb]#MirroredElemLabels] : deriving.Mirror.Of[Bbb]#MirroredElemLabels
patterns : case _:EmptyTuple
case _:*:[t @ _, ts @ _]
How should this difference be understood?
Is it correct to understand that MirroredElemLabels is not obtained as a constant type at compile-time?
Trying the following code results in “Tuple”, causing me some confusion.
//> using scala 3.3.1
import scala.compiletime.*
import scala.deriving.Mirror
class Aaa[T](a: Int)(using m: Mirror.Of[T]):
inline def whatis =
inline erasedValue[m.MirroredElemLabels] match
case _: EmptyTuple => "Empty"
case _: (t *: ts) => "Cons" // pass
case _: Tuple => "Tuple" // match
case _ => "Unknown"