scala-reflect produces inconsistent results for type boundaries obtained through etaExpand on scala 2.13.0
pshirshov opened this issue · comments
Let's consider this example (you may just copypaste it into scala shell):
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
import scala.reflect.runtime.universe._
trait LightTypeTag { /*TODO*/ }
def makeTag[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[LightTypeTag] = {
import c.universe._
val tpe = implicitly[WeakTypeTag[T]].tpe
println((tpe, tpe.hashCode, System.identityHashCode(tpe)))
def test() = {
tpe.etaExpand.resultType.dealias.typeArgs.map(_.dealias.resultType.typeSymbol.typeSignature).map {
case tpe: TypeBoundsApi =>
tpe.hi
}.foreach {
tpe =>
println((tpe, tpe.hashCode, System.identityHashCode(tpe)))
}
}
test()
test()
test()
c.Expr[LightTypeTag](q"null")
}
def materialize1[T[_]]: LightTypeTag = macro makeTag[T[Nothing]]
materialize1[Enum]
On scala < 2.13 it prints
(Enum,-2104744931,1129119773)
(Enum[E],2055684080,910505843)
(Enum[E],2055684080,910505843)
(Enum[E],2055684080,910505843)
Which is expected.
On scala 2.13 it prints
(Enum,847238925,1831829645)
(Enum[E],-1086966789,342809115)
(Enum[E],-37304610,678306695)
(Enum[E],-500995075,606816495)
So, each invocation returns it's own, unique type boundary. And =:=
check fails.
It works without etaExpand
though.
there is some discussion at https://gitter.im/scala/contributors?at=5d4dde99d03a7c63e6fc4071 on whether this qualifies as a regression, or whether it's simply the kind of compiler-internals thing that might be expected to change in a minor release, let alone a major release
the bisect script from adriaanm/binfu#5 should be useful for identifying the scala/scala PR where this behavior changed, which I think would be the single most important piece of information to have in hand, in order to discuss whether this is a regression or simply a behavior change
Some time ago it (magically) started working again.