summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-08-26 13:28:37 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-08-26 13:28:37 +0000
commitb3e8963c30de38a6d813640d58cbb1a0a00eba36 (patch)
tree95d646feeff954fb5c78077a82ed1fcf09282d24
parentcbb97ea1136982742344a0493cadb6080a19a082 (diff)
downloadscala-b3e8963c30de38a6d813640d58cbb1a0a00eba36.tar.gz
scala-b3e8963c30de38a6d813640d58cbb1a0a00eba36.tar.bz2
scala-b3e8963c30de38a6d813640d58cbb1a0a00eba36.zip
Closes #3497.
-rw-r--r--src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala29
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala4
-rw-r--r--test/files/pos/spec-t3497.scala16
3 files changed, 35 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
index 0af482912d..b1be70a54c 100644
--- a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
+++ b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
@@ -580,17 +580,23 @@ abstract class ScalaPrimitives {
import definitions._
val code = getPrimitive(fun)
- var elem: Type = null
- tpe match {
- case TypeRef(_, sym, _elem :: Nil)
- if (sym == ArrayClass) => elem = _elem
- case _ => ()
+ def elementType = atPhase(currentRun.typerPhase) {
+ val arrayParent = tpe :: tpe.parents find {
+ case TypeRef(_, sym, _elem :: Nil)
+ if (sym == ArrayClass) => true
+ case _ => false
+ }
+ if (arrayParent.isEmpty) {
+ println(fun.fullName + " : " + tpe :: tpe.baseTypeSeq.toList)
+ }
+ val TypeRef(_, _, elem :: Nil) = arrayParent.get
+ elem
}
code match {
case APPLY =>
- toTypeKind(elem) match {
+ toTypeKind(elementType) match {
case BOOL => ZARRAY_GET
case BYTE => BARRAY_GET
case SHORT => SARRAY_GET
@@ -601,11 +607,11 @@ abstract class ScalaPrimitives {
case DOUBLE => DARRAY_GET
case REFERENCE(_) | ARRAY(_) => OARRAY_GET
case _ =>
- abort("Unexpected array element type: " + elem)
+ abort("Unexpected array element type: " + elementType)
}
case UPDATE =>
- toTypeKind(elem) match {
+ toTypeKind(elementType) match {
case BOOL => ZARRAY_SET
case BYTE => BARRAY_SET
case SHORT => SARRAY_SET
@@ -616,12 +622,11 @@ abstract class ScalaPrimitives {
case DOUBLE => DARRAY_SET
case REFERENCE(_) | ARRAY(_) => OARRAY_SET
case _ =>
- abort("Unexpected array element type: " + elem)
+ abort("Unexpected array element type: " + elementType)
}
case LENGTH =>
- assert(elem != null)
- toTypeKind(elem) match {
+ toTypeKind(elementType) match {
case BOOL => ZARRAY_LENGTH
case BYTE => BARRAY_LENGTH
case SHORT => SARRAY_LENGTH
@@ -632,7 +637,7 @@ abstract class ScalaPrimitives {
case DOUBLE => DARRAY_LENGTH
case REFERENCE(_) | ARRAY(_) => OARRAY_LENGTH
case _ =>
- abort("Unexpected array element type: " + elem)
+ abort("Unexpected array element type: " + elementType)
}
case _ =>
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 65c685b350..4f764f6fc0 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -679,7 +679,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val specMember = sym.cloneSymbol(owner) // this method properly duplicates the symbol's info
specMember.name = specializedName(sym, env)
- specMember.setInfo(subst(env, specMember.info))
+ specMember.setInfo(subst(env, specMember.info.asSeenFrom(owner.thisType, sym.owner)))
.setFlag(SPECIALIZED)
.resetFlag(DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
}
@@ -748,8 +748,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
for (overriding <- clazz.info.decls;
val (overridden, env) = needsSpecialOverride(overriding, overriding.allOverriddenSymbols)
if overridden != NoSymbol) {
- log("Added specialized overload for " + overriding.fullName + " in env: " + env)
val om = specializedOverload(clazz, overridden, env)
+ log("Added specialized overload for %s in env: %s with type: %s".format(overriding.fullName, env, om.info))
typeEnv(om) = env
concreteSpecMethods += overriding
if (!overriding.isDeferred) { // concrete method
diff --git a/test/files/pos/spec-t3497.scala b/test/files/pos/spec-t3497.scala
new file mode 100644
index 0000000000..ff054aa7de
--- /dev/null
+++ b/test/files/pos/spec-t3497.scala
@@ -0,0 +1,16 @@
+abstract class A[T, @specialized U] {
+ def score(state: T): U
+}
+
+object B extends A[ Array[Byte], Int ] {
+ def score(state: Array[Byte]): Int = {
+ var index = 0
+ while (index < state.length) { // (index < 2) leads to the #2755 NullPointerException
+ if (state(index) == 0) {
+ return -1
+ }
+ }
+
+ return 0
+ }
+}