@@ -5,6 +5,7 @@ package typer
5
5
import core ._
6
6
import Types ._ , Contexts ._ , Symbols ._ , Decorators ._ , Constants ._
7
7
import annotation .{tailrec , infix }
8
+ import StdNames .nme
8
9
import util .Property
9
10
10
11
/** Operations for implementing a flow analysis for nullability */
@@ -17,7 +18,7 @@ object Nullables with
17
18
case class NotNullInfo (asserted : Set [TermRef ], retracted : Set [TermRef ])
18
19
assert((asserted & retracted).isEmpty)
19
20
20
- def isEmpty = this eq noNotNulls
21
+ def isEmpty = this eq NotNullInfo .empty
21
22
22
23
/** The sequential combination with another not-null info */
23
24
@ infix def seq (that : NotNullInfo ): NotNullInfo =
@@ -28,25 +29,23 @@ object Nullables with
28
29
this .retracted.union(that.retracted).diff(that.asserted))
29
30
30
31
object NotNullInfo with
32
+ val empty = new NotNullInfo (Set (), Set ())
31
33
def apply (asserted : Set [TermRef ], retracted : Set [TermRef ]): NotNullInfo =
32
- if asserted.isEmpty && retracted.isEmpty then noNotNulls
34
+ if asserted.isEmpty && retracted.isEmpty then empty
33
35
else new NotNullInfo (asserted, retracted)
34
36
end NotNullInfo
35
37
36
- val noNotNulls = new NotNullInfo (Set (), Set ())
37
-
38
38
/** A pair of not-null sets, depending on whether a condition is `true` or `false` */
39
39
case class NotNullConditional (ifTrue : Set [TermRef ], ifFalse : Set [TermRef ]) with
40
- def isEmpty = this eq neitherNotNull
40
+ def isEmpty = this eq NotNullConditional .empty
41
41
42
42
object NotNullConditional with
43
+ val empty = new NotNullConditional (Set (), Set ())
43
44
def apply (ifTrue : Set [TermRef ], ifFalse : Set [TermRef ]): NotNullConditional =
44
- if ifTrue.isEmpty && ifFalse.isEmpty then neitherNotNull
45
+ if ifTrue.isEmpty && ifFalse.isEmpty then empty
45
46
else new NotNullConditional (ifTrue, ifFalse)
46
47
end NotNullConditional
47
48
48
- val neitherNotNull = new NotNullConditional (Set (), Set ())
49
-
50
49
/** An attachment that represents conditional flow facts established
51
50
* by this tree, which represents a condition.
52
51
*/
@@ -117,8 +116,9 @@ object Nullables with
117
116
false
118
117
119
118
def extendWith (info : NotNullInfo ) =
120
- if info.asserted.forall(infos.containsRef(_))
121
- && ! info.retracted.exists(infos.containsRef(_))
119
+ if info.isEmpty
120
+ || info.asserted.forall(infos.containsRef(_))
121
+ && ! info.retracted.exists(infos.containsRef(_))
122
122
then infos
123
123
else info :: infos
124
124
@@ -135,7 +135,7 @@ object Nullables with
135
135
def notNullInfo (given Context ): NotNullInfo =
136
136
stripInlined(tree).getAttachment(NNInfo ) match
137
137
case Some (info) if ! curCtx.erasedTypes => info
138
- case _ => noNotNulls
138
+ case _ => NotNullInfo .empty
139
139
140
140
/** The paths that are known to be not null if the condition represented
141
141
* by `tree` yields `true` or `false`. Two empty sets if `tree` is not
@@ -144,7 +144,7 @@ object Nullables with
144
144
def notNullConditional (given Context ): NotNullConditional =
145
145
stripBlock(tree).getAttachment(NNConditional ) match
146
146
case Some (cond) if ! curCtx.erasedTypes => cond
147
- case _ => neitherNotNull
147
+ case _ => NotNullConditional .empty
148
148
149
149
/** The current context augmented with nullability information of `tree` */
150
150
def nullableContext (given Context ): Context =
@@ -181,7 +181,7 @@ object Nullables with
181
181
def computeNullable ()(given Context ): tree.type =
182
182
def setConditional (ifTrue : Set [TermRef ], ifFalse : Set [TermRef ]) =
183
183
tree.putAttachment(NNConditional , NotNullConditional (ifTrue, ifFalse))
184
- if ! curCtx.erasedTypes then
184
+ if ! curCtx.erasedTypes && analyzedOps.contains(tree.symbol.name.toTermName) then
185
185
tree match
186
186
case CompareNull (TrackedRef (ref), testEqual) =>
187
187
if testEqual then setConditional(Set (), Set (ref))
@@ -209,4 +209,6 @@ object Nullables with
209
209
tree.computeNullable()
210
210
}.traverse(tree)
211
211
212
+ private val analyzedOps = Set (nme.EQ , nme.NE , nme.eq, nme.ne, nme.ZAND , nme.ZOR , nme.UNARY_! )
213
+
212
214
end Nullables
0 commit comments