summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-05-30 17:44:29 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-05-30 18:57:32 +0200
commit608f577e0a565c746f94b9b52ceadf9728b179b4 (patch)
tree6586576ad532ee94959306c06892eb8e69d94cee
parent681f2070053bc6f3133425b44083fe056bfeb1fa (diff)
downloadscala-608f577e0a565c746f94b9b52ceadf9728b179b4.tar.gz
scala-608f577e0a565c746f94b9b52ceadf9728b179b4.tar.bz2
scala-608f577e0a565c746f94b9b52ceadf9728b179b4.zip
SI-6841 Fix bug at the intersection of DelayedInit and named args
The DelayedInit transformation analyses the constructor to partition regular initialization from calls to super constructors / trait initializers. It failed to find such super calls if they were nested in a Block, which can happens when using named or default arguments. This commit makes that code peer into Blocks to correctly partition the constructor statements. This change doesn't affect the result of run/t4680.scala, which was mentioned in nearby comments and which chronicles bugs with DelayedInit when used in inheritance hierarchies.
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala5
-rw-r--r--test/files/run/t6481.check4
-rw-r--r--test/files/run/t6481.scala13
3 files changed, 21 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 4891ef2fd1..1a1137f402 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -523,7 +523,10 @@ abstract class Constructors extends Transform with ast.TreeDSL {
/** Return a pair consisting of (all statements up to and including superclass and trait constr calls, rest) */
def splitAtSuper(stats: List[Tree]) = {
- def isConstr(tree: Tree) = (tree.symbol ne null) && tree.symbol.isConstructor
+ def isConstr(tree: Tree): Boolean = tree match {
+ case Block(_, expr) => isConstr(expr) // SI-6481 account for named argument blocks
+ case _ => (tree.symbol ne null) && tree.symbol.isConstructor
+ }
val (pre, rest0) = stats span (!isConstr(_))
val (supercalls, rest) = rest0 span (isConstr(_))
(pre ::: supercalls, rest)
diff --git a/test/files/run/t6481.check b/test/files/run/t6481.check
new file mode 100644
index 0000000000..7ec29631b1
--- /dev/null
+++ b/test/files/run/t6481.check
@@ -0,0 +1,4 @@
+delayed init
+new foo(1, 2)
+delayed init
+new foo(b = 2, a = 1)
diff --git a/test/files/run/t6481.scala b/test/files/run/t6481.scala
new file mode 100644
index 0000000000..125da3b15a
--- /dev/null
+++ b/test/files/run/t6481.scala
@@ -0,0 +1,13 @@
+abstract class foo(a: Int, b: Int) extends scala.DelayedInit {
+ def delayedInit(x: => Unit) {
+ println("delayed init");
+ x
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ new foo(1, 2) { println("new foo(1, 2)") }
+ new foo(b = 2, a = 1) { println("new foo(b = 2, a = 1)") }
+ }
+}