File tree Expand file tree Collapse file tree 6 files changed +42
-5
lines changed
compiler/src/dotty/tools/dotc
library/src/scala/annotation Expand file tree Collapse file tree 6 files changed +42
-5
lines changed Original file line number Diff line number Diff line change @@ -1101,6 +1101,7 @@ class Definitions {
11011101 @ tu lazy val RetainsByNameAnnot : ClassSymbol = requiredClass(" scala.annotation.retainsByName" )
11021102 @ tu lazy val PublicInBinaryAnnot : ClassSymbol = requiredClass(" scala.annotation.publicInBinary" )
11031103 @ tu lazy val WitnessNamesAnnot : ClassSymbol = requiredClass(" scala.annotation.internal.WitnessNames" )
1104+ @ tu lazy val StableNullAnnot : ClassSymbol = requiredClass(" scala.annotation.stableNull" )
11041105
11051106 @ tu lazy val JavaRepeatableAnnot : ClassSymbol = requiredClass(" java.lang.annotation.Repeatable" )
11061107
Original file line number Diff line number Diff line change @@ -186,15 +186,21 @@ object Nullables:
186186 * Check `usedOutOfOrder` to see the explaination and example of "out of order".
187187 * See more examples in `tests/explicit-nulls/neg/var-ref-in-closure.scala`.
188188 */
189- def isTracked (ref : TermRef )(using Context ) =
189+ def isTracked (ref : TermRef )(using Context ) = // true
190+ val sym = ref.symbol
191+
192+ def isNullStableField : Boolean =
193+ ref.prefix.isStable
194+ && sym.isField
195+ && sym.hasAnnotation(defn.StableNullAnnot )
196+
190197 ref.isStable
191- || { val sym = ref.symbol
192- val unit = ctx.compilationUnit
198+ || isNullStableField
199+ || { val unit = ctx.compilationUnit
193200 ! ref.usedOutOfOrder
194201 && sym.span.exists
195202 && (unit ne NoCompilationUnit ) // could be null under -Ytest-pickler
196- && unit.assignmentSpans.contains(sym.span.start)
197- }
203+ && unit.assignmentSpans.contains(sym.span.start) }
198204
199205 /** The nullability context to be used after a case that matches pattern `pat`.
200206 * If `pat` is `null`, this will assert that the selector `sel` is not null afterwards.
Original file line number Diff line number Diff line change 1+ package scala .annotation
2+
3+ /** An annotation that can be used to mark a mutable field as trackable for nullability.
4+ * With explicit nulls, a normal mutable field cannot be tracked for nullability by flow typing,
5+ * since it can be updated to a null value at the same time.
6+ * This annotation will force the compiler to track the field for nullability, as long as the
7+ * prefix is a stable path.
8+ * See `tests/explicit-nulls/pos/force-track-var-fields.scala` for an example.
9+ */
10+ private [scala] final class stableNull extends StaticAnnotation
Original file line number Diff line number Diff line change @@ -1141,6 +1141,7 @@ object Build {
11411141 file(s " ${baseDirectory.value}/src/scala/annotation/init.scala " ),
11421142 file(s " ${baseDirectory.value}/src/scala/annotation/unroll.scala " ),
11431143 file(s " ${baseDirectory.value}/src/scala/annotation/targetName.scala " ),
1144+ file(s " ${baseDirectory.value}/src/scala/annotation/stableNull.scala " ),
11441145 file(s " ${baseDirectory.value}/src/scala/deriving/Mirror.scala " ),
11451146 file(s " ${baseDirectory.value}/src/scala/compiletime/package.scala " ),
11461147 file(s " ${baseDirectory.value}/src/scala/quoted/Type.scala " ),
@@ -1278,6 +1279,7 @@ object Build {
12781279 file(s " ${baseDirectory.value}/src/scala/annotation/init.scala " ),
12791280 file(s " ${baseDirectory.value}/src/scala/annotation/unroll.scala " ),
12801281 file(s " ${baseDirectory.value}/src/scala/annotation/targetName.scala " ),
1282+ file(s " ${baseDirectory.value}/src/scala/annotation/stableNull.scala " ),
12811283 file(s " ${baseDirectory.value}/src/scala/deriving/Mirror.scala " ),
12821284 file(s " ${baseDirectory.value}/src/scala/compiletime/package.scala " ),
12831285 file(s " ${baseDirectory.value}/src/scala/quoted/Type.scala " ),
Original file line number Diff line number Diff line change @@ -22,6 +22,8 @@ object MiMaFilters {
2222
2323 ProblemFilters .exclude[DirectMissingMethodProblem ](" scala.Conversion.underlying" ),
2424 ProblemFilters .exclude[MissingClassProblem ](" scala.Conversion$" ),
25+
26+ ProblemFilters .exclude[MissingClassProblem ](" scala.annotation.stableNull" ),
2527 ),
2628
2729 // Additions since last LTS
Original file line number Diff line number Diff line change 1+ package scala
2+
3+ import scala .annotation .stableNull
4+
5+ class A :
6+ @ stableNull var s : String | Null = null
7+ def getS : String =
8+ if s == null then s = " "
9+ s
10+
11+ def test (a : A ): String =
12+ if a.s == null then
13+ a.s = " "
14+ a.s
15+ else
16+ a.s
You can’t perform that action at this time.
0 commit comments