Skip to content

Commit c13682a

Browse files
authored
Adjust generator element type, cf. #3148 (#3218)
Adjust generator element type, cf. #3148.
1 parent 51390f0 commit c13682a

File tree

1 file changed

+47
-33
lines changed

1 file changed

+47
-33
lines changed

specification/dartLangSpec.tex

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
% been eliminated (it is spelled out each time which modifiers must be
5555
% present or not present). The concept is confusing now where a variable can
5656
% be late and final, and assignments to it are allowed by the static analysis.
57+
% - Change the definition of the 'element type of a generator function', due to
58+
% soundness issue with the current definition.
5759
%
5860
% Mar 2023
5961
% - Clarify how line breaks are handled in a multi-line string literal. Rename
@@ -2076,30 +2078,40 @@ \section{Functions}
20762078
a function marked \code{\SYNC*} or \code{\ASYNC*} is \VOID.
20772079

20782080
\LMHash{}%
2079-
We define the notion of the
2080-
\IndexCustom{element type of a generator}{function!generator!element type}
2081-
as follows:
2081+
We define the
2082+
\Index{union-free type derived from}
2083+
a type $T$ as follows:
2084+
If $T$ is of the form \code{$S$?}\ or the form \code{FutureOr<$S$>}
2085+
then the union-free type derived from $T$ is
2086+
the union-free type derived from $S$.
2087+
Otherwise, the union-free type derived from $T$ is $T$.
2088+
\commentary{%
2089+
For example, the union-free type derived from
2090+
\code{FutureOr<int?>?} is \code{int}.%
2091+
}
2092+
2093+
\LMHash{}%
2094+
We define the
2095+
\IndexCustom{element type of a generator function}{%
2096+
function!generator!element type}
2097+
$f$ as follows:
2098+
%
2099+
Let $S$ be the union-free type derived from the declared return type of $f$.
20822100
%
2083-
If the function $f$ is a synchronous generator
2084-
whose declared return type implements \code{Iterable<$U$>} for some $U$
2101+
If $f$ is a synchronous generator and
2102+
$S$ implements \code{Iterable<$U$>} for some $U$
20852103
(\ref{interfaceSuperinterfaces})
20862104
then the element type of $f$ is $U$.
20872105
%
2088-
If the function $f$ is an asynchronous generator
2089-
whose declared return type implements \code{Stream<$U$>} for some $U$
2106+
If $f$ is an asynchronous generator and
2107+
$S$ implements \code{Stream<$U$>} for some $U$
20902108
then the element type of $f$ is $U$.
20912109
%
2092-
Otherwise, if the function $f$ is a generator
2093-
(\commentary{synchronous or asynchronous})
2110+
Otherwise, if $f$ is a generator (synchronous or asynchronous)
2111+
and $S$ is a supertype of \code{Object}
2112+
(\commentary{which includes \code{Object} itself})
20942113
then the element type of $f$ is \DYNAMIC.
2095-
2096-
\commentary{%
2097-
%% TODO(eernst): Come nnbd, change `a top type' to \DYNAMIC.
2098-
In the latter case the return type is a top type,
2099-
because the declaration of $f$ would otherwise be a compile-time error.
2100-
This implies that there is no information about
2101-
the type of elements that the generator will yield.%
2102-
}
2114+
\commentary{No further cases are possible.}
21032115

21042116

21052117
\subsection{Function Declarations}
@@ -11642,7 +11654,7 @@ \subsection{Function Expressions}
1164211654

1164311655
\LMHash{}%
1164411656
We say that $S$ is the
11645-
\IndexCustom{future type of a type}{type!future type of}
11657+
\IndexCustom{future type derived from a type}{type!future type derived from}
1164611658
$T$ in the following cases, using the first applicable case:
1164711659

1164811660
\begin{itemize}
@@ -11657,10 +11669,10 @@ \subsection{Function Expressions}
1165711669

1165811670
\LMHash{}%
1165911671
When none of these cases are applicable,
11660-
we say that $T$ does not have a future type.
11672+
we say that $T$ does not derive a future type.
1166111673

1166211674
\commentary{%
11663-
Note that if $T$ has a future type $F$ then \SubtypeNE{T}{F},
11675+
Note that if $T$ derives a future type $F$ then \SubtypeNE{T}{F},
1166411676
and $F$ is always of the form \code{$G$<...>} or \code{$G$<...>?},
1166511677
where $G$ is \code{Future} or \code{FutureOr}.%
1166611678
}
@@ -11677,17 +11689,17 @@ \subsection{Function Expressions}
1167711689
\item If $T$ is \code{$X$\,\&\,$S$}
1167811690
for some type variable $X$ and type $S$ then
1167911691
\begin{itemize}
11680-
\item if $S$ has future type $U$
11692+
\item if $S$ derives a future type $U$
1168111693
then \DefEquals{\flatten{T}}{\code{\flatten{U}}}.
1168211694
\item otherwise,
1168311695
\DefEquals{\flatten{T}}{\code{\flatten{X}}}.
1168411696
\end{itemize}
1168511697

11686-
\item If $T$ has future type \code{Future<$S$>}
11698+
\item If $T$ derives a future type \code{Future<$S$>}
1168711699
or \code{FutureOr<$S$>}
1168811700
then \DefEquals{\flatten{T}}{S}.
1168911701

11690-
\item If $T$ has future type \code{Future<$S$>?}\ or
11702+
\item If $T$ derives a future type \code{Future<$S$>?}\ or
1169111703
\code{FutureOr<$S$>?}\ then \DefEquals{\flatten{T}}{\code{$S$?}}.
1169211704

1169311705
\item Otherwise, \DefEquals{\flatten{T}}{T}.
@@ -12464,10 +12476,10 @@ \subsection{Function Invocation}
1246412476
If $f$ is marked \code{\SYNC*} (\ref{functions}),
1246512477
then a fresh instance (\ref{generativeConstructors}) $i$
1246612478
implementing \code{Iterable<$U$>} is immediately returned,
12467-
where $U$ is determined as follows:
12468-
Let $T$ be the actual return type of $f$ (\ref{actualTypes}).
12469-
If $T$ is \code{Iterable<$S$>} for some type $S$, then $U$ is $S$,
12470-
otherwise $U$ is \code{Object}.
12479+
where $U$ is the actual type
12480+
(\ref{actualTypes})
12481+
corresponding to the element type of $f$
12482+
(\ref{functions}).
1247112483

1247212484
\commentary{%
1247312485
A Dart implementation will need to provide
@@ -12550,8 +12562,10 @@ \subsection{Function Invocation}
1255012562
If $f$ is marked \ASYNC{} (\ref{functions}),
1255112563
then a fresh instance (\ref{generativeConstructors}) $o$
1255212564
is associated with the invocation,
12553-
where the dynamic type of $o$ implements \code{Future<$flatten(T)$>},
12554-
and $T$ is the actual return type of $f$ (\ref{actualTypes}).
12565+
where the dynamic type of $o$ implements \code{Future<T>},
12566+
where $T$ is the actual type
12567+
(\ref{actualTypes})
12568+
corresponding to the future value type of $f$.
1255512569
Then the body of $f$ is executed until it either suspends or completes,
1255612570
at which point $o$ is returned.
1255712571
\commentary{%
@@ -12577,10 +12591,10 @@ \subsection{Function Invocation}
1257712591
If $f$ is marked \code{\ASYNC*} (\ref{functions}),
1257812592
then a fresh instance (\ref{generativeConstructors}) $s$
1257912593
implementing \code{Stream<$U$>} is immediately returned,
12580-
where $U$ is determined as follows:
12581-
Let $T$ be the actual return type of $f$ (\ref{actualTypes}).
12582-
If $T$ is \code{Stream<$S$>} for some type $S$, then $U$ is $S$,
12583-
otherwise $U$ is \code{Object}.
12594+
where $U$ is the actual type
12595+
(\ref{actualTypes})
12596+
corresponding to the element type of $f$
12597+
(\ref{functions}).
1258412598
When $s$ is listened to, execution of the body of $f$ will begin.
1258512599
When execution of the body of $f$ completes:
1258612600
\begin{itemize}

0 commit comments

Comments
 (0)