Skip to content

Commit 675779e

Browse files
authored
Merge pull request #7435 from dotty-staging/fix-#7434
Fix #7434: Tighten a condition in LazyVals
2 parents 34bb622 + af1bde2 commit 675779e

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

compiler/src/dotty/tools/dotc/transform/LazyVals.scala

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import dotty.tools.dotc.core.Contexts.Context
99
import dotty.tools.dotc.core.Decorators._
1010
import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
1111
import dotty.tools.dotc.core.Flags._
12-
import dotty.tools.dotc.core.NameKinds.{LazyBitMapName, LazyLocalInitName, LazyLocalName}
12+
import dotty.tools.dotc.core.NameKinds.{LazyBitMapName, LazyLocalInitName, LazyLocalName, ExpandedName}
1313
import dotty.tools.dotc.core.StdNames.nme
1414
import dotty.tools.dotc.core.Symbols._
1515
import dotty.tools.dotc.core.Types._
@@ -73,7 +73,18 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
7373
else {
7474
val isField = sym.owner.isClass
7575
if (isField)
76-
if (sym.isAllOf(SyntheticModule))
76+
if sym.isAllOf(SyntheticModule)
77+
&& sym.allOverriddenSymbols.isEmpty
78+
&& !sym.name.is(ExpandedName) then
79+
// I am not sure what the conditions for this optimization should be.
80+
// It was applied for all synthetic objects, but this is clearly false, as t704 demonstrates.
81+
// It seems we have to at least exclude synthetic objects that derive from mixins.
82+
// This is done by demanding that the object does not override anything.
83+
// Figuring out whether a symbol implements a trait module is not so simple.
84+
// For non-private trait members we can check whether there is an overridden symbol.
85+
// For private trait members this does not work, since `ensureNotPrivate` in phase Mixins
86+
// does change the name but does not update the owner's scope, so `allOverriddenSymbols` does
87+
// not work in that case. However, we can check whether the name is an ExpandedName instead.
7788
transformSyntheticModule(tree)
7889
else if (sym.isThreadUnsafe || ctx.settings.scalajs.value)
7990
if (sym.is(Module) && !ctx.settings.scalajs.value) {

tests/run/t704.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
xxxx should appear twice
2+
zzzz should appear twice
3+
yyyy should appear twice
4+
xxxx should appear twice
5+
zzzz should appear twice
6+
yyyy should appear twice

tests/pos/t704.scala renamed to tests/run/t704.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,27 @@ trait D {
22
private val x = "xxxx should appear twice"
33
private object xxxx { Console.println(x) }
44
def get_xxxx: AnyRef = xxxx
5+
6+
private val z = "zzzz should appear twice"
7+
private lazy val zzzz = new ZZZZ
8+
class ZZZZ { Console.println(z) }
9+
def get_zzzz: AnyRef = zzzz
510
}
611

712
trait E extends D {
813
def f(): Unit = {
914
val y = "yyyy should appear twice"
1015
object yyyy {
1116
val x1 = get_xxxx
17+
val z1 = get_zzzz
1218
Console.println(y)
1319
}
1420
yyyy
1521
}
1622
}
1723
class C extends E {}
18-
object Go extends D {
24+
object Test extends D {
25+
object E
1926
def main(args : Array[String]): Unit = {
2027
new C().f()
2128
new C().f()

0 commit comments

Comments
 (0)