diff --git a/docs/_docs/reference/experimental/explicit-nulls.md b/docs/_docs/reference/experimental/explicit-nulls.md index bb432ba1baea..52c807f581d0 100644 --- a/docs/_docs/reference/experimental/explicit-nulls.md +++ b/docs/_docs/reference/experimental/explicit-nulls.md @@ -457,6 +457,31 @@ See [more examples](https://github.com/scala/scala3/blob/main/tests/explicit-nul Currently, we are unable to track paths with a mutable variable prefix. For example, `x.a` if `x` is mutable. +### Tracking Mutable Fields with `@stableNull` + +By default, mutable class fields (`var`) are not tracked by flow typing, because a concurrent +assignment could set the field to `null` between the null check and its subsequent use. +To opt into flow typing for a mutable field, annotate it with +`scala.annotation.stableNull`. +The field will then be tracked whenever it is accessed through a stable prefix. + +```scala +import scala.annotation.stableNull + +class A: + @stableNull private var s: String | Null = null + def getS: String = + if s == null then s = "" + s // s: String +``` + +**Warning:** `@stableNull` can break null safety. The compiler assumes the field stays +non-nullable after a null check, but nothing prevents another thread, a reentrant call, or +unrelated code reachable from the same reference from reassigning it to `null` in between. +We recommend only using it to manage a mutable nullable state *locally* within a class. +A typical case is a field where `null` represents an uninitialized value that is assigned +once on first access. + ### Unsupported Idioms We don't support: diff --git a/library/src/scala/annotation/stableNull.scala b/library/src/scala/annotation/stableNull.scala index e2ebac72fce5..045c8b29d123 100644 --- a/library/src/scala/annotation/stableNull.scala +++ b/library/src/scala/annotation/stableNull.scala @@ -7,4 +7,4 @@ package scala.annotation * prefix is a stable path. * See `tests/explicit-nulls/pos/force-track-var-fields.scala` for an example. */ -private[scala] final class stableNull extends StaticAnnotation +final class stableNull extends StaticAnnotation