You have seen this comment I trust, especially "I would be very
surprised if there aren't more."
/** Apparently we smuggle a Type around as a Literal(Constant(tp))
* and the implementation of Constant#tpe is such that x.tpe becomes
* ClassType(value.asInstanceOf[Type]), i.e. java.lang.Class[Type].
* Can't find any docs on how/why it's done this way. See ticket
* SI-490 for some interesting comments from lauri alanko suggesting
* that the type given by classOf[T] is too strong and should be
* weakened so as not to suggest that classOf[List[String]] is any
* different from classOf[List[Int]].
*
* !!! See deconstMap in Erasure for one bug this encoding has induced:
* I would be very surprised if there aren't more.
*/
def mkClassOf(tp: Type): Tree =
Literal(Constant(tp)) setType ConstantType(Constant(tp))
And
val deconstMap = new TypeMap {
// For some reason classOf[Foo] creates
ConstantType(Constant(tpe)) with an actual Type for tpe,
// which is later translated to a Class. Unfortunately that means
we have bugs like the erasure
// of Class[Foo] and classOf[Bar] not being seen as equivalent,
leading to duplicate method
// generation and failing bytecode. See ticket #4753.
def apply(tp: Type): Type = tp match {
case PolyType(_, _) => mapOver(tp)
case MethodType(_, _) => mapOver(tp) //
nullarymethod was eliminated during uncurry
case ConstantType(Constant(_: Type)) => ClassClass.tpe // all
classOfs erase to Class
case _ => tp.deconst
}
}
> Hence I'd like to hear the original
> motivation behind making _tpe a lazy val.
There's a comment right above it which sounds like a motivation to me:
/** Save the type of `value`. For Java enums, it depends on
finding the linked class,
* which might not be found after `flatten`. */
It's safest to assume nothing was thought of.
> For example, as far as I can guess, enums are smuggled in symbols.
> Does this mean that if I make _tpe lazy only for enum constants, I
> will not break anything?
Most of what I know about what doesn't work is derived from just
making a change like this and ant all.clean test. If everything
passes, that doesn't necessarily mean it's okay - but since something
usually breaks, it's useful for avoiding too much actual thinking.
https://github.com/scala/scala/commit/f36d200b
https://issues.scala-lang.org/browse/SI-1329