Type Class: Not using `asInstanceOf`, but still getting `ClassCastException`

108 views Asked by At

Consider the following relatively simple code:

import scala.deriving.Mirror

trait TC[A]:
  def show: A
object TC:
  inline def derived[A](using m: Mirror.ProductOf[A]): TC[A] = new TC[A]:
    override def show: A =
      val p: Product = new Product:
        def canEqual(that: Any): Boolean = true
        def productArity: Int = 1
        def productElement(n: Int): Any = 1
      m.fromProduct(p)

sealed trait T
case class C(x: Int) extends T derives TC
case object C // If I remove this line, then no exception will be thrown

@main
def main: Unit =
  println(summon[TC[C]].show)

Running it results in the following exception:

java.lang.ClassCastException: class nn.C$ cannot be cast to class nn.C (nn.C$ and nn.C are in unnamed module of loader sbt.internal.LayeredClassLoader @48aba6c1)
    at nn.C$$anon$1.show(MarshalerMacrosTest.scala:14)
    at nn.C$$anon$1.show(MarshalerMacrosTest.scala:9)
    at nn.MarshalerMacrosTest$package$.main(MarshalerMacrosTest.scala:22)
    at nn.main.main(MarshalerMacrosTest.scala:20)

But if I remove case object C, then everything will be fine. The exception happens at m.fromProduct(p). When case object C exists, m.fromProduct(p) returns this object and not an instance of type C. Any idea why that is the case? And what is the best fix for it?

0

There are 0 answers