Skip to content

Commit 5994bfa

Browse files
committed
Fix #5350: Fix purity of local lazy vals
1 parent 0b5d67f commit 5994bfa

File tree

4 files changed

+21
-1
lines changed

4 files changed

+21
-1
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,12 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
400400
def isKnownPureOp(sym: Symbol) =
401401
sym.owner.isPrimitiveValueClass || sym.owner == defn.StringClass
402402
if (tree.tpe.isInstanceOf[ConstantType] && isKnownPureOp(tree.symbol) // A constant expression with pure arguments is pure.
403-
|| fn.symbol.isStable
403+
|| (fn.symbol.isStable && !fn.symbol.is(Lazy))
404404
|| fn.symbol.isPrimaryConstructor && fn.symbol.owner.isNoInitsClass) // TODO: include in isStable?
405405
minOf(exprPurity(fn), args.map(exprPurity)) `min` Pure
406406
else if (fn.symbol.is(Erased)) Pure
407+
else if (fn.symbol.isStable /* && fn.symbol.is(Lazy) */)
408+
minOf(exprPurity(fn), args.map(exprPurity)) `min` Idempotent
407409
else Impure
408410
case Typed(expr, _) =>
409411
exprPurity(expr)

compiler/test-resources/repl/i5350

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
scala> def foo = { lazy val bar: Unit = { println("Hello") }; bar }
2+
def foo: Unit
3+
scala> foo
4+
Hello
5+
scala> { lazy val bar: Unit = { println("Hello") }; bar }
6+
Hello
7+
val bar: Unit = <lazy>

tests/run/i5350.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello

tests/run/i5350.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Test {
2+
def foo = {
3+
lazy val bar: Unit = println("Hello")
4+
bar
5+
}
6+
7+
def main(args: Array[String]): Unit = {
8+
foo
9+
}
10+
}

0 commit comments

Comments
 (0)