Closed
Description
Compiler version
Latest nightly (i.e. dottyLatestNightlyBuild.get
)
Minimized code
Create a simple mirror type object which summons a product mirror, add an extension method for it to be able to be applied to any type:
object MirrorType {
class Container[T]
inline def decode[T]: String =
summonFrom {
case ev: Mirror.ProductOf[T] =>
s"Product-${new Container[ev.MirroredElemLabels]}" // This is the part that splices in the cast
case m: Mirror.SumOf[T] =>
"Sum"
}
inline def generic[T]: MirrorType[T] =
new MirrorType[T] {
def mirrorType: String = decode[T]
}
extension[T](inline value: T)
inline def mirrorType = summonFrom {
case mt: MirrorType[T] => mt.mirrorType
case _ => "mirror not found"
}
}
Then import the context and run it:
object ContextUse {
def main(args: Array[String]): Unit = {
val ctx = new MyContext();
import ctx._
val tup = ("foo", 1)
println( tup.mirrorType )
}
}
Output
A class cast exception will occur
[error] (run-main-2) java.lang.ClassCastException: io.getquill.mytest.ContextUse$$anon$2 cannot be cast to scala.deriving.Mirror$Product
[error] java.lang.ClassCastException: io.getquill.mytest.ContextUse$$anon$2 cannot be cast to scala.deriving.Mirror$Product
[error] at io.getquill.mytest.ContextUse$$anon$1.mirrorType(Use.scala:10)
[error] at io.getquill.mytest.ContextUse$.main(Use.scala:10)
[error] at io.getquill.mytest.ContextUse.main(Use.scala)
[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)
This is probably because I can see that the following code is being spliced:
{
val ev: Product {
type MirroredType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredMonoType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredElemTypes >: Nothing <: Tuple
} & Product {
type MirroredMonoType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredLabel >: "Tuple2" <: "Tuple2"
} {
type MirroredElemTypes >: *:[String, *:[Int, EmptyTuple]] <: *:[String, *:[Int, EmptyTuple]]
type MirroredElemLabels >: *:["_1", *:["_2", EmptyTuple]] <: *:["_1", *:["_2", EmptyTuple]]
} = {
final class $anon() {
type MirroredMonoType = Tuple2[String, Int]
}
(new $anon(): Object)
}.$asInstanceOf$[Product { // WHAT??? You can't cast this to a Product
type MirroredType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredMonoType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredElemTypes >: Nothing <: Tuple
} & Product {
type MirroredMonoType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredType >: Tuple2[String, Int] <: Tuple2[String, Int]
type MirroredLabel >: "Tuple2" <: "Tuple2"
} {
type MirroredElemTypes >: *:[String, *:[Int, EmptyTuple]] <: *:[String, *:[Int, EmptyTuple]]
type MirroredElemLabels >: *:["_1", *:["_2", EmptyTuple]] <: *:["_1", *:["_2", EmptyTuple]]
}]
_root_.scala.StringContext.apply("Product-", "").s(new Container[MirroredElemLabels]())
}
Expectation
Code should compile and run correctly.
Repository
Code is available here:
https://github.com/deusaquilus/class_cast_issue