@@ -11275,35 +11275,62 @@ \subsection{Function Expressions}
11275
11275
where inferred types have already been added.%
11276
11276
}
11277
11277
11278
+ \LMHash{}%
11279
+ We say that $S$ is the
11280
+ \IndexCustom{future type of a type}{type!future type of}
11281
+ $T$ in the following cases, using the first applicable case:
11282
+
11283
+ \begin{itemize}
11284
+ \item $T$ implements $S$
11285
+ (\ref{interfaceSuperinterfaces}),
11286
+ and there is a $U$ such that $S$ is \code{Future<$U$>}.
11287
+ \item $T$ is $S$ bounded
11288
+ (\ref{bindingActualsToFormals}),
11289
+ and there is a $U$ such that
11290
+ $S$ is \code{FutureOr<$U$>}, \code{Future<$U$>?}, or \code{FutureOr<$U$>?}.
11291
+ \end{itemize}
11292
+
11293
+ \LMHash{}%
11294
+ When none of these cases are applicable,
11295
+ we say that $T$ does not have a future type.
11296
+
11297
+ \commentary{%
11298
+ Note that if $T$ has a future type $F$ then \SubtypeNE{T}{F},
11299
+ and $F$ is always of the form \code{$G$<...>} or \code{$G$<...>?},
11300
+ where $G$ is \code{Future} or \code{FutureOr}.%
11301
+ }
11302
+
11278
11303
\LMHash{}%
11279
11304
We define the auxiliary function
11280
- \IndexCustom{\flatten{T}}{flatten(t)@\emph{flatten}$(T)$},
11281
- which is used below and in other sections, as follows :
11305
+ \IndexCustom{\flatten{T}}{flatten(t)@\emph{flatten}$(T)$}
11306
+ as follows, using the first applicable case :
11282
11307
11283
11308
\begin{itemize}
11284
- \item{} If $T$ is \code{$S$?}\ bounded
11285
- (\ref{bindingActualsToFormals})
11286
- for some $S$ then \DefEquals{\flatten{T}}{\code{\flatten{S}?}}.
11309
+ \item If $T$ is \code{$S$?}\ for some $S$
11310
+ then \DefEquals{\flatten{T}}{\code{\flatten{S}?}}.
11287
11311
11288
- \item{} If $T$ is \code{FutureOr<$S$>} bounded
11289
- then \DefEquals{\flatten{T}}{S}.
11312
+ \item If $T$ is \code{$X$\,\&\,$S$}
11313
+ for some type variable $X$ and type $S$ then
11314
+ \begin{itemize}
11315
+ \item if $S$ has future type $U$
11316
+ then \DefEquals{\flatten{T}}{\code{\flatten{U}}}.
11317
+ \item otherwise,
11318
+ \DefEquals{\flatten{T}}{\code{\flatten{X}}}.
11319
+ \end{itemize}
11290
11320
11291
- \item{} If $T$ implements \code{Future<$S$>}
11292
- (\ref{interfaceSuperinterfaces})
11321
+ \item If $T$ has future type \code{Future<$S$>}
11322
+ or \code{FutureOr<$S$>}
11293
11323
then \DefEquals{\flatten{T}}{S}.
11294
11324
11295
- \item{} Otherwise, \DefEquals{\flatten{T}}{T}.
11325
+ \item If $T$ has future type \code{Future<$S$>?}\ or
11326
+ \code{FutureOr<$S$>?}\ then \DefEquals{\flatten{T}}{\code{$S$?}}.
11327
+
11328
+ \item Otherwise, \DefEquals{\flatten{T}}{T}.
11296
11329
\end{itemize}
11297
11330
11298
- \commentary {%
11331
+ \rationale {%
11299
11332
This definition guarantees that for any type $T$,
11300
- \code{$T <:$ FutureOr<$\flatten{T}$>}.
11301
- Note that when $X$ is a type variable with bound $B$,
11302
- it is possible that \flatten{X} is different from $X$:
11303
- $B$ could, for some $S$, be \code{FutureOr<$S$>},
11304
- or a type variable $Y$ with bound \code{FutureOr<$S$>},
11305
- or a class $C$ that implements \code{Future<$S$>},
11306
- or a type variable $X$ with bound $C$.%
11333
+ \code{$T <:$ FutureOr<$\flatten{T}$>}.%
11307
11334
}
11308
11335
11309
11336
\LMHash{}%
@@ -15992,27 +16019,25 @@ \subsection{Await Expressions}
15992
16019
\end{grammar}
15993
16020
15994
16021
\LMHash{}%
15995
- Evaluation of an await expression $a$ of the form \code{\AWAIT{} $e$}
15996
- where $e$ has static type $S$ proceeds as follows:
15997
- First, the expression $e$ is evaluated to an object $o$.
15998
- Let $T$ be \flatten{S}
15999
- (\flatten{} is defined in section \ref{functionExpressions}).
16000
- It is a dynamic type error if the run-time type of $o$ is not a subtype
16001
- of \code{FutureOr<$T$>} \commentary{(that is, if it is neither a subtype
16002
- of $T$ nor of \code{Future<$T$>})}.
16022
+ \BlindDefineSymbol{a, e, S}%
16023
+ Let $a$ be an expression of the form \code{\AWAIT\,\,$e$}.
16024
+ Let $S$ be the static type of $e$.
16025
+ The static type of $a$ is then \flatten{S}
16026
+ (\ref{functionExpressions}).
16003
16027
16004
16028
\LMHash{}%
16005
- % NOTICE: Removed the requirement that an error thrown by $e$ is caught in a
16006
- % future. There is no reason $var x = e; await x;$ and $await e$ should behave
16007
- % differently, and no implementation actually implemented it .
16029
+ Evaluation of $a$ proceeds as follows:
16030
+ First, the expression $e$ is evaluated to an object $o$.
16031
+ Let \DefineSymbol{T} be \flatten{S} .
16008
16032
If the run-time type of $o$ is a subtype of \code{Future<$T$>},
16009
- then let $f$ be $o$;
16033
+ then let \DefineSymbol{f} be $o$;
16010
16034
otherwise let $f$ be the result of creating
16011
16035
a new object using the constructor \code{Future<$T$>.value()}
16012
16036
with $o$ as its argument.
16013
16037
16014
16038
\LMHash{}%
16015
- Next, the stream associated with the innermost enclosing asynchronous for loop
16039
+ Next, the stream associated with
16040
+ the innermost enclosing asynchronous \FOR{} loop
16016
16041
(\ref{asynchronousFor-in}),
16017
16042
if any, is paused.
16018
16043
The current invocation of the function body immediately enclosing $a$
@@ -16023,8 +16048,34 @@ \subsection{Await Expressions}
16023
16048
(\ref{expressionEvaluation}).
16024
16049
If $f$ completes with an object $v$, $a$ evaluates to $v$.
16025
16050
16026
- % Otherwise, the value of $a$ is the value of $e$. If evaluation of
16027
- % $e$ raises an exception $x$, $a$ raises $x$.
16051
+ \rationale{%
16052
+ The use of \flattenName{} to find $T$ and hence determine the dynamic type test
16053
+ implies that we await a future in every case where this choice is sound.%
16054
+ }
16055
+
16056
+ \commentary{%
16057
+ An interesting case on the edge of this trade-off is when $e$
16058
+ has the static type \code{FutureOr<Object>?}.
16059
+ You could say that the intention behind this type is that
16060
+ the value of $e$ is a \code{Future<Object>},
16061
+ or it is an \code{Object} which is not a future,
16062
+ or it is \NULL.
16063
+ So, presumably, we should await the first kind,
16064
+ and we should pass on the second and third kind unchanged.
16065
+ However, the second kind could be a \code{Future<Object?>}.
16066
+ This object isn't a \code{Future<Object>}, and it isn't \NULL,
16067
+ so it \emph{must} be considered to be in the second group.
16068
+ Nevertheless, \flatten{\code{FutureOr<Object>?}} is \code{Object?},
16069
+ so we \emph{will} await a \code{Future<Object?>}.
16070
+ We have chosen this semantics because it was the smallest breaking change
16071
+ relative to the semantics in earlier versions of Dart,
16072
+ and also because it allows for a simple rule:
16073
+ The type of \code{\AWAIT\,\,$e$} is used to decide whether or not
16074
+ the future (if any) is awaited, and there are no exceptions---even
16075
+ in cases like this example, where the type seems to imply that
16076
+ a \code{Future<Object?>} should not be awaited.
16077
+ In summary, we await every future that we can soundly await.%
16078
+ }
16028
16079
16029
16080
\commentary{%
16030
16081
An await expression can only occur in a function which is declared
@@ -16047,9 +16098,6 @@ \subsection{Await Expressions}
16047
16098
Tools may choose to give a hint in such cases.%
16048
16099
}
16049
16100
16050
- \LMHash{}%
16051
- The static type of $a$ is $T$.
16052
-
16053
16101
16054
16102
\subsection{Postfix Expressions}
16055
16103
\LMLabel{postfixExpressions}
0 commit comments