Skip to content

Commit 937424a

Browse files
committed
Fix failing testCompilation tests for new lazy vals
Pre-review lazy vals adjustments
1 parent 81094be commit 937424a

30 files changed

+942
-87
lines changed

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/InitializedAccess.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ class InitializedAccess {
2727
bh.consume(holder)
2828
bh.consume(holder.value)
2929
}
30-
}
30+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/InitializedAccessAny.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ class InitializedAccessAny {
2727
bh.consume(holder)
2828
bh.consume(holder.value)
2929
}
30-
}
30+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/InitializedAccessGeneric.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ class InitializedAccessGeneric {
2727
bh.consume(holder)
2828
bh.consume(holder.value)
2929
}
30-
}
30+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/InitializedAccessMultiple.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ class InitializedAccessMultiple {
3131
i = i + 1
3232
}
3333
}
34-
}
34+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/InitializedAccessString.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ class InitializedAccessString {
2727
bh.consume(holder)
2828
bh.consume(holder.value)
2929
}
30-
}
30+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/LazyVals.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ object LazyVals {
5050
}
5151
}
5252
}
53-
}
53+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/UninitializedAccess.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ class UninitializedAccess {
2222
bh.consume(holder.value)
2323
i = i + 1
2424
}
25-
}
25+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/UninitializedAccessMultiple.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ class UninitializedAccessMultiple {
2424
i = i + 1
2525
}
2626
}
27-
}
27+
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import Types._, Contexts._, Flags._
77
import Symbols._, Annotations._, Trees._, Symbols._, Constants.Constant
88
import Decorators._
99
import dotty.tools.dotc.transform.SymUtils._
10-
import transform.LazyVals
1110

1211
/** A map that applies three functions and a substitution together to a tree and
1312
* makes sure they are coordinated so that the result is well-typed. The functions are

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ private sealed trait XSettings:
241241
val XcheckMacros: Setting[Boolean] = BooleanSetting("-Xcheck-macros", "Check some invariants of macro generated code while expanding macros", aliases = List("--Xcheck-macros"))
242242
val XmainClass: Setting[String] = StringSetting("-Xmain-class", "path", "Class for manifest's Main-Class entry (only useful with -d <jar>)", "")
243243
val XimplicitSearchLimit: Setting[Int] = IntSetting("-Ximplicit-search-limit", "Maximal number of expressions to be generated in an implicit search", 50000)
244-
val XlegacyLazyVals: Setting[Boolean] = BooleanSetting("-Xlegacy-lazy-values", "Use legacy lazy vals implementations")
245244

246245
val XmixinForceForwarders = ChoiceSetting(
247246
name = "-Xmixin-force-forwarders",
@@ -331,6 +330,7 @@ private sealed trait YSettings:
331330
val YrecheckTest: Setting[Boolean] = BooleanSetting("-Yrecheck-test", "Run basic rechecking (internal test only)")
332331
val YccDebug: Setting[Boolean] = BooleanSetting("-Ycc-debug", "Used in conjunction with captureChecking language import, debug info for captured references")
333332
val YccNoAbbrev: Setting[Boolean] = BooleanSetting("-Ycc-no-abbrev", "Used in conjunction with captureChecking language import, suppress type abbreviations")
333+
val YlightweightLazyVals: Setting[Boolean] = BooleanSetting("-Ylightweight-lazy-vals", "Use experimental lightweight implementation of lazy vals")
334334

335335
/** Area-specific debug output */
336336
val YexplainLowlevel: Setting[Boolean] = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")

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

+27-22
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@ package dotty.tools.dotc
22
package transform
33

44
import java.util.IdentityHashMap
5-
65
import ast.tpd
76
import core.Annotations.Annotation
87
import core.Constants.Constant
9-
import core.Contexts._
10-
import core.Decorators._
8+
import core.Contexts.*
9+
import core.Decorators.*
1110
import core.DenotTransformers.IdentityDenotTransformer
12-
import core.Flags._
13-
import core.NameKinds.{LazyBitMapName, LazyLocalInitName, LazyLocalName, ExpandedName}
11+
import core.Flags.*
12+
import core.NameKinds.{ExpandedName, LazyBitMapName, LazyLocalInitName, LazyLocalName}
1413
import core.StdNames.nme
15-
import core.Symbols._
16-
import core.Types._
14+
import core.Symbols.*
15+
import core.Types.*
1716
import core.{Names, StdNames}
17+
import dotty.tools.dotc.config.Feature
1818
import transform.MegaPhase.MiniPhase
19-
import transform.SymUtils._
19+
import transform.SymUtils.*
20+
2021
import scala.collection.mutable
2122

2223
class LazyVals extends MiniPhase with IdentityDenotTransformer {
@@ -59,9 +60,6 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
5960
else nullables.toList
6061
}
6162

62-
private inline def isLegacyLazyVals(using ctx: Context): Boolean =
63-
ctx.settings.XlegacyLazyVals.value
64-
6563
private def needsBoxing(tp: Type)(using Context): Boolean = tp != NoType && tp != defn.UnitType && tp.classSymbol.isPrimitiveValueClass
6664

6765
private def boxIfCan(tp: Type)(using Context): Type =
@@ -120,7 +118,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
120118
*/
121119
override def transformTemplate(template: Template)(using Context): Tree = {
122120
val cls = ctx.owner.asClass
123-
(if isLegacyLazyVals then oldAppendOffsetDefs else appendOffsetDefs).get(cls) match {
121+
(if !ctx.settings.YlightweightLazyVals.value then oldAppendOffsetDefs else appendOffsetDefs).get(cls) match {
124122
case None => template
125123
case Some(data) =>
126124
data.defs.foreach(_.symbol.addAnnotation(Annotation(defn.ScalaStaticAnnot)))
@@ -338,10 +336,15 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
338336
* val current: AnyRef = _x
339337
* if current == null then
340338
* if CAS(_x, null, Evaluating) then
339+
* var resultNullable: AnyRef = null
341340
* var result: AnyRef = null
342341
* try
342+
* resultNullable = rhs
343343
* nullable = null
344-
* if result == null then result = NullValue
344+
* if resultNullable == null then
345+
* result = NullValue
346+
* else
347+
* result = resultNullable
345348
* return result
346349
* finally
347350
* if !CAS(_x, Evaluating, result) then
@@ -417,6 +420,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
417420
// if observed a null (uninitialized) value
418421
val initialize = {
419422
// var result: AnyRef
423+
val resSymbNullable = newSymbol(lazyInitMethodSymbol, lazyNme.resultNullable, Synthetic | Mutable, defn.ObjectType)
420424
val resSymb = newSymbol(lazyInitMethodSymbol, lazyNme.result, Synthetic | Mutable, defn.ObjectType)
421425
// releasing block in finally
422426
val lockRel = {
@@ -430,26 +434,26 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
430434
objCasFlag.appliedTo(thiz, offset, evaluating, ref(resSymb)).select(nme.UNARY_!).appliedToNone,
431435
lockRel,
432436
unitLiteral
433-
) :: Nil, Return(ref(resSymb), lazyInitMethodSymbol)).withType(defn.UnitType)
437+
) :: Nil, unitLiteral).withType(defn.UnitType)
434438
// entire try block
435439
val evaluate = Try(
436440

437441
Block(
438-
(Assign(ref(resSymb), if needsBoxing(tp) && rhsMappedOwner != EmptyTree then rhsMappedOwner.ensureConforms(boxIfCan(tp)) else rhsMappedOwner) // try result = rhs
442+
(Assign(ref(resSymbNullable), if needsBoxing(tp) && rhsMappedOwner != EmptyTree then rhsMappedOwner.ensureConforms(boxIfCan(tp)) else rhsMappedOwner) // try result = rhs
439443
:: If(
440-
ref(resSymb).select(defn.Any_==).appliedTo(nullLiteral),
444+
ref(resSymbNullable).select(defn.Any_==).appliedTo(nullLiteral),
441445
Assign(ref(resSymb), nullValue),
442-
unitLiteral
446+
Assign(ref(resSymb), ref(resSymbNullable))
443447
) :: Nil)
444448
::: nullOut(nullableFor(accessorMethodSymbol)),
445-
unitLiteral),
449+
Return(ref(resSymbNullable), lazyInitMethodSymbol)),
446450
Nil,
447451
fin
448452
)
449453
// if CAS(_, null, Evaluating)
450454
If(
451455
objCasFlag.appliedTo(thiz, offset, nullLiteral, evaluating),
452-
Block(ValDef(resSymb, nullLiteral) :: Nil, // var result: AnyRef = null
456+
Block(ValDef(resSymb, nullLiteral) :: ValDef(resSymbNullable, nullLiteral) :: Nil, // var result: AnyRef = null
453457
evaluate), // try ... finally ...
454458
unitLiteral
455459
).withType(defn.UnitType)
@@ -490,10 +494,10 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
490494

491495
def transformMemberDefThreadSafe(x: ValOrDefDef)(using Context): Thicket = {
492496
assert(!(x.symbol is Mutable))
493-
if isLegacyLazyVals then
494-
transformMemberDefThreadSafeLegacy(x)
495-
else
497+
if ctx.settings.YlightweightLazyVals.value then
496498
transformMemberDefThreadSafeNew(x)
499+
else
500+
transformMemberDefThreadSafeLegacy(x)
497501
}
498502

499503
def transformMemberDefThreadSafeNew(x: ValOrDefDef)(using Context): Thicket = {
@@ -741,6 +745,7 @@ object LazyVals {
741745
val flag: TermName = "flag".toTermName
742746
val state: TermName = "state".toTermName
743747
val result: TermName = "result".toTermName
748+
val resultNullable: TermName = "resultNullable".toTermName
744749
val value: TermName = "value".toTermName
745750
val initialized: TermName = "initialized".toTermName
746751
val initialize: TermName = "initialize".toTermName
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Repeated.scala
2+
byname-implicits-8.scala
3+
existentials.scala
4+
i1235.scala
5+
i13332super.scala
6+
i13349.scala
7+
i13460.scala
8+
i14626.scala
9+
i1753.scala
10+
i4031.scala
11+
i4328.scala
12+
i6450.scala
13+
i6565.scala
14+
i8031.scala
15+
i8111.scala
16+
i8900-unflip.scala
17+
lazyvals.scala
18+
singletons.scala
19+
spec-traits.scala
20+
spurious-overload.scala
21+
t1591_pos.scala
22+
t2910.scala
23+
t3411.scala
24+
t3420.scala
25+
t3452f.scala
26+
t3670.scala
27+
t3927.scala
28+
t4432.scala
29+
t4716.scala
30+
t4717.scala
31+
t5099.scala
32+
t5796.scala
33+
t6278-synth-def.scala
34+
t6925b.scala
35+
t7011.scala
36+
t8306.scala
37+
zipped.scala
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# CI only: cannot reduce summonFrom with
2-
sip23-valueof.scala
2+
sip23-valueof.scala
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
IArrayOps.scala
2+
Lazies1.scala
3+
Lazies2.scala
4+
OrderingTest.scala
5+
anon-mirror-gen-local.scala
6+
byname-implicits-28.scala
7+
byname-implicits-30.scala
8+
byname-implicits-5.scala
9+
exports.scala
10+
i13146.scala
11+
i13146a.scala
12+
i13332a.scala
13+
i13332shapeless.scala
14+
i13358.scala
15+
i1692.scala
16+
i1692b.scala
17+
i1856.scala
18+
i2266.scala
19+
i2275.scala
20+
i4451.scala
21+
i4559.scala
22+
i5340.scala
23+
i5350.scala
24+
i7675.scala
25+
i9473.scala
26+
isInstanceOf-eval.scala
27+
lazy-exprs.scala
28+
lazy-impl.scala
29+
lazy-implicit-lists.scala
30+
lazy-override-run.scala
31+
lazy-traits.scala
32+
lazyVals.scala
33+
lazyVals_c3.0.0.scala
34+
lazyVals_c3.1.0.scala
35+
nonLocalReturns.scala
36+
nothing-lazy-val.scala
37+
null-lazy-val.scala
38+
patmatch-classtag.scala
39+
priorityQueue.scala
40+
serialization-new-legacy.scala
41+
serialization-new.scala
42+
singletons.scala
43+
statics.scala
44+
stream_flatmap_odds.scala
45+
t1535.scala
46+
t1591.scala
47+
t2333.scala
48+
t3038.scala
49+
t3670.scala
50+
t3699.scala
51+
t3877.scala
52+
t3895.scala
53+
t3980.scala
54+
t429.scala
55+
t5552.scala
56+
t5610a.scala
57+
t603.scala
58+
t6272.scala
59+
t6443-by-name.scala
60+
t6443-varargs.scala
61+
t704.scala
62+
t7406.scala
63+
t8245.scala
64+
unapply.scala
65+
unit-lazy-val.scala
66+
view-iterator-stream.scala

compiler/test/dotc/run-test-pickling.blacklist

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ i12753
4343
t6138
4444
t6138-2
4545
i12656.scala
46-
trait-static-forwarder
46+
trait-static-forwarder

compiler/test/dotc/run-test-recheck.excludes

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ i5976.scala
1010
tagless.scala
1111
safeThrowsStrawman2.scala
1212
t7584.scala
13-
function-arity.scala
13+
function-arity.scala

compiler/test/dotty/tools/TestSources.scala

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,26 @@ object TestSources {
1313

1414
def posFromTastyBlacklistFile: String = "compiler/test/dotc/pos-from-tasty.blacklist"
1515
def posTestPicklingBlacklistFile: String = "compiler/test/dotc/pos-test-pickling.blacklist"
16-
def posTestRecheckExcludesFile = "compiler/test/dotc/pos-test-recheck.excludes"
16+
def posTestRecheckExcludesFile: String = "compiler/test/dotc/pos-test-recheck.excludes"
17+
def posLazyValsAllowlistFile: String = "compiler/test/dotc/pos-lazy-vals-tests.allowlist"
1718

1819
def posFromTastyBlacklisted: List[String] = loadList(posFromTastyBlacklistFile)
1920
def posTestPicklingBlacklisted: List[String] = loadList(posTestPicklingBlacklistFile)
20-
def posTestRecheckExcluded = loadList(posTestRecheckExcludesFile)
21+
def posTestRecheckExcluded: List[String] = loadList(posTestRecheckExcludesFile)
22+
def posLazyValsAllowlist: List[String] = loadList(posLazyValsAllowlistFile)
2123

2224
// run tests lists
2325

2426
def runFromTastyBlacklistFile: String = "compiler/test/dotc/run-from-tasty.blacklist"
2527
def runTestPicklingBlacklistFile: String = "compiler/test/dotc/run-test-pickling.blacklist"
26-
def runTestRecheckExcludesFile = "compiler/test/dotc/run-test-recheck.excludes"
28+
def runTestRecheckExcludesFile: String = "compiler/test/dotc/run-test-recheck.excludes"
29+
def runLazyValsAllowlistFile: String = "compiler/test/dotc/run-lazy-vals-tests.allowlist"
30+
2731

2832
def runFromTastyBlacklisted: List[String] = loadList(runFromTastyBlacklistFile)
2933
def runTestPicklingBlacklisted: List[String] = loadList(runTestPicklingBlacklistFile)
30-
def runTestRecheckExcluded = loadList(runTestRecheckExcludesFile)
34+
def runTestRecheckExcluded: List[String] = loadList(runTestRecheckExcludesFile)
35+
def runLazyValsAllowlist: List[String] = loadList(runLazyValsAllowlistFile)
3136

3237
// load lists
3338

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ class DottyBytecodeTests extends DottyBytecodeTest {
597597
val clsIn = dir.lookupName("Test.class", directory = false).input
598598
val clsNode = loadClassNode(clsIn)
599599
val method = getMethod(clsNode, "test")
600-
assertEquals(118, instructionsFromMethod(method).size)
600+
assertEquals(88, instructionsFromMethod(method).size)
601601
}
602602
}
603603

compiler/test/dotty/tools/dotc/CompilationTests.scala

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class CompilationTests {
4343
compileFilesInDir("tests/pos-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking")),
4444
compileFilesInDir("tests/pos-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions")),
4545
compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init")),
46+
// Run tests for experimental lightweight lazy vals
47+
compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init", "-Ylightweight-lazy-vals"), FileFilter.include(TestSources.posLazyValsAllowlist)),
4648
compileFilesInDir("tests/pos-deep-subtype", allowDeepSubtypes),
4749
compileFilesInDir("tests/pos-custom-args/no-experimental", defaultOptions.and("-Yno-experimental")),
4850
compileDir("tests/pos-special/java-param-names", defaultOptions.withJavacOnlyOptions("-parameters")),
@@ -215,7 +217,9 @@ class CompilationTests {
215217
compileDir("tests/run-custom-args/Xmacro-settings/compileTimeEnv", defaultOptions.and("-Xmacro-settings:a,b=1,c.b.a=x.y.z=1,myLogger.level=INFO")),
216218
compileFilesInDir("tests/run-custom-args/captures", allowDeepSubtypes.and("-language:experimental.captureChecking")),
217219
compileFilesInDir("tests/run-deep-subtype", allowDeepSubtypes),
218-
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init"))
220+
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init"), FileFilter.exclude("serialization-new.scala")),
221+
// Run tests for experimental lightweight lazy vals and stable lazy vals.
222+
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init", "-Ylightweight-lazy-vals"), FileFilter.include(TestSources.runLazyValsAllowlist)),
219223
).checkRuns()
220224
}
221225

0 commit comments

Comments
 (0)