summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-01-28 09:10:37 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-02-02 13:19:06 +0100
commitfd6125428af90b02cb8969a53586f3551e275b0f (patch)
tree17acfa819519ec2d92eeac8b2e0dece89aad7b25
parentee24807f8706bb91b9d854eaba39f0ddd9c2a054 (diff)
downloadscala-fd6125428af90b02cb8969a53586f3551e275b0f.tar.gz
scala-fd6125428af90b02cb8969a53586f3551e275b0f.tar.bz2
scala-fd6125428af90b02cb8969a53586f3551e275b0f.zip
SI-6666 Account for nesting in setting INCONSTRUCTOR
This flag is calcualed in Namers, and assigned to class and module class symbols that are defined in self/super-calls, and in early definitions. For example, class D is INCONSTRUCTOR in each case below: class C extends Super({class D; ()}) class C(a: Any) { def this(a: Any) = this({class D; ()}) } new { val x = { class D; () } with Super(()) But, the calculation of this flag failed to account for nesting, so it was not set in cases like: class C(a: Any) { def this(a: Any) = this({val x = {class D; ()}; x}) } This patch searches the enclosing context chain, rather than just the immediate context. The search is terminated at the first non term-owned context. In the following example, this avoids marking `E` as INCONSTRUCTOR; only `D` should be. class C extends Super({class D { class E }; ()}) This closes SI-6259 and SI-6506, and fixes one problem in the recently reopened SI-6957.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala9
-rw-r--r--test/files/run/t6259.scala2
-rw-r--r--test/files/run/t6506.scala8
-rw-r--r--test/files/run/t6666a.scala16
-rw-r--r--test/files/run/t6957.scala8
5 files changed, 39 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 98b6264051..967a3214f2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -123,9 +123,12 @@ trait Namers extends MethodSynthesis {
def setPrivateWithin(tree: MemberDef, sym: Symbol): Symbol =
setPrivateWithin(tree, sym, tree.mods)
- def inConstructorFlag: Long =
- if (owner.isConstructor && !context.inConstructorSuffix || owner.isEarlyInitialized) INCONSTRUCTOR
- else 0l
+ def inConstructorFlag: Long = {
+ val termOwnedContexts: List[Context] = context.enclosingContextChain.takeWhile(_.owner.isTerm)
+ val constructorNonSuffix = termOwnedContexts exists (c => c.owner.isConstructor && !c.inConstructorSuffix)
+ val earlyInit = termOwnedContexts exists (_.owner.isEarlyInitialized)
+ if (constructorNonSuffix || earlyInit) INCONSTRUCTOR else 0L
+ }
def moduleClassFlags(moduleFlags: Long) =
(moduleFlags & ModuleToClassFlags) | inConstructorFlag
diff --git a/test/files/run/t6259.scala b/test/files/run/t6259.scala
index a5a7bf9043..294c95e96b 100644
--- a/test/files/run/t6259.scala
+++ b/test/files/run/t6259.scala
@@ -48,7 +48,7 @@ object Test extends App {
val e = new E {}; e.F
val g = new G; g.H
- //locally(HasX.x) TODO sort out VerifyError in HasX$InVal$2$.<init> by accounting for nesting in Namer#inConstructorFlag
+ locally(HasX.x)
// locally(Early.x) TODO sort out VerifyError in Early$.<init>
// DoubleOk TODO sort out VerifyError in DoubleOk$.<init>
}
diff --git a/test/files/run/t6506.scala b/test/files/run/t6506.scala
new file mode 100644
index 0000000000..04d77c3c16
--- /dev/null
+++ b/test/files/run/t6506.scala
@@ -0,0 +1,8 @@
+object Test {
+ def main(args: Array[String]) {
+ new WL(new {} #:: S) with T
+ }
+ object S { def #::(a: Any): Any = () }
+ trait T
+ class WL(a: Any)
+}
diff --git a/test/files/run/t6666a.scala b/test/files/run/t6666a.scala
new file mode 100644
index 0000000000..1d208a32e7
--- /dev/null
+++ b/test/files/run/t6666a.scala
@@ -0,0 +1,16 @@
+class A(a: Any)
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ }
+
+ val x: Unit = {
+ object InVal extends A({
+ new {} // okay
+ val o = {new {}} // nesting triggers a VerifyError.
+ null
+ });
+ InVal;
+ ()
+ };
+}
diff --git a/test/files/run/t6957.scala b/test/files/run/t6957.scala
new file mode 100644
index 0000000000..d0bf8e7b5e
--- /dev/null
+++ b/test/files/run/t6957.scala
@@ -0,0 +1,8 @@
+object Test {
+ def main(args: Array[String]) {
+ class Foo
+ class Parent(f:Foo)
+ class Child extends Parent({val x=new Foo{}; x})
+ new Child
+ }
+}