@@ -53,37 +53,45 @@ object Nullables:
53
53
TypeBoundsTree (lo, hiTree, alias)
54
54
55
55
/** A set of val or var references that are known to be not null
56
- * after the tree finishes executing normally (non-exceptionally),
56
+ * after the tree finishes executing normally (non-exceptionally),
57
57
* plus a set of variable references that are ever assigned to null,
58
58
* and may therefore be null if execution of the tree is interrupted
59
59
* by an exception.
60
60
*/
61
- case class NotNullInfo (asserted : Set [TermRef ], retracted : Set [TermRef ]):
61
+ case class NotNullInfo (asserted : Set [TermRef ] | Null , retracted : Set [TermRef ]):
62
62
def isEmpty = this eq NotNullInfo .empty
63
63
64
64
def retractedInfo = NotNullInfo (Set (), retracted)
65
65
66
+ def terminatedInfo = NotNullInfo (null , retracted)
67
+
66
68
/** The sequential combination with another not-null info */
67
69
def seq (that : NotNullInfo ): NotNullInfo =
68
70
if this .isEmpty then that
69
71
else if that.isEmpty then this
70
- else NotNullInfo (
71
- this .asserted.diff(that.retracted).union(that.asserted),
72
- this .retracted.union(that.retracted))
72
+ else
73
+ val newAsserted =
74
+ if this .asserted == null || that.asserted == null then null
75
+ else this .asserted.diff(that.retracted).union(that.asserted)
76
+ val newRetracted = this .retracted.union(that.retracted)
77
+ NotNullInfo (newAsserted, newRetracted)
73
78
74
79
/** The alternative path combination with another not-null info. Used to merge
75
- * the nullability info of the two branches of an if.
80
+ * the nullability info of the branches of an if or match .
76
81
*/
77
82
def alt (that : NotNullInfo ): NotNullInfo =
78
- NotNullInfo (this .asserted.intersect(that.asserted), this .retracted.union(that.retracted))
79
-
80
- def withRetracted (that : NotNullInfo ): NotNullInfo =
81
- NotNullInfo (this .asserted, this .retracted.union(that.retracted))
83
+ val newAsserted =
84
+ if this .asserted == null then that.asserted
85
+ else if that.asserted == null then this .asserted
86
+ else this .asserted.intersect(that.asserted)
87
+ val newRetracted = this .retracted.union(that.retracted)
88
+ NotNullInfo (newAsserted, newRetracted)
89
+ end NotNullInfo
82
90
83
91
object NotNullInfo :
84
92
val empty = new NotNullInfo (Set (), Set ())
85
- def apply (asserted : Set [TermRef ], retracted : Set [TermRef ]): NotNullInfo =
86
- if asserted.isEmpty && retracted.isEmpty then empty
93
+ def apply (asserted : Set [TermRef ] | Null , retracted : Set [TermRef ]): NotNullInfo =
94
+ if asserted != null && asserted .isEmpty && retracted.isEmpty then empty
87
95
else new NotNullInfo (asserted, retracted)
88
96
end NotNullInfo
89
97
@@ -227,7 +235,7 @@ object Nullables:
227
235
*/
228
236
@ tailrec def impliesNotNull (ref : TermRef ): Boolean = infos match
229
237
case info :: infos1 =>
230
- if info.asserted.contains(ref) then true
238
+ if info.asserted != null && info.asserted .contains(ref) then true
231
239
else if info.retracted.contains(ref) then false
232
240
else infos1.impliesNotNull(ref)
233
241
case _ =>
@@ -243,7 +251,9 @@ object Nullables:
243
251
/** Retract all references to mutable variables */
244
252
def retractMutables (using Context ) =
245
253
val mutables = infos.foldLeft(Set [TermRef ]()):
246
- (ms, info) => ms.union(info.asserted.filter(_.symbol.is(Mutable )))
254
+ (ms, info) => ms.union(
255
+ if info.asserted == null then Set .empty
256
+ else info.asserted.filter(_.symbol.is(Mutable )))
247
257
infos.extendWith(NotNullInfo (Set (), mutables))
248
258
249
259
end extension
@@ -516,7 +526,10 @@ object Nullables:
516
526
&& assignmentSpans.getOrElse(sym.span.start, Nil ).exists(whileSpan.contains(_))
517
527
&& ctx.notNullInfos.impliesNotNull(ref)
518
528
519
- val retractedVars = ctx.notNullInfos.flatMap(_.asserted.filter(isRetracted)).toSet
529
+ val retractedVars = ctx.notNullInfos.flatMap(info =>
530
+ if info.asserted == null then Set .empty
531
+ else info.asserted.filter(isRetracted)
532
+ ).toSet
520
533
ctx.addNotNullInfo(NotNullInfo (Set (), retractedVars))
521
534
end whileContext
522
535
0 commit comments