Skip to content

Commit

Permalink
Adjust generator element type, cf. #3148
Browse files Browse the repository at this point in the history
  • Loading branch information
eernstg committed Jul 17, 2023
1 parent 35c9062 commit cf28fdd
Showing 1 changed file with 37 additions and 27 deletions.
64 changes: 37 additions & 27 deletions specification/dartLangSpec.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1759,30 +1759,38 @@ \section{Functions}
a function marked \code{\SYNC*} or \code{\ASYNC*} is \VOID.

\LMHash{}%
We define the notion of the
\IndexCustom{element type of a generator}{function!generator!element type}
as follows:
We define the
\Index{union-free type}
of a type $T$ as follows:
If $T$ is of the form \code{$S$?}\ or the form \code{FutureOr<$S$>}
then the union-free type of $T$ is the union-free type of $S$.
Otherwise, the union-free type of $T$ is $T$.
\commentary{%
For example, the union-free type of \code{FutureOr<int?>?} is \code{int}.%
}

\LMHash{}%
We define the
\IndexCustom{element type of a generator function}{%
function!generator!element type}
$f$ as follows:
%
Let $S$ be the union-free type of the declared return type of $f$.
%
If the function $f$ is a synchronous generator
whose declared return type implements \code{Iterable<$U$>} for some $U$
If $f$ is a synchronous generator and
$S$ implements \code{Iterable<$U$>} for some $U$
(\ref{interfaceSuperinterfaces})
then the element type of $f$ is $U$.
%
If the function $f$ is an asynchronous generator
whose declared return type implements \code{Stream<$U$>} for some $U$
If $f$ is an asynchronous generator and
$S$ implements \code{Stream<$U$>} for some $U$
then the element type of $f$ is $U$.
%
Otherwise, if the function $f$ is a generator
(\commentary{synchronous or asynchronous})
Otherwise, if $f$ is a generator (synchronous or asynchronous)
and $S$ is a supertype of \code{Object}
(\commentary{which includes \code{Object} itself})
then the element type of $f$ is \DYNAMIC.

\commentary{%
%% TODO(eernst): Come nnbd, change `a top type' to \DYNAMIC.
In the latter case the return type is a top type,
because the declaration of $f$ would otherwise be a compile-time error.
This implies that there is no information about
the type of elements that the generator will yield.%
}
\commentary{No further cases are possible.}


\subsection{Function Declarations}
Expand Down Expand Up @@ -12136,10 +12144,10 @@ \subsection{Function Invocation}
If $f$ is marked \code{\SYNC*} (\ref{functions}),
then a fresh instance (\ref{generativeConstructors}) $i$
implementing \code{Iterable<$U$>} is immediately returned,
where $U$ is determined as follows:
Let $T$ be the actual return type of $f$ (\ref{actualTypes}).
If $T$ is \code{Iterable<$S$>} for some type $S$, then $U$ is $S$,
otherwise $U$ is \code{Object}.
where $U$ is the actual type
(\ref{actualTypes})
corresponding to the element type of $f$
(\ref{functions}).

\commentary{%
A Dart implementation will need to provide
Expand Down Expand Up @@ -12222,8 +12230,10 @@ \subsection{Function Invocation}
If $f$ is marked \ASYNC{} (\ref{functions}),
then a fresh instance (\ref{generativeConstructors}) $o$
is associated with the invocation,
where the dynamic type of $o$ implements \code{Future<$flatten(T)$>},
and $T$ is the actual return type of $f$ (\ref{actualTypes}).
where the dynamic type of $o$ implements \code{Future<T>},
where $T$ is the actual type
(\ref{actualTypes})
corresponding to the future value type of $f$.
Then the body of $f$ is executed until it either suspends or completes,
at which point $o$ is returned.
\commentary{%
Expand All @@ -12249,10 +12259,10 @@ \subsection{Function Invocation}
If $f$ is marked \code{\ASYNC*} (\ref{functions}),
then a fresh instance (\ref{generativeConstructors}) $s$
implementing \code{Stream<$U$>} is immediately returned,
where $U$ is determined as follows:
Let $T$ be the actual return type of $f$ (\ref{actualTypes}).
If $T$ is \code{Stream<$S$>} for some type $S$, then $U$ is $S$,
otherwise $U$ is \code{Object}.
where $U$ is the actual type
(\ref{actualTypes})
corresponding to the element type of $f$
(\ref{functions}).
When $s$ is listened to, execution of the body of $f$ will begin.
When execution of the body of $f$ completes:
\begin{itemize}
Expand Down

0 comments on commit cf28fdd

Please sign in to comment.