summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala15
-rw-r--r--test/files/neg/bug3736.check13
-rw-r--r--test/files/neg/bug3736.scala21
-rw-r--r--test/files/run/hashhash.scala9
4 files changed, 46 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 541ef35b4b..16c6203474 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -80,11 +80,6 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
}
private def transformSuperSelect(tree: Tree): Tree = tree match {
- // Intercept super.## and translate it to this.##
- // which is fine since it's final.
- case Select(sup @ Super(_, _), nme.HASHHASH) =>
- Select(gen.mkAttributedThis(sup.symbol), Object_##) setType IntClass.tpe
-
case Select(sup @ Super(_, mix), name) =>
val sym = tree.symbol
val clazz = sup.symbol
@@ -127,6 +122,13 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
tree
}
+ // Disallow some super.XX calls targeting Any methods which would
+ // otherwise lead to either a compiler crash or runtime failure.
+ private def isDisallowed(name: Name) = name match {
+ case nme.HASHHASH | nme.EQ | nme.NE | nme.isInstanceOf_ => true
+ case _ => false
+ }
+
override def transform(tree: Tree): Tree = {
val sym = tree.symbol
@@ -203,6 +205,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
unit.error(tree.pos, "super may be not be used on "+
(if (sym.hasFlag(ACCESSOR)) sym.accessed else sym))
}
+ else if (isDisallowed(name)) {
+ unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
+ }
transformSuperSelect(tree)
case TypeApply(sel @ Select(qual, name), args) =>
diff --git a/test/files/neg/bug3736.check b/test/files/neg/bug3736.check
new file mode 100644
index 0000000000..8a91088914
--- /dev/null
+++ b/test/files/neg/bug3736.check
@@ -0,0 +1,13 @@
+bug3736.scala:4: error: super not allowed here: use this.isInstanceOf instead
+ def f2 = super.isInstanceOf[String]
+ ^
+bug3736.scala:6: error: super not allowed here: use this.== instead
+ def f4 = super.==(new AnyRef)
+ ^
+bug3736.scala:7: error: super not allowed here: use this.!= instead
+ def f5 = super.!=(new AnyRef)
+ ^
+bug3736.scala:8: error: super not allowed here: use this.## instead
+ def f6 = super.##
+ ^
+four errors found
diff --git a/test/files/neg/bug3736.scala b/test/files/neg/bug3736.scala
new file mode 100644
index 0000000000..8e63021f69
--- /dev/null
+++ b/test/files/neg/bug3736.scala
@@ -0,0 +1,21 @@
+object Test {
+ class A {
+ def f1 = super.toString
+ def f2 = super.isInstanceOf[String]
+ def f3 = super.asInstanceOf[AnyRef]
+ def f4 = super.==(new AnyRef)
+ def f5 = super.!=(new AnyRef)
+ def f6 = super.##
+ }
+
+ def main(args: Array[String]): Unit = {
+ val x = new A
+ x.f1
+ x.f2
+ x.f3
+ x.f4
+ x.f5
+ x.f6
+ }
+}
+
diff --git a/test/files/run/hashhash.scala b/test/files/run/hashhash.scala
index 4a34ab12e0..d3800be876 100644
--- a/test/files/run/hashhash.scala
+++ b/test/files/run/hashhash.scala
@@ -1,15 +1,10 @@
-object Test
-{
- class A { val x1 = this.## ; val x2 = super.## }
- val myA = new A
- assert(myA.x1 == myA.x2)
-
+object Test {
def confirmSame(x: Any) = assert(x.## == x.hashCode, "%s.## != %s.hashCode".format(x, x))
def confirmDifferent(x: Any) = assert(x.## != x.hashCode, "%s.## == %s.hashCode (but should not)".format(x, x))
def main(args: Array[String]): Unit = {
/** Just a little sanity check, not to be confused with a unit test. */
- List(5, 5.5f, "abc", new AnyRef, new A, ()) foreach confirmSame
+ List(5, 5.5f, "abc", new AnyRef, ()) foreach confirmSame
List(5.0f, 1.0d, -(5.0f), (-1.0d)) foreach confirmDifferent
}
}