summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-03-15 15:50:41 +0100
committerJason Zaugg <jzaugg@gmail.com>2014-03-15 16:05:15 +0100
commitdc656062c35040f28c8b7774710d899b79f2e401 (patch)
tree2450b8c6f965a100efba2cbf06e2c68c113ee3ce
parent9c38e86a5526887f93a3f031b19a0e4fa31745d3 (diff)
downloadscala-dc656062c35040f28c8b7774710d899b79f2e401.tar.gz
scala-dc656062c35040f28c8b7774710d899b79f2e401.tar.bz2
scala-dc656062c35040f28c8b7774710d899b79f2e401.zip
SI-7992 Fix super-accessor generation after a local class
The transformer in the superaccessors phase uses the var `validCurrentOwner` to track whether we're in a part of the code that won't end up in the host method, and as such, will need to access super-method via a super-accessor. But, this bit of bookkeeping was not correctly reset after traversing out of a local class. A `VerifyError` ensued. This commit changes `atOwner` to save and restore that flag, rather than leaving it set to `true`. I've also added a test variation using a by-name argument.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--test/files/run/t7992.scala20
-rw-r--r--test/files/run/t7992b.scala18
3 files changed, 40 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 87da565142..9b9e641cad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -346,12 +346,14 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
* performance hit for the compiler as a whole.
*/
override def atOwner[A](tree: Tree, owner: Symbol)(trans: => A): A = {
+ val savedValid = validCurrentOwner
if (owner.isClass) validCurrentOwner = true
val savedLocalTyper = localTyper
localTyper = localTyper.atOwner(tree, if (owner.isModule) owner.moduleClass else owner)
typers = typers updated (owner, localTyper)
val result = super.atOwner(tree, owner)(trans)
localTyper = savedLocalTyper
+ validCurrentOwner = savedValid
typers -= owner
result
}
diff --git a/test/files/run/t7992.scala b/test/files/run/t7992.scala
new file mode 100644
index 0000000000..fde231b961
--- /dev/null
+++ b/test/files/run/t7992.scala
@@ -0,0 +1,20 @@
+class C {
+ def foo: Int = 0
+}
+
+class D extends C {
+ override def foo: Int = {
+ val f = () => {
+ class C // comment this line to fix.
+ D.super.foo // no super accessor generated here!
+ // java.lang.VerifyError: (class: D$$anonfun$1, method: apply$mcI$sp signature: ()I) Illegal use of nonvirtual function call
+ }
+ f()
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ new D().foo
+ }
+}
diff --git a/test/files/run/t7992b.scala b/test/files/run/t7992b.scala
new file mode 100644
index 0000000000..6fe1f990d5
--- /dev/null
+++ b/test/files/run/t7992b.scala
@@ -0,0 +1,18 @@
+class C {
+ def foo: Int = 0
+}
+
+class E extends C {
+ override def foo: Int = {
+ (None: Option[Int]).getOrElse {
+ class C
+ E.super.foo
+ }
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ new E().foo
+ }
+}