The method to call is the SAM of the following type class:
trait DiscriminatorCriteria[A] {
def getFor[V <: A]: Int
}
And the headType
to pass as type argument (to type parameter V) was obtained from a Mirror.SumOf.MirroredElemTypes
using a type quote pattern matching like this:
def deriveSerializerImpl[A: Type](using quotes: Quotes): Expr[Serializer[A]] = {
import quotes.reflect.*
Expr.summon[Mirror.Of[A]] match {
case Some('{ $m: Mirror.SumOf[A] {type MirroredElemTypes = elemTypes} }) =>
Type.of[elemTypes] match {
case '[headType *: tailTypes] =>
...
}
I need to define a quoted expression that calls getFor
like this:
case '[headType *: tailTypes] =>
val discriminatorCriteriaExpr = Expr.summon[DiscriminatorCriteria[A]].get // asume that exists
val discriminator: Expr[Int] = '{ $discriminatorCriteriaExpr.getFor[headType] }
But the compiler complains saying that headType
does not conform to the upper bound A
.
Try
... & A
val discriminator: Expr[Int] = '{ $discriminatorCriteriaExpr.getFor[headType & A] }
'{...}
rather than type quotations '[...]
case Some('{ $m: Mirror.SumOf[A] {type MirroredElemTypes = elemTypes} }) =>
'{ tag[elemTypes] } match {
case '{
type headType <: A
tag[`headType` *: tailTypes]
} =>
where dummy method is defined
def tag[A] = ???
type ABounded[T <: A] = T
val discriminator: Expr[Int] = '{ $discriminatorCriteriaExpr.getFor[ABounded[headType]] }
Type.of[elemTypes] match {
case '[type headType <: A; `headType` *: tailTypes] =>
Type.of[elemTypes] match {
case '[
type headType <: A
`headType` *: tailTypes
] =>
Explicit type conversion in Scala 3 macros
What Scala 3 syntax can match on a Type and its Type parameters in the context of a macro?
Replacement for `x.asType match { case '[type t <: S; t] => ...` in Scala 3.3 (LTS)