Skip to content

Commit 1a16815

Browse files
authored
Specify that an initializerExpression cannot be a function literal (#3503)
Adjust the language specification grammar and text to specify the rule that an `<initializerExpression>` cannot be a function literal. Also add two alternatives to `<initializerExpression>`. The implementations already support both.
1 parent b92280e commit 1a16815

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

specification/dartLangSpec.tex

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
% Dec 2023
4545
% - Allow `~/` on operands of type `double` in constant expressions, aligning
4646
% the specification with already implemented behavior.
47+
% - Broaden the grammar rule about `initializerExpression` to match the
48+
% implemented behavior. Specify that an initializer expression can not be
49+
% a function literal.
4750
%
4851
% Nov 2023
4952
% - Specify that the dynamic error for calling a function in a deferred and
@@ -4233,13 +4236,43 @@ \subsubsection{Generative Constructors}
42334236
<fieldInitializer> ::= \gnewline{}
42344237
(\THIS{} `.')? <identifier> `=' <initializerExpression>
42354238

4236-
<initializerExpression> ::= <conditionalExpression> | <cascade>
4239+
<initializerExpression> ::= \gnewline{}
4240+
<assignableExpression> <assignmentOperator> <expression>
4241+
\alt <conditionalExpression>
4242+
\alt <cascade>
4243+
\alt <throwExpression>
42374244
\end{grammar}
42384245

4246+
%% TODO(eernst): When #54262 is resolved, delete the next paragraph.
4247+
%% If <expression> is changed such that it derives <functionExpression>,
4248+
%% the following error will simply be a property of the grammar rule
4249+
%% because <initializerExpression> will _not_ derive <functionExpression>.
4250+
\LMHash{}%
4251+
As a special disambiguation rule,
4252+
an \synt{initializerExpression} can not derive a \synt{functionExpression}.
4253+
4254+
\rationale{%
4255+
This resolves a near-ambiguity:
4256+
In \code{A()\,:\,\,x\,\,=\,\,()\,\,\{\,\ldots\,\}},
4257+
\code{x} could be initialized to the empty record,
4258+
and the block could be the body of the constructor.
4259+
Alternatively, \code{x} could be initialized to a function object,
4260+
and the constructor would then not have a body.
4261+
It would only be known which case we have when we encounter
4262+
(or do not encounter)
4263+
a semicolon at the very end.
4264+
That was considered unreadable.
4265+
Hence, parsers can commit to not parsing a function expression
4266+
in this situation.
4267+
Note that it is still possible for \synt{initializerExpression} to derive
4268+
a term that contains a function expression as a subterm, e.g.,
4269+
\code{A()\,:\,\,x\,\,=\,\,(()\,\,\{\,\ldots\,\});}.%
4270+
}
4271+
42394272
\LMHash{}%
42404273
An initializer of the form \code{$v$ = $e$} is equivalent to
42414274
an initializer of the form \code{\THIS.$v$ = $e$},
4242-
both forms are called \Index{instance variable initializers}.
4275+
and both forms are called \Index{instance variable initializers}.
42434276
It is a compile-time error if the enclosing class
42444277
does not declare an instance variable named $v$.
42454278
It is a compile-time error unless the static type of $e$
@@ -8318,6 +8351,11 @@ \section{Expressions}
83188351
which may affect the static type and evaluation of the expression.
83198352
Every object has an associated dynamic type (\ref{dynamicTypeSystem}).
83208353

8354+
%% TODO(eernst): <expression> should derive <functionExpression> as well,
8355+
%% the fact that it is currently derived from <primary> induces a genuine
8356+
%% and serious source of ambiguity, which makes it difficult to parse Dart
8357+
%% using anything other than a modified recursive descent parser.
8358+
83218359
\begin{grammar}
83228360
<expression> ::= <assignableExpression> <assignmentOperator> <expression>
83238361
\alt <conditionalExpression>

0 commit comments

Comments
 (0)