Skip to content

ClassCastException when trying to use Mirror.Of[T] when T contains a Tuple #11961

Closed
@VlachJosef

Description

@VlachJosef

Compiler version

3.0.0-RC2
sbt 1.4.9 (GraalVM Community Java 1.8.0_282)

Minimized code

import scala.deriving.*
import scala.compiletime.{erasedValue, summonInline}

case class Simple(a: String, b: Boolean) derives Printable
case class SimpleT(a: (String, Boolean)) derives Printable

@main def hello: Unit = {

  summon[Printable[Simple]].print // Prints STRING BOOLEAN as expected

  summon[Printable[SimpleT]].print // java.lang.ClassCastException: SimpleT$$anon$1 cannot be cast to scala.deriving.Mirror$Product

}

trait Printable[T]:
   def print: Unit

object Printable:

   given Printable[String] with
      def print: Unit = println("STRING")

   given Printable[Boolean] with
      def print: Unit = println("BOOLEAN")

   def printProduct[T](p: Mirror.ProductOf[T], elems: => List[Printable[_]]): Printable[T] =
      new Printable[T]:
         def print: Unit =
            elems.foreach(_.print)

   inline given derived[T](using m: Mirror.Of[T]): Printable[T] =
      val elemInstances = summonAllPrintable[m.MirroredElemTypes]
      inline m match
         case p: Mirror.ProductOf[T] => printProduct(p, elemInstances)

end Printable

inline def summonAllPrintable[T <: Tuple]: List[Printable[_]] =
   inline erasedValue[T] match
      case _: EmptyTuple => Nil
      case _: (t *: ts) => summonInline[Printable[t]] :: summonAllPrintable[ts]

Output

> run
[info] running hello 
STRING
BOOLEAN
[error] (run-main-0) java.lang.ClassCastException: SimpleT$$anon$1 cannot be cast to scala.deriving.Mirror$Product
[error] java.lang.ClassCastException: SimpleT$$anon$1 cannot be cast to scala.deriving.Mirror$Product
[error] 	at SimpleT$.derived$Printable(Main.scala:5)
[error] 	at Main$package$.hello(Main.scala:11)
[error] 	at hello.main(Main.scala:7)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] 	at java.lang.reflect.Method.invoke(Method.java:498)
[error] stack trace is suppressed; run last Compile / bgRun for the full output
[error] Nonzero exit code: 1
[error] (Compile / run) Nonzero exit code: 1
[error] Total time: 3 s, completed Mar 31, 2021 9:16:29 PM

Expectation

I'd expect this program to produce compilation error about missing Printable[(String, Boolean)] or similar.

Trying to get familiar with type-classes-supporting-automatic-deriving I'm trying to implement typeclass which prints its own type.

Minimized project is available here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions