Open
Description
Minimized code
package example
trait Sealed[A] {
type NumCases <: Int
}
object Sealed {
import quoted._
transparent inline def derived[A]: Sealed[A] = ${ deriveSealed[A] }
def deriveSealed[A: Type](using Quotes): Expr[Sealed[A]] =
import quotes.reflect._
val tpe = TypeRepr.of[A]
val sym = tpe.classSymbol match
case Some(sym) => sym
case _ => report.throwError(s"${tpe.show} is not a class type")
val numCases = ConstantType(IntConstant(sym.children.length)).asType.asInstanceOf[quoted.Type[Int]]
'{
new {
type NumCases = numCases.Underlying
}
}
}
// second source
import example._
enum MyEnum derives Sealed { case A, B, C }
val fromDerived = summon[Sealed[MyEnum]] // : example.Sealed[MyEnum]
val manual = Sealed.derived[MyEnum] // : example.Sealed[MyEnum]{NumCases = 3}
Expectation
I would expect the cached values to remember type refinements, so e.g. the derived Sealed
instance can be used in further type class derivation to extract the NumCases
type