diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/AddInterfaces.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 18 | ||||
-rw-r--r-- | test/files/neg/names-defaults-neg.check | 16 | ||||
-rw-r--r-- | test/files/neg/names-defaults-neg.scala | 19 | ||||
-rw-r--r-- | test/files/run/names-defaults.check | 7 | ||||
-rw-r--r-- | test/files/run/names-defaults.scala | 39 |
6 files changed, 61 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index f009f69f4a..ccae9578b9 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -294,7 +294,8 @@ abstract class AddInterfaces extends InfoTransform { } (tree: @unchecked) match { case Block(stats, expr) => - val (presuper, supercall :: rest) = stats span (_.symbol.hasFlag(PRESUPER)) + // needs `hasSymbol' check because `supercall' could be a block (named / default args) + val (presuper, supercall :: rest) = stats span (t => t.hasSymbol && t.symbol.hasFlag(PRESUPER)) //assert(supercall.symbol.isClassConstructor, supercall) treeCopy.Block(tree, presuper ::: (supercall :: mixinConstructorCalls ::: rest), expr) } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index b104bed2c7..0ede740b00 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -179,13 +179,23 @@ trait NamesDefaults { self: Analyzer => assert(treeInfo.isPureExpr(qual), qual) blockWithoutQualifier(baseFun1, defaultQual) + // super constructor calls + + case Select(Super(_, _), _) if isConstr => + blockWithoutQualifier(baseFun1, None) + + // self constructor calls (in secondary constructors) + + case Select(qual, name) if isConstr => + assert(treeInfo.isPureExpr(qual), qual) + blockWithoutQualifier(baseFun1, None) + // other method calls case Ident(_) => blockWithoutQualifier(baseFun1, None) case Select(qual, name) => - assert(!isConstr, baseFun1) if (treeInfo.isPureExpr(qual)) blockWithoutQualifier(baseFun1, Some(qual.duplicate)) else @@ -224,11 +234,7 @@ trait NamesDefaults { self: Analyzer => } // begin transform - if (treeInfo.isSelfConstrCall(tree)) { - errorTree(tree, "using named or default arguments in a self constructor call is not allowed") - } else if (treeInfo.isSuperConstrCall(tree)) { - errorTree(tree, "using named or default arguments in a super constructor call is not allowed") - } else if (isNamedApplyBlock(tree)) { + if (isNamedApplyBlock(tree)) { context.namedApplyBlockInfo.get._1 } else tree match { // we know that Apply(Apply(...)) can only be an application of a curried method; diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index d4331ab63f..b208157c6a 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -85,21 +85,9 @@ names-defaults-neg.scala:88: error: type mismatch; names-defaults-neg.scala:88: error: multiple overloaded alternatives of method bar define default arguments def bar(i: Int = 129083) = i ^ -names-defaults-neg.scala:93: error: using named or default arguments in a super constructor call is not allowed -class B1 extends A1(10) - ^ -names-defaults-neg.scala:94: error: using named or default arguments in a super constructor call is not allowed -class B2 extends A1(y = 20, x = 2) - ^ -names-defaults-neg.scala:99: error: using named or default arguments in a self constructor call is not allowed - this(y = 10, x = a.toString()) - ^ -names-defaults-neg.scala:105: error: using named or default arguments in a self constructor call is not allowed - this(sep + b + sep) - ^ -names-defaults-neg.scala:112: error: type mismatch; +names-defaults-neg.scala:95: error: type mismatch; found : java.lang.Object required: java.lang.String class B5 extends A5 { override def foo(a: Object = new Object) = 1 } ^ -26 errors found
\ No newline at end of file +22 errors found
\ No newline at end of file diff --git a/test/files/neg/names-defaults-neg.scala b/test/files/neg/names-defaults-neg.scala index 29db82924c..68cdcf782f 100644 --- a/test/files/neg/names-defaults-neg.scala +++ b/test/files/neg/names-defaults-neg.scala @@ -88,25 +88,8 @@ class C extends B { def bar(i: Int = 129083) = i } -// using names / defaults in super constructor call not allowed -class A1(x: Int, y: Int = 2) -class B1 extends A1(10) -class B2 extends A1(y = 20, x = 2) - -// using names / defaults in self constructor call not allowed -class A2(x: String, y: Int = 10) { - def this(a: Object) { - this(y = 10, x = a.toString()) - println(x) - } -} -class A3(x: String, y: Int = 11) { - def this(b: Double, sep: String) { - this(sep + b + sep) - } -} - case class Fact(a: Int, b: String)(c: Int*) +// overriding default must have same type class A5 { def foo(a: Object = "dlkf") = 0 } class B5 extends A5 { override def foo(a: Object = new Object) = 1 } diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check index 3fed6e601a..07a7d7d1be 100644 --- a/test/files/run/names-defaults.check +++ b/test/files/run/names-defaults.check @@ -92,4 +92,9 @@ test5 2 test5 3 -slkdfj1
\ No newline at end of file +slkdfj1 +1 +lskfdjlk +11 +2 +20
\ No newline at end of file diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index c016a98e1a..6ec391af2f 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -183,10 +183,21 @@ object Test extends Application { // bug #2057 - class O { class I(x: Int = 1) } + class O { class I(val x: Int = 1) } class U extends O { val f = new I() } + val u1 = new U + println(u1.f.x) + // names / defaults in self constructor call + new A3("lskfdjlk") + new A4(1.23, ",") + + + // names / defaults in super constructor call + new B4() + new B5() + // DEFINITIONS def test1(a: Int, b: String) = println(a +": "+ b) @@ -251,3 +262,29 @@ class A2 { } class C2 } + + + +// using names / defaults in self constructor call +class A3(x: String, y: Int = 10) { + def this(a: Object) { + this(y = 10, x = a.toString()) + println(x) + } +} +class A4(x: String, y: Int = 11) { + def this(b: Double, sep: String) { + this(sep + b + sep) + println(y) + } +} + + +// using names / defaults in super constructor call +class A5(x: Int, val y: Int = 2)(z: Int = x + y) +class B4 extends A5(10)() { + println(y) +} +class B5 extends A5(y = 20, x = 2)() { + println(y) +} |