Permalink
Browse files

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.
  • Loading branch information...
1 parent 681f207 commit 608f577e0a565c746f94b9b52ceadf9728b179b4 @retronym retronym committed May 30, 2013
View
5 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)
View
4 test/files/run/t6481.check
@@ -0,0 +1,4 @@
+delayed init
+new foo(1, 2)
+delayed init
+new foo(b = 2, a = 1)
View
13 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)") }
+ }
+}

0 comments on commit 608f577

Please sign in to comment.