Skip to content

Commit c975760

Browse files
authored
Merge pull request #5703 from dotty-staging/fix-#5350
Fix #5350: Fix purity of local lazy vals
2 parents 634b54c + ec3b3e1 commit c975760

File tree

12 files changed

+61
-6
lines changed

12 files changed

+61
-6
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/src/dotty/tools/dotc/printing/ReplPrinter.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ReplPrinter(_ctx: Context) extends DecompilerPrinter(_ctx) {
2929
else Str(const.value.toString)
3030

3131
override def dclText(sym: Symbol): Text = {
32+
("lazy": Text).provided(sym.is(Lazy)) ~~
3233
toText(sym) ~ {
3334
if (sym.is(Method)) toText(sym.info)
3435
else if (sym.isType && sym.info.isTypeAlias) toText(sym.info)

compiler/src/dotty/tools/repl/Rendering.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,8 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None) {
7676
val dcl = d.symbol.showUser
7777

7878
try {
79-
val resultValue =
80-
if (d.symbol.is(Flags.Lazy)) Some("<lazy>")
81-
else valueOf(d.symbol)
82-
83-
resultValue.map(value => s"$dcl = $value")
79+
if (d.symbol.is(Flags.Lazy)) Some(dcl)
80+
else valueOf(d.symbol).map(value => s"$dcl = $value")
8481
}
8582
catch { case ex: InvocationTargetException => Some(renderError(ex)) }
8683
}

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+
lazy val bar: Unit

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+
}

tests/run/i5350b.check

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

tests/run/i5350b.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: Unit = {
3+
object bar { println("Hello") }
4+
bar
5+
}
6+
7+
def main(args: Array[String]): Unit = {
8+
foo
9+
}
10+
}

tests/run/i5350c.check

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

tests/run/i5350c.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: Unit = {
3+
bar
4+
}
5+
6+
def main(args: Array[String]): Unit = {
7+
foo
8+
}
9+
}
10+
object bar { println("Hello") }

tests/run/i5350d.check

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

tests/run/i5350d.scala

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

0 commit comments

Comments
 (0)