Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust generator element type, cf. dart-lang/language#3148 #3218

Merged
merged 3 commits into from
Jul 26, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 37 additions & 27 deletions specification/dartLangSpec.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2073,30 +2073,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}
eernstg marked this conversation as resolved.
Show resolved Hide resolved
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$.
eernstg marked this conversation as resolved.
Show resolved Hide resolved
%
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 @@ -12463,10 +12471,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 @@ -12549,8 +12557,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 @@ -12576,10 +12586,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