Closed
Description
scala.tasty.Reflection
provides given instances of ClassTag
to be able to pattern match (ClassTag.unapply
).
But if they are used those as ClassTag
(i.e. for arrays) we hit an unsoundness when type types in Reflection
are implemented with the same class.
The solution is not to give implicit ClassTag
s for those types, or only give one for the root type (Tree
, Type
, Position
, ...).
Therefore the ClassTag
concept should be separate from the type testing logic (see #7555).
Here is a minimal self contained example of how this unsoundness can be triggered
package x
@main def Foo = {
val refl: Refl = new ReflImpl
import refl._
val arr = Array[refl.Tree]()
arr match
case arr: Array[refl.Term] => throw new Exception() // some elements of the array may to be refl.Term
case _ => // ok
}
trait Refl {
type Tree
type Term <: Tree
def treeCT: scala.reflect.ClassTag[Tree]
def termCT: scala.reflect.ClassTag[Term]
given scala.reflect.ClassTag[Tree] = treeCT
given scala.reflect.ClassTag[Term] = termCT
}
object ReflImpl {
class Tree
def treeCT: scala.reflect.ClassTag[Tree] = summon[scala.reflect.ClassTag[Tree]]
}
class ReflImpl extends Refl {
type Tree = ReflImpl.Tree
type Term = ReflImpl.Tree
def treeCT: scala.reflect.ClassTag[Tree] = ReflImpl.treeCT
def termCT: scala.reflect.ClassTag[Term] = ReflImpl.treeCT
}