Specify dynamic type of Futures/... returned from async/... functions
Addressing https://github.com/dart-lang/sdk/issues/33213.
Change-Id: I383d496c46fa0d1bf9313f315ad767eb21577eb6
Reviewed-on: https://dart-review.googlesource.com/56487
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index f06888f..0fc0ae8 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -56,6 +56,8 @@
% - Introduce `subterm` and `immediate subterm`.
% - Introduce `top type`.
% - Specify configurable imports.
+% - Specify the dynamic type of the Iterable/Future/Stream returned from
+% invocations of functions marked sync*/async/async*.
%
% 1.15
% - Change how language specification describes control flow.
@@ -360,6 +362,14 @@
\subsection{Scoping}
\LMLabel{scoping}
+%% TODO(eernst): Perhaps this section is the right place for the following?: We
+%% need to say that `\code{Object}` and a handful of other identifiers in this document
+%% are intended to refer to `the built-in class \code{Object}` etc., such that we don't
+%% have to say such a thing everywhere such names are used. Currently we have about 20
+%% occurrences of `the built-in class ..` and such, so they should be deleted when we
+%% specify the general rule here. It needs to be said that this may be a _violation_
+%% of the current scope rules, or that we assume that programs don't shadow these names.
+
\LMHash{}
A {\em namespace} is a mapping of names denoting declarations to actual declarations.
Let $NS$ be a namespace.
@@ -4907,7 +4917,13 @@
}
\LMHash{}
-If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementing the built-in class \code{Iterable} is associated with the invocation and immediately returned.
+If $f$ is marked \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{actualTypeOfADeclaration}).
+If $T$ is \code{Iterable<$S$>} for some type $S$, then $U$ is $S$,
+otherwise $U$ is \code{Object}.
\commentary{
A Dart implementation will need to provide a specific implementation of \code{Iterable} that will be returned by \SYNC* methods.
@@ -4957,7 +4973,10 @@
% The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. The yielded value might differ from the expression in the yield. And it is a potential memory leak as the cache is kept alive by any iterator.
\LMHash{}
-If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generativeConstructors}) $o$ implementing the built-in class \code{Future} is associated with the 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{actualTypeOfADeclaration}).
Then the body of $f$ is executed until it either suspends or completes, at which point $o$ is returned.
\commentary{
The body of $f$ may suspend during the evaluation of an \AWAIT{} expression or execution of an asynchronous \FOR{} loop.
@@ -4976,7 +4995,13 @@
}
\LMHash{}
-If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementing the built-in class \code{Stream} is associated with the invocation and immediately returned.
+If $f$ is marked \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{actualTypeOfADeclaration}).
+If $T$ is \code{Stream<$S$>} for some type $S$, then $U$ is $S$,
+otherwise $U$ is \code{Object}.
When $s$ is listened to, execution of the body of $f$ will begin.
When execution of the body of $f$ completes:
\begin{itemize}