Skip to content

Commit f56089b

Browse files
authored
Stabilize new lazy vals (#16614)
Resolve #16555
2 parents 7337b6f + cd5e644 commit f56089b

File tree

11 files changed

+12
-38
lines changed

11 files changed

+12
-38
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ private sealed trait YSettings:
365365
val YshowTreeIds: Setting[Boolean] = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
366366
val YfromTastyIgnoreList: Setting[List[String]] = MultiStringSetting("-Yfrom-tasty-ignore-list", "file", "List of `tasty` files in jar files that will not be loaded when using -from-tasty")
367367
val YnoExperimental: Setting[Boolean] = BooleanSetting("-Yno-experimental", "Disable experimental language features")
368+
val YlegacyLazyVals: Setting[Boolean] = BooleanSetting("-Ylegacy-lazy-vals", "Use legacy (pre 3.3.0) implementation of lazy vals")
368369

369370
val YprofileEnabled: Setting[Boolean] = BooleanSetting("-Yprofile-enabled", "Enable profiling.")
370371
val YprofileDestination: Setting[String] = StringSetting("-Yprofile-destination", "file", "Where to send profiling output - specify a file, default is to the console.", "")
@@ -382,7 +383,6 @@ private sealed trait YSettings:
382383
val YrecheckTest: Setting[Boolean] = BooleanSetting("-Yrecheck-test", "Run basic rechecking (internal test only)")
383384
val YccDebug: Setting[Boolean] = BooleanSetting("-Ycc-debug", "Used in conjunction with captureChecking language import, debug info for captured references")
384385
val YccNoAbbrev: Setting[Boolean] = BooleanSetting("-Ycc-no-abbrev", "Used in conjunction with captureChecking language import, suppress type abbreviations")
385-
val YlightweightLazyVals: Setting[Boolean] = BooleanSetting("-Ylightweight-lazy-vals", "Use experimental lightweight implementation of lazy vals")
386386

387387
/** Area-specific debug output */
388388
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

+3-3
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,10 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
448448

449449
def transformMemberDefThreadSafe(x: ValOrDefDef)(using Context): Thicket = {
450450
assert(!(x.symbol is Mutable))
451-
if ctx.settings.YlightweightLazyVals.value then
452-
transformMemberDefThreadSafeNew(x)
453-
else
451+
if ctx.settings.YlegacyLazyVals.value then
454452
transformMemberDefThreadSafeLegacy(x)
453+
else
454+
transformMemberDefThreadSafeNew(x)
455455
}
456456

457457
def transformMemberDefThreadSafeNew(x: ValOrDefDef)(using Context): Thicket = {

compiler/test/dotc/run-lazy-vals-tests.allowlist

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ null-lazy-val.scala
3838
patmatch-classtag.scala
3939
priorityQueue.scala
4040
serialization-new-legacy.scala
41-
serialization-new.scala
4241
singletons.scala
4342
statics.scala
4443
stream_flatmap_odds.scala

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(88, instructionsFromMethod(method).size)
600+
assertEquals(23, instructionsFromMethod(method).size)
601601
}
602602
}
603603

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class CompilationTests {
4444
compileFilesInDir("tests/pos-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking")),
4545
compileFilesInDir("tests/pos-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions")),
4646
compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init")),
47-
// Run tests for experimental lightweight lazy vals
48-
compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init", "-Ylightweight-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.posLazyValsAllowlist)),
47+
// Run tests for legacy lazy vals
48+
compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init", "-Ylegacy-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.posLazyValsAllowlist)),
4949
compileFilesInDir("tests/pos-deep-subtype", allowDeepSubtypes),
5050
compileFilesInDir("tests/pos-custom-args/no-experimental", defaultOptions.and("-Yno-experimental")),
5151
compileDir("tests/pos-special/java-param-names", defaultOptions.withJavacOnlyOptions("-parameters")),
@@ -212,9 +212,9 @@ class CompilationTests {
212212
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")),
213213
compileFilesInDir("tests/run-custom-args/captures", allowDeepSubtypes.and("-language:experimental.captureChecking")),
214214
compileFilesInDir("tests/run-deep-subtype", allowDeepSubtypes),
215-
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init"), FileFilter.exclude("serialization-new.scala")),
216-
// Run tests for experimental lightweight lazy vals and stable lazy vals.
217-
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init", "-Ylightweight-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.runLazyValsAllowlist)),
215+
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init")),
216+
// Run tests for legacy lazy vals.
217+
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init", "-Ylegacy-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.runLazyValsAllowlist)),
218218
).checkRuns()
219219
}
220220

library/src/scala/runtime/LazyVals.scala

-6
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,24 @@ object LazyVals {
4545

4646
/* ------------- Start of public API ------------- */
4747

48-
@experimental
4948
sealed trait LazyValControlState
5049

5150
/**
5251
* Used to indicate the state of a lazy val that is being
5352
* evaluated and of which other threads await the result.
5453
*/
55-
@experimental
5654
final class Waiting extends CountDownLatch(1) with LazyValControlState
5755

5856
/**
5957
* Used to indicate the state of a lazy val that is currently being
6058
* evaluated with no other thread awaiting its result.
6159
*/
62-
@experimental
6360
object Evaluating extends LazyValControlState
6461

6562
/**
6663
* Used to indicate the state of a lazy val that has been evaluated to
6764
* `null`.
6865
*/
69-
@experimental
7066
object NullValue extends LazyValControlState
7167

7268
final val BITS_PER_LAZY_VAL = 2L
@@ -86,7 +82,6 @@ object LazyVals {
8682
unsafe.compareAndSwapLong(t, offset, e, n)
8783
}
8884

89-
@experimental
9085
def objCAS(t: Object, offset: Long, exp: Object, n: Object): Boolean = {
9186
if (debug)
9287
println(s"objCAS($t, $exp, $n)")
@@ -147,7 +142,6 @@ object LazyVals {
147142
r
148143
}
149144

150-
@experimental
151145
def getStaticFieldOffset(field: java.lang.reflect.Field): Long = {
152146
@nowarn
153147
val r = unsafe.staticFieldOffset(field)

project/MiMaFilters.scala

-9
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,6 @@ object MiMaFilters {
55
val Library: Seq[ProblemFilter] = Seq(
66
ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.MappedAlternative"),
77

8-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.LazyVals.getStaticFieldOffset"),
9-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.LazyVals.objCAS"),
10-
ProblemFilters.exclude[MissingClassProblem]("scala.runtime.LazyVals$LazyValControlState"),
11-
ProblemFilters.exclude[MissingClassProblem]("scala.runtime.LazyVals$Evaluating$"),
12-
ProblemFilters.exclude[MissingClassProblem]("scala.runtime.LazyVals$NullValue$"),
13-
ProblemFilters.exclude[MissingClassProblem]("scala.runtime.LazyVals$Waiting"),
14-
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.LazyVals.Evaluating"),
15-
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.LazyVals.NullValue"),
16-
178
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language#experimental.into"),
189
ProblemFilters.exclude[MissingClassProblem]("scala.runtime.stdLibPatches.language$experimental$into$"),
1910
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language#experimental.pureFunctions"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Ylegacy-lazy-vals

tests/printing/transformed/lazy-vals-new.flags

-1
This file was deleted.

tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala

-10
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,6 @@ val experimentalDefinitionInLibrary = Set(
7676
"scala.quoted.Quotes.reflectModule.SymbolModule.newClass",
7777
"scala.quoted.Quotes.reflectModule.SymbolModule.freshName",
7878
"scala.quoted.Quotes.reflectModule.SymbolMethods.info",
79-
80-
// New APIs: Lightweight lazy vals. Can be stabilized in 3.3.0
81-
"scala.runtime.LazyVals$.Evaluating",
82-
"scala.runtime.LazyVals$.Evaluating$",
83-
"scala.runtime.LazyVals$.LazyValControlState",
84-
"scala.runtime.LazyVals$.NullValue",
85-
"scala.runtime.LazyVals$.NullValue$",
86-
"scala.runtime.LazyVals$.Waiting",
87-
"scala.runtime.LazyVals$.getStaticFieldOffset",
88-
"scala.runtime.LazyVals$.objCAS"
8979
)
9080

9181

0 commit comments

Comments
 (0)