summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/Erasure.scala
diff options
context:
space:
mode:
authorJames Iry <jamesiry@gmail.com>2013-01-14 11:24:11 -0800
committerJames Iry <jamesiry@gmail.com>2013-01-15 10:48:22 -0800
commit765386ff970af8d53aaa66a42b030e83043d471d (patch)
tree9c3d9cff76fc2e989890e9a88a829dc8596657ee /src/compiler/scala/tools/nsc/transform/Erasure.scala
parent621f7a56c21686ebbd39b8ffe9282f917fe1f128 (diff)
downloadscala-765386ff970af8d53aaa66a42b030e83043d471d.tar.gz
scala-765386ff970af8d53aaa66a42b030e83043d471d.tar.bz2
scala-765386ff970af8d53aaa66a42b030e83043d471d.zip
SI-5568 Fixes verify error from getClass on refinement of value type
().asInstanceOf[AnyRef with Unit].getClass and 5.asInstanceOf[AnyRef with Int].getClass would cause a verify error. Going the other way, i.e. [Unit with AnyRef] or [Int with AnyRef] worked fine. This commit fixes it that both directions work out to BoxedUnit or java.lang.Integer.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Erasure.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 7b9b13ae1c..58494cb18e 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -340,12 +340,18 @@ abstract class Erasure extends AddInterfaces
case _ => tp.deconst
}
}
- // Methods on Any/Object which we rewrite here while we still know what
- // is a primitive and what arrived boxed.
- private lazy val interceptedMethods = Set[Symbol](Any_##, Object_##, Any_getClass, AnyVal_getClass) ++ (
- // Each value class has its own getClass for ultra-precise class object typing.
+
+ // Each value class has its own getClass for ultra-precise class object typing.
+ private lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ (
ScalaValueClasses map (_.tpe member nme.getClass_)
)
+
+ // ## requires a little translation
+ private lazy val poundPoundMethods = Set[Symbol](Any_##, Object_##)
+
+ // Methods on Any/Object which we rewrite here while we still know what
+ // is a primitive and what arrived boxed.
+ private lazy val interceptedMethods = poundPoundMethods ++ primitiveGetClassMethods
// -------- erasure on trees ------------------------------------------
@@ -1136,7 +1142,7 @@ abstract class Erasure extends AddInterfaces
args)
}
} else if (args.isEmpty && interceptedMethods(fn.symbol)) {
- if (fn.symbol == Any_## || fn.symbol == Object_##) {
+ if (poundPoundMethods.contains(fn.symbol)) {
// This is unattractive, but without it we crash here on ().## because after
// erasure the ScalaRunTime.hash overload goes from Unit => Int to BoxedUnit => Int.
// This must be because some earlier transformation is being skipped on ##, but so
@@ -1152,9 +1158,14 @@ abstract class Erasure extends AddInterfaces
} else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
// Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen))))
- } else if (fn.symbol == AnyVal_getClass) {
+ } else if (primitiveGetClassMethods.contains(fn.symbol)) {
+ // if we got here then we're trying to send a primitive getClass method to
+ // a) an Any, or
+ // b) a non-primitive, e.g. because the qualifier's type is a refinement type where part of the refinement is a primitive.
+ // if we use Object_getClass then things work out because we will call getClass on the boxed form of the Any or primitive
tree setSymbol Object_getClass
} else {
+ debugwarn(s"The symbol '${fn.symbol}' was interecepted but didn't match any cases, that means the intercepted methods set doesn't match the code")
tree
}
} else qual match {