@@ -22,6 +22,9 @@ Status: Draft
22
22
2020.05.20
23
23
- Turn new references to ` CastError ` into being dynamic type errors.
24
24
25
+ 2020.07.21
26
+ - ** CHANGE** Changes to definite assignment for local variables.
27
+
25
28
2020.05.14
26
29
- ** CHANGE** Strong mode is auto-opted in when the "main" file is opted in.
27
30
- ** CHANGE** Specify weak mode/strong mode flag.
@@ -498,23 +501,23 @@ It is an error to call an expression whose type is potentially nullable and not
498
501
` dynamic ` .
499
502
500
503
It is an error if a top level variable or static variable with a non-nullable
501
- type has no initializer expression unless the variable is marked with a
502
- ` late ` or ` external ` modifier.
504
+ type has no initializer expression unless the variable is marked with a ` late `
505
+ or ` external ` modifier.
503
506
504
507
It is an error if a class declaration declares an instance variable with a
505
- potentially non-nullable type and no initializer expression, and the class has
506
- a generative constructor where the variable is not initialized via an
507
- initializing formal or an initializer list entry, unless the variable is marked
508
- with a ` late ` , ` abstract ` , or ` external ` modifier.
508
+ potentially non-nullable type and no initializer expression, and the class has a
509
+ generative constructor where the variable is not initialized via an initializing
510
+ formal or an initializer list entry, unless the variable is marked with a
511
+ ` late ` , ` abstract ` , or ` external ` modifier.
509
512
510
513
It is an error if a mixin declaration or a class declaration with no generative
511
514
constructors declares an instance variable without an initializing expression
512
- which is final or whose type is potentially non-nullable, unless the variable
513
- is marked with a ` late ` , ` abstract ` , or ` external ` modifier.
515
+ which is final or whose type is potentially non-nullable, unless the variable is
516
+ marked with a ` late ` , ` abstract ` , or ` external ` modifier.
514
517
515
- It is an error if a potentially non-nullable local variable which has no
516
- initializer expression and is not marked ` late ` is used before it is definitely
517
- assigned (see Definite Assignment below) .
518
+ It is an error to derive a mixin from a class declaration which contains an
519
+ instance variable with a potentially non-nullable type and no initializer
520
+ expression unless the variable is marked with the ` late ` modifier .
518
521
519
522
It is an error if the body of a method, function, getter, or function expression
520
523
with a potentially non-nullable return type ** may complete normally** .
@@ -568,18 +571,9 @@ expression.
568
571
It is an error for a class with a ` const ` constructor to have a ` late final `
569
572
instance variable.
570
573
571
- It is not a compile time error to write to a ` final ` variable if that variable
572
- is declared ` late ` and does not have an initializer.
573
-
574
- It is a compile time error to assign a value to a local variable marked ` late `
575
- and ` final ` when the variable is ** definitely assigned** . This includes all
576
- forms of assignments, including assignments via the composite assignment
577
- operators as well as pre and post-fix operators.
578
-
579
- It is a compile time error to read a local variable marked ` late ` when the
580
- variable is ** definitely unassigned** . This includes all forms of reads,
581
- including implicit reads via the composite assignment operators as well as pre
582
- and post-fix operators.
574
+ It is not a compile time error to write to a ` final ` non-local or instance
575
+ variable if that variable is declared ` late ` and does not have an initializer.
576
+ For local variables, see the section below.
583
577
584
578
It is an error if the object being iterated over by a ` for-in ` loop has a static
585
579
type which is not ` dynamic ` , and is not a subtype of ` Iterable<dynamic> ` .
@@ -628,6 +622,109 @@ It is a warning to use a null aware operator (`?.`, `?[]`, `?..`, `??`, `??=`, o
628
622
It is a warning to use the null check operator (` ! ` ) on an expression of type
629
623
` T ` if ` T ` is ** strictly non-nullable** .
630
624
625
+ ### Local variables and definite (un)assignment.
626
+
627
+ As part of the null safety release, errors for local variables are specified to
628
+ take into account ** definite assignment** and ** definite unassignment** (see the
629
+ section on Definite Assignment below). We say that a variable is ** potentially
630
+ assigned** if it is not ** definitely unassigned** , and that a variable is
631
+ ** potentially unassigned** if it is not ** definitely assigned** .
632
+
633
+ In all cases in this section, errors that are described as occurring on reads of
634
+ a variable are intended to apply to all form of reads, including indirectly as
635
+ part of compound assignment operators, as well as via pre and post-fix
636
+ operators. Similarly, errors that are described as occurring on writes of a
637
+ variable are intended to apply to all form of writes.
638
+
639
+ It is a compile time error to assign a value to a ` final ` , non-` late ` local
640
+ variable which is ** potentially assigned** . Thus, it is * not* a compile time
641
+ error to assign to a ** definitely unassigned** ` final ` local variable.
642
+
643
+ It is a compile time error to assign a value to a ` final ` , ` late ` local variable
644
+ if it is ** definitely assigned** . Thus, it is * not* a compile time error to
645
+ assign to a ** potentially unassigned** ` final ` , ` late ` local variable.
646
+
647
+ * Note that a variable is always considered ** definitely assigned** and not
648
+ ** definitely unassigned** if it has an explicit initializer, or an implicit
649
+ initializer as part of a larger construct (e.g. the loop variable in a ` for in `
650
+ construct).*
651
+
652
+ It is a compile time error to read a local variable when the variable is
653
+ ** definitely unassigned** unless the variable is non-` final ` , and non-` late ` ,
654
+ and has nullable type.
655
+
656
+ It is a compile time error to read a local variable when the variable is
657
+ ** potentially unassigned** unless the variable is non-` final ` and has nullable
658
+ type, or is ` late ` .
659
+
660
+ The errors specified above are summarized in the following table, where ` int ` is
661
+ used as an example of an arbitrary ** potentially non-nullable** type, ` int? ` is
662
+ used as an example of an arbitrary ** nullable** type, and ` T ` is used to stand
663
+ for a type of any nullability. A variable which has an initializer (explicit or
664
+ implicit) is always considered definitely assigned, and is never considered
665
+ definitely unassigned.
666
+
667
+
668
+ Read Behavior:
669
+
670
+ | Declaration form | Def. Assigned | Neither | Def. Unassigned |
671
+ | ----------------- | ------------- | ----------------- | --------------- |
672
+ | var x; | Ok | Ok | Ok |
673
+ | final x; | Ok | Error | Error |
674
+ | int x; | Ok | Error | Error |
675
+ | int? x; | Ok | Ok | Ok |
676
+ | final T x; | Ok | Error | Error |
677
+ | late var x; | Ok | Ok | Error |
678
+ | late final x; | Ok | Ok | Error |
679
+ | late T x; | Ok | Ok | Error |
680
+ | late final T x; | Ok | Ok | Error |
681
+
682
+ Write Behavior:
683
+
684
+ | Declaration form | Def. Assigned | Neither | Def. Unassigned |
685
+ | ----------------- | ------------- | ------------------- | --------------- |
686
+ | var x; | Ok | Ok | Ok |
687
+ | final x; | Error | Error | Ok |
688
+ | int x; | Ok | Ok | Ok |
689
+ | int? x; | Ok | Ok | Ok |
690
+ | final T x; | Error | Error | Ok |
691
+ | late var x; | Ok | Ok | Ok |
692
+ | late final x; | Error | Ok | Ok |
693
+ | late T x; | Ok | Ok | Ok |
694
+ | late final T x; | Error | Ok | Ok |
695
+
696
+ ### Local variables and inference
697
+
698
+ Local variables with explicitly written types are given the declared types as
699
+ written. The declared type of the variable is considered a "type of interest"
700
+ in the sense defined in the flow analysis specification. If the variable has an
701
+ initializer (explicit or implicit) and is not ` final ` , then the declaration is
702
+ treated as an assignment for the purposes of promotion.
703
+
704
+ * Treating the declared type of the variable as a "type of interest" implies that
705
+ if the variable has a nullable type, then the non-nullable version of that type
706
+ is also a type of interest. Treating the initialization as an assignment for
707
+ the purposes of promotion means that initializing a mutable variable declared at
708
+ type ` T? ` with a value of non-nullable type ` T ` immediately promotes the
709
+ variable to the non-nullable type.*
710
+
711
+ ``` dart
712
+ void test() {
713
+ int? x = 3; // x is declared at `int?`
714
+ x.isEven; // Valid, x has been promoted to `int`
715
+ x = null; // Valid, demotes to the declared type.
716
+ }
717
+ ```
718
+
719
+ Local variables with no explicitly written type but with an initializer are
720
+ given an inferred type equal to the type of their initializer, unless that type
721
+ is a subtype of ` Null ` , in which case the inferred type of the variable shall be
722
+ ` dynamic ` . The inferred type of the variable is considered a "type of interest"
723
+ in the sense defined in the flow analysis specification. In the case that the
724
+ type of the initializer is a promoted type variable ` X & T ` , the inferred type
725
+ of the variable shall be ` X ` . However, such a variable shall be treated as
726
+ immediately promoted to ` X & T ` .
727
+
631
728
### Expression typing
632
729
633
730
It is permitted to invoke or tear-off a method, setter, getter, or operator that
0 commit comments