Skip to content

Commit aa3fba7

Browse files
committed
Corrected variable initialization specification ("has been stored" rather than "first execution of getter/setter")
1 parent 99e261f commit aa3fba7

File tree

1 file changed

+62
-38
lines changed

1 file changed

+62
-38
lines changed

specification/dartLangSpec.tex

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,13 @@ \section{Variables}
14021402
That is, any kind of variable which is not a local variable.%
14031403
}
14041404

1405+
\LMHash{}%
1406+
A \IndexCustom{non-local variable}{variable!non-local}
1407+
is a library variable, a class variable, or an instance variable.
1408+
\commentary{%
1409+
That is, any kind of variable which is not a local variable.%
1410+
}
1411+
14051412
\LMHash{}%
14061413
A \IndexCustom{constant variable}{variable!constant}
14071414
is a variable whose declaration includes the modifier \CONST.
@@ -1532,13 +1539,10 @@ \subsection{Implicitly Induced Getters and Setters}
15321539
A variable declaration of the form
15331540
\code{\STATIC?\,\,\LATE?\,\,\VAR\,\,\id{} = $e$;}
15341541
implicitly induces a setter with the header
1535-
\code{\VOID\,\,\SET\,\,\id(\DYNAMIC\,\,$x$)},
1542+
\code{\VOID\,\,\SET\,\,\id($T$\,\,$x$)},
15361543
whose execution sets the value of \id{} to the incoming argument $x$.
1537-
1538-
\commentary{%
1539-
Type inference could have provided a type different from \DYNAMIC{}
1540-
(\ref{overview}).%
1541-
}
1544+
The type $T$ is obtained from type inference
1545+
(\ref{overview}).
15421546
\EndCase
15431547

15441548
\LMHash{}%
@@ -1563,7 +1567,7 @@ \subsection{Implicitly Induced Getters and Setters}
15631567
A variable declaration of the form
15641568
\code{\STATIC?\,\,\LATE\,\,\FINAL\,\,$T$\,\,\id;}
15651569
implicitly induces a setter (\ref{setters}) with the header
1566-
\code{\VOID\,\,\SET\,\,\id($T$\,\,$x$)}.
1570+
\code{\VOID\,\,\SET\,\,\id(\DYNAMIC\,\,$x$)}.
15671571
If this setter is executed
15681572
in a situation where the variable \id{} has not been bound,
15691573
it will bind \id{} to the object that $x$ is bound to.
@@ -1887,7 +1891,39 @@ \subsection{Evaluation of Implicit Variable Getters}
18871891
\commentary{%
18881892
Note that these static or library variables can be \emph{implicitly}
18891893
late-initialized, in the sense that they do not have
1890-
the modifier \LATE.%
1894+
the modifier \LATE.
1895+
1896+
An initializing expression can have side effects
1897+
that are significant during initialization.
1898+
For example:%
1899+
}
1900+
1901+
\begin{dartCode}
1902+
bool b = \TRUE;
1903+
int i = (() => (b = !b) ? (i = 10) : i + 1 )();
1904+
\\
1905+
\VOID{} main() \{
1906+
print(i); // '11'.
1907+
\}
1908+
\end{dartCode}
1909+
1910+
\commentary{%
1911+
In this example, \code{main} invokes
1912+
the implicitly induced getter named \code{i},
1913+
and no value has been stored in the variable \code{i} at this point.
1914+
Hence, evaluation of the initializing expression proceeds.
1915+
This causes \code{b} to be toggled to \FALSE,
1916+
which again causes \code{i + 1} to be evaluated.
1917+
This causes the getter \code{i} to be invoked again,
1918+
and it is still true that no value has been stored in the variable,
1919+
so the initializing expression is evaluated again.
1920+
This toggles \code{b} to \TRUE,
1921+
which causes \code{i = 10} to be evaluated,
1922+
which causes the implicitly induced setter named \code{i=} to be invoked,
1923+
and the most recent invocation of the getter \code{i}
1924+
returns 10.
1925+
This makes \code{i + 1} evaluate to 11,
1926+
which is stored in the variable.%
18911927
}
18921928
\item \emph{Constant variable.}
18931929
If $d$ declares a constant variable with the initializing expression $e$,
@@ -1915,6 +1951,7 @@ \subsection{Evaluation of Implicit Variable Getters}
19151951
the implicitly induced getter is a late-uninitialized getter.
19161952
This determines the semantics of an invocation.
19171953
\end{itemize}
1954+
\EndCase
19181955

19191956
% Reduce whitespace after itemized list: This is just an end symbol.
19201957
\vspace{-\baselineskip}\EndCase
@@ -3947,6 +3984,11 @@ \subsection{Instance Variables}
39473984
is considered to be covariant-by-declaration
39483985
(\ref{covariantParameters}).
39493986

3987+
\LMHash{}%
3988+
A \Error{compile-time error} occurs if an instance variable declaration
3989+
includes the modifier \COVARIANT,
3990+
but it does not implicitly induce a setter.
3991+
39503992
\commentary{%
39513993
The modifier \COVARIANT{} on an instance variable has no other effects.
39523994
In particular, the return type of the implicitly induced getter
@@ -8582,7 +8624,7 @@ \subsection{Constants}
85828624
that is not qualified by a deferred prefix,
85838625
is a potentially constant and constant expression.
85848626
\commentary{%
8585-
For example, if class $C$ declares a constant static variable $v$,
8627+
For example, if class $C$ declares a constant class variable $v$,
85868628
\code{$C$.$v$} is a constant.
85878629
The same is true if $C$ is accessed via a prefix $p$;
85888630
\code{$p$.$C$.$v$} is a constant unless $p$ is a deferred prefix.%
@@ -13350,11 +13392,13 @@ \subsubsection{Unqualified Invocation}
1335013392
\vspace{-2ex}
1335113393
\EndCase
1335213394

13395+
\LMHash{}%
1335313396
\Case{Lexical lookup yields an import prefix}
1335413397
When the lexical lookup of \id{} yields an import prefix,
1335513398
a \Error{compile-time error} occurs.
1335613399
\EndCase
1335713400

13401+
\LMHash{}%
1335813402
\Case{Lexical lookup yields nothing}
1335913403
When the lexical lookup of \id{} yields nothing,
1336013404
$i$ is treated as
@@ -17024,21 +17068,23 @@ \subsection{Postfix Expressions}
1702417068
All but the latter three are specified elsewhere.
1702517069

1702617070
\LMHash{}%
17027-
\Case{Null checks}
17071+
\Case{Non-null assertions}
1702817072
Consider an expression $e$ of the form \code{$e_1$\!!}\ where
1702917073
$e_1$ is derived from \syntax{<primary> <selector>*}.
1703017074

1703117075
\LMHash{}%
1703217076
Let $S$ be the static type of $e_1$.
1703317077
A warning occurs if $S$ is non-nullable.
17034-
\commentary{In this case, the null check is redundant.}
17078+
\commentary{In this case, the non-null assertion is redundant.}
1703517079
The static type of $e$ is \NonNullType{$S$}.
1703617080

1703717081
\LMHash{}%
1703817082
$e$ is evaluated as follows: $e_1$ is evaluated to an object $o$.
1703917083
If $o$ is the null object then a dynamic error occurs,
1704017084
otherwise $e$ evaluates to $o$.
17085+
\EndCase
1704117086

17087+
\LMHash{}%
1704217088
\Case{Constructor Invocations}
1704317089
Consider a \synt{constructorInvocation} $e$ of the form
1704417090
\code{$n$<\metavar{typeArguments}>.\id(\metavar{arguments})}.
@@ -17908,7 +17954,7 @@ \subsection{Type Test}
1790817954
such a refinement would accept more code without errors,
1790917955
but not reject any code now error-free.
1791017956

17911-
The rule only applies to locals and parameters,
17957+
The rule only applies to local variables (including formal parameters),
1791217958
as non-local variables could be modified
1791317959
via side-effecting functions or methods that are not accessible
1791417960
to a local analysis.
@@ -19545,6 +19591,7 @@ \subsection{Return}
1954519591
The case where the evaluation of $e$ throws is covered by the general rule
1954619592
which propagates the throwing completion from $e$ to $s$ to the function body.%
1954719593
}
19594+
\EndCase
1954819595

1954919596
\LMHash{}%
1955019597
\Case{Asynchronous non-generator functions}
@@ -24733,18 +24780,6 @@ \subsubsection{Null promotion}
2473324780
These are extended as per
2473424781
[separate proposal](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md).
2473524782

24736-
\paragraph{Constant instances}
24737-
24738-
!!!TODO!!!
24739-
24740-
24741-
\subsubsection{Null check operator}
24742-
24743-
When evaluating an expression of the form \code{$e$!},
24744-
where $e$ evaluates to a value $v$,
24745-
a dynamic type error occurs if $v$ is \code{null},
24746-
and otherwise the expression evaluates to $v$.
24747-
2474824783
\subsubsection{Null aware operator}
2474924784
\LMLabel{nullShorteningTransformation}
2475024785

@@ -24895,20 +24930,9 @@ \subsubsection{Null aware operator}
2489524930

2489624931
\subsubsection{Late fields and variables}
2489724932

24898-
A non-local \LATE{} variable declaration $D$ implicitly induces a getter
24899-
into the enclosing scope. It also induces an implicit setter iff one of the
24900-
following conditions is satisfied:
24901-
24902-
- $D$ is non-final.
24903-
- $D$ is late, final, and has no initializing expression.
24904-
24905-
The late final variable declaration with no initializer is permitted, and
24906-
introduces a variable which may be assigned to so long as the variable is not
24907-
known to be definitely assigned. The property that the variable is never
24908-
mutated after initialization is enforced dynamically rather than statically.
24933+
!!!TODO!!!
2490924934

24910-
An instance variable declaration may be declared \COVARIANT{} iff it introduces
24911-
an implicit setter.
24935+
A variable which is marked as \LATE{} ...
2491224936

2491324937
A read of a field or variable which is marked as \LATE{} which has not yet been
2491424938
written to causes the initializer expression of the variable to be evaluated to
@@ -24956,7 +24980,7 @@ \subsubsection{Late fields and variables}
2495624980
\}
2495724981
\end{dartCode}
2495824982

24959-
A toplevel or static variable with an initializer is evaluated as if it
24983+
A toplevel or class variable with an initializer is evaluated as if it
2496024984
was marked \LATE. Note that this is a change from pre-NNBD semantics in that:
2496124985

2496224986
\begin{itemize}

0 commit comments

Comments
 (0)