Skip to content
Browse files

Fixed a bug involving classOf[Foo] having the wrong erasure.

Luckily I had only days ago deciphered the unique handling of
classOf, so I knew what was up. Closes #4753, review by odersky.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@25217 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
  • Loading branch information...
1 parent 6e9faad commit bdac60f9eee9a9037627cdfe2bba425d48ccad6c extempore committed
View
3 src/compiler/scala/reflect/internal/TreeGen.scala
@@ -226,6 +226,9 @@ abstract class TreeGen {
* 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))
View
11 src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -527,10 +527,15 @@ abstract class Erasure extends AddInterfaces
}
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 _ => tp.deconst
+ 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
}
}
// Methods on Any/Object which we rewrite here while we still know what
View
1 test/files/run/bug4753.check
@@ -0,0 +1 @@
+boolean
View
12 test/files/run/bug4753.scala
@@ -0,0 +1,12 @@
+trait A {
+ val actualType: Class[_]
+}
+trait B extends A {
+ final val actualType = classOf[Boolean]
+}
+
+object Test extends B {
+ def main(args: Array[String]): Unit = {
+ println(actualType)
+ }
+}

0 comments on commit bdac60f

Please sign in to comment.
Something went wrong with that request. Please try again.