diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-08-28 15:51:49 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-09-11 23:22:07 +0200 |
commit | f04257b8414745d8e13bee213e551ef01c839602 (patch) | |
tree | 88ebb2e730d7958c7061d660c0b5c66ab02610e3 /src | |
parent | c2dc34640c9fd06abda91266ca21160bb423bf41 (diff) | |
download | scala-f04257b8414745d8e13bee213e551ef01c839602.tar.gz scala-f04257b8414745d8e13bee213e551ef01c839602.tar.bz2 scala-f04257b8414745d8e13bee213e551ef01c839602.zip |
SI-3832 Don't lift methods in aux constructor trailing stats as STATIC
SI-1909 modified LambdaLift to lift in auxiliary constructors methods as STATIC
so they could be called before the self-constructor was called.
That allowed for:
class Foo (x: Int) {
def this() = this( {
def bar() = 5
bar
})
}
However, if the method is in a statement that trails the self constructor call,
this is unnecessary and in fact incorrect as it robs the lifted method of `this`.
This commit uses the machinery established in SI-6666 to limit the STATIC-ness
of lifted methods to those used in arguments for self-constructor calls.
This is used exclusively; the `isAuxillaryConstructor` check wasn't the right
way to solve this, as was seen by the regression it caused in SI-3832.
A new test case shows that we can statically lift methods in super-constructor
calls, rather than just self-constructor calls.
We also have to avoid statically lifting objects in these positions. For now,
I just emit a dev warning that a VerifyError is in your future. With some more
thought we could escalate that to a implementation restriction and emit an error.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LambdaLift.scala | 11 |
1 files changed, 9 insertions, 2 deletions
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 |