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>
This commit is contained in:
@@ -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 @@ To get multiple copies of a library running simultaneously, one needs to spawn a
|
||||
\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 @@ Completing normally or returning without a value is treated the same as returnin
|
||||
}
|
||||
|
||||
\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 @@ Two executions of an iterator interact only via state outside the function.
|
||||
% 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 @@ so the future is not completed with an error {\em before} it has been returned.
|
||||
}
|
||||
|
||||
\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}
|
||||
|
||||
Reference in New Issue
Block a user