From f04257b8414745d8e13bee213e551ef01c839602 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 28 Aug 2013 15:51:49 +0200 Subject: 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. --- src/compiler/scala/tools/nsc/transform/LambdaLift.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') 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 -- cgit v1.2.3