From 903478337c9b83ea9317d1dab311c62f654a7a45 Mon Sep 17 00:00:00 2001 From: Hubert Plociniczak Date: Tue, 9 Nov 2010 11:04:39 +0000 Subject: Closes #3980. Review by dragos. --- src/compiler/scala/tools/nsc/transform/LazyVals.scala | 19 +++++++++++++------ test/files/run/t3980.check | 3 +++ test/files/run/t3980.scala | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 test/files/run/t3980.check create mode 100644 test/files/run/t3980.scala diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala index 84916606a3..2ab7daa901 100644 --- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala +++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala @@ -17,6 +17,8 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD def newTransformer(unit: CompilationUnit): Transformer = new LazyValues(unit) + private def lazyUnit(sym: Symbol) = sym.tpe.resultType.typeSymbol == UnitClass + object LocalLazyValFinder extends Traverser { var result: Boolean = _ @@ -29,6 +31,10 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD case v@ValDef(_, _, _, _) if v.symbol.isLazy => result = true + case d@DefDef(_, _, _, _, _, _) if d.symbol.isLazy && lazyUnit(d.symbol) => + d.symbol.resetFlag(symtab.Flags.LAZY) + result = true + case ClassDef(_, _, _, _) | DefDef(_, _, _, _, _, _) | ModuleDef(_, _, _) => case LabelDef(name, _, _) if nme.isLoopHeaderLabel(name) => @@ -70,8 +76,8 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD if (sym.enclMethod == NoSymbol) sym.owner else sym.enclMethod val idx = lazyVals(enclosingDummyOrMethod) lazyVals(enclosingDummyOrMethod) = idx + 1 - val rhs1 = mkLazyDef(enclosingDummyOrMethod, super.transform(rhs), idx) - sym.resetFlag(LAZY | ACCESSOR) + val rhs1 = mkLazyDef(enclosingDummyOrMethod, super.transform(rhs), idx, sym) + sym.resetFlag((if (lazyUnit(sym)) 0 else LAZY) | ACCESSOR) rhs1 } else super.transform(rhs) @@ -180,16 +186,17 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD * () * } */ - private def mkLazyDef(meth: Symbol, tree: Tree, offset: Int): Tree = { + private def mkLazyDef(meth: Symbol, tree: Tree, offset: Int, lazyVal: Symbol): Tree = { val bitmapSym = getBitmapFor(meth, offset) val mask = LIT(1 << (offset % FLAGS_PER_WORD)) def mkBlock(stmt: Tree) = BLOCK(stmt, mkSetFlag(bitmapSym, mask), UNIT) val (block, res) = tree match { - case Block(List(assignment), res) => (mkBlock(assignment), res) - case rhs => (mkBlock(rhs), UNIT) + case Block(List(assignment), res) if !lazyUnit(lazyVal) => + (mkBlock(assignment), res) + case rhs => + (mkBlock(rhs), UNIT) } - assert(res != UNIT || meth.tpe.finalResultType.typeSymbol == UnitClass) val cond = (Ident(bitmapSym) INT_& mask) INT_== ZERO diff --git a/test/files/run/t3980.check b/test/files/run/t3980.check new file mode 100644 index 0000000000..8bb03f18bb --- /dev/null +++ b/test/files/run/t3980.check @@ -0,0 +1,3 @@ +once +2 +2 diff --git a/test/files/run/t3980.scala b/test/files/run/t3980.scala new file mode 100644 index 0000000000..c140176ce4 --- /dev/null +++ b/test/files/run/t3980.scala @@ -0,0 +1,19 @@ +object A { + def run1 { + lazy val x: Unit = {(); println("once")} + x + x + } + def run2 { + lazy val y: Int = 2 + println(y) + println(y) + } +} + +object Test { + def main(args: Array[String]) = { + A.run1 + A.run2 + } +} \ No newline at end of file -- cgit v1.2.3