@@ -371,12 +371,7 @@ s match {
371
371
372
372
### Mutable Variable
373
373
374
- A mutable vriable is trackable with following restrictions:
375
-
376
- 1 . All the assignment must in the same closure as the definition (more strictly,
377
- reachable by the definition).
378
- 2 . We only analyze the comparisons and use the facts in the same closure as
379
- the definition.
374
+ We are able to detect the nullability of some local mutable variables. A simple example is:
380
375
381
376
``` scala
382
377
class C (val x : Int , val next : C | Null )
@@ -394,33 +389,50 @@ while (xs != null) {
394
389
}
395
390
```
396
391
397
- ``` scala
398
- var x : String | Null = ???
399
- def y = {
400
- x = null
401
- }
402
- if (x != null ) {
403
- // y can be called here
404
- val a : String = x // error: x is captured and mutated by the closure, not tackable
405
- }
406
- ```
407
-
408
- ``` scala
409
- var x : String | Null = ???
410
- def y = {
411
- if (x != null ) {
412
- // not safe to use the fact (x != null) here
413
- // since y can be executed at the same time as the outer block
414
- val _: String = x
415
- }
416
- }
417
- if (x != null ) {
418
- val a : String = x // ok to use the fact here
419
- x = null
420
- }
421
- ```
422
-
423
- Currently, we are unable to track ` x.a ` if ` x ` is mutable.
392
+ When dealing with local mutable variables, there are two questions:
393
+
394
+ 1 . Whether to track a local mutable variable during flow typing.
395
+ We track a local mutable variable iff the variable is not assigned in a closure.
396
+ For example, in the following code ` x ` is assigned to by the closure ` y ` , so we do not
397
+ do flow typing on ` x ` .
398
+
399
+ ``` scala
400
+ var x : String | Null = ???
401
+ def y = {
402
+ x = null
403
+ }
404
+ if (x != null ) {
405
+ // y can be called here, which break the fact
406
+ val a : String = x // error: x is captured and mutated by the closure, not tackable
407
+ }
408
+ ```
409
+
410
+ 2 . Whether to generate and use flow typing on a specific _ use_ of a local mutable variable.
411
+ We only want to do flow typing on a use that belongs to the same method as the definition
412
+ of the local variable.
413
+ For example, in the following code, even ` x ` is not assigned to by a closure, but we can only
414
+ use flow typing in one of the occurrences (because the other occurrence happens within a nested
415
+ closure).
416
+
417
+ ``` scala
418
+ var x : String | Null = ???
419
+ def y = {
420
+ if (x != null ) {
421
+ // not safe to use the fact (x != null) here
422
+ // since y can be executed at the same time as the outer block
423
+ val _: String = x
424
+ }
425
+ }
426
+ if (x != null ) {
427
+ val a : String = x // ok to use the fact here
428
+ x = null
429
+ }
430
+ ```
431
+
432
+ See more examples in ` tests/explicit-nulls/neg/var-ref-in-closure.scala ` .
433
+
434
+ Currently, we are unable to track paths with a mutable variable prefix.
435
+ For example, ` x.a ` if ` x ` is mutable.
424
436
425
437
### Unsupported Idioms
426
438
0 commit comments