summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-09-15 07:21:26 -0700
committerJason Zaugg <jzaugg@gmail.com>2013-09-15 07:21:26 -0700
commitc2f7ce5cbbc3ccd086764e49c47e139786e0ab24 (patch)
tree5779d4b901132c164a94e75f52916fb2cf3bdc92 /src
parentf3d9bdc283a82b816218aefc3df7d287e0cdd271 (diff)
parent27d73ee7a92d8dd10d4d0598a29d3a3657053995 (diff)
downloadscala-c2f7ce5cbbc3ccd086764e49c47e139786e0ab24.tar.gz
scala-c2f7ce5cbbc3ccd086764e49c47e139786e0ab24.tar.bz2
scala-c2f7ce5cbbc3ccd086764e49c47e139786e0ab24.zip
Merge pull request #2884 from retronym/ticket/3832
SI-1909 SI-3832 SI-7007 SI-7223 Improved handling of larval objects
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala17
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala19
4 files changed, 32 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 8c2eb3334f..a2bf5bf9e5 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -216,7 +216,7 @@ abstract class ExplicitOuter extends InfoTransform
* values for outer parameters of constructors.
* The class provides methods for referencing via outer.
*/
- abstract class OuterPathTransformer(unit: CompilationUnit) extends TypingTransformer(unit) {
+ abstract class OuterPathTransformer(unit: CompilationUnit) extends TypingTransformer(unit) with UnderConstructionTransformer {
/** The directly enclosing outer parameter, if we are in a constructor */
protected var outerParam: Symbol = NoSymbol
@@ -277,16 +277,6 @@ abstract class ExplicitOuter extends InfoTransform
}
- /** The stack of class symbols in which a call to this() or to the super
- * constructor, or early definition is active
- */
- protected def isUnderConstruction(clazz: Symbol) = selfOrSuperCalls contains clazz
- protected val selfOrSuperCalls = mutable.Stack[Symbol]()
- @inline protected def inSelfOrSuperCall[A](sym: Symbol)(a: => A) = {
- selfOrSuperCalls push sym
- try a finally selfOrSuperCalls.pop()
- }
-
override def transform(tree: Tree): Tree = {
val savedOuterParam = outerParam
try {
@@ -300,10 +290,7 @@ abstract class ExplicitOuter extends InfoTransform
}
case _ =>
}
- if ((treeInfo isSelfOrSuperConstrCall tree) || (treeInfo isEarlyDef tree))
- inSelfOrSuperCall(currentOwner.owner)(super.transform(tree))
- else
- super.transform(tree)
+ super.transform(tree)
}
finally outerParam = savedOuterParam
}
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 515fa66cfa..acef2a50d8 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -436,8 +436,15 @@ abstract class LambdaLift extends InfoTransform {
private def liftDef(tree: Tree): Tree = {
val sym = tree.symbol
val oldOwner = sym.owner
- if (sym.owner.isAuxiliaryConstructor && sym.isMethod) // # bug 1909
- sym setFlag STATIC
+ if (sym.isMethod && isUnderConstruction(sym.owner.owner)) { // # bug 1909
+ if (sym.isModule) { // Yes, it can be a module and a method, see comments on `isModuleNotMethod`!
+ // TODO promote to an implementation restriction if we can reason that this *always* leads to VerifyError.
+ // See neg/t1909-object.scala
+ def msg = s"SI-1909 Unable to STATICally lift $sym, which is defined in the self- or super-constructor call of ${sym.owner.owner}. A VerifyError is likely."
+ devWarning(tree.pos, msg)
+ } else sym setFlag STATIC
+ }
+
sym.owner = sym.owner.enclClass
if (sym.isClass) sym.owner = sym.owner.toInterface
if (sym.isMethod) sym setFlag LIFTED
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 454f913412..9ac0b0835a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -135,7 +135,8 @@ trait Namers extends MethodSynthesis {
setPrivateWithin(tree, sym, tree.mods)
def inConstructorFlag: Long = {
- val termOwnedContexts: List[Context] = context.enclosingContextChain.takeWhile(_.owner.isTerm)
+ val termOwnedContexts: List[Context] =
+ context.enclosingContextChain.takeWhile(c => c.owner.isTerm && !c.owner.isAnonymousFunction)
val constructorNonSuffix = termOwnedContexts exists (c => c.owner.isConstructor && !c.inConstructorSuffix)
val earlyInit = termOwnedContexts exists (_.owner.isEarlyInitialized)
if (constructorNonSuffix || earlyInit) INCONSTRUCTOR else 0L
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index a54f86bdde..38f1f0f725 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -1606,6 +1606,25 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
+ /** Tracks the classes currently under construction during a transform */
+ trait UnderConstructionTransformer extends Transformer {
+ import collection.mutable
+
+ protected def isUnderConstruction(clazz: Symbol) = selfOrSuperCalls contains clazz
+
+ /** The stack of class symbols in which a call to this() or to the super
+ * constructor, or early definition is active */
+ private val selfOrSuperCalls = mutable.Stack[Symbol]()
+
+ abstract override def transform(tree: Tree) = {
+ if ((treeInfo isSelfOrSuperConstrCall tree) || (treeInfo isEarlyDef tree)) {
+ selfOrSuperCalls push currentOwner.owner
+ try super.transform(tree)
+ finally selfOrSuperCalls.pop()
+ } else super.transform(tree)
+ }
+ }
+
def duplicateAndKeepPositions(tree: Tree) = new Duplicator(focusPositions = false) transform tree
// ------ copiers -------------------------------------------