Skip to content

Commit a3b45ab

Browse files
authored
Breaking change to await, update to flatten. (#2333)
This PR specifies a breaking change to await, and an update to flatten which includes null safety. In particular, **flatten** is changed such that it is defined for type variables and intersection types. It changes `await` to throw when provided a `Future` value of a type that could provide an unsound value if awaited. This differs from the current specification, which instead treats the future as a value, so `await someFuture` can evaluate to `someFuture`. It also differs from the current implementation, which awaits `someFuture` to its value, whether the result is sound or not. See also dart-lang/sdk#49396, #2326.
1 parent 0a1284c commit a3b45ab

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

specification/dart.sty

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@
281281
% name of optional parameters, number of optional parameters.
282282
\newcommand{\FunctionTypeNamedArguments}[4]{%
283283
\List{#1}{1}{#2},\ \{\PairList{#1}{#3}{{#2}+1}{{#2}+{#4}}\}}
284-
284+
285285
\newcommand{\FunctionTypeNamedArgumentsStd}{%
286286
\FunctionTypeNamedArguments{T}{n}{x}{k}}
287287

@@ -387,6 +387,12 @@
387387
\newcommand{\EvaluateElementName}{\metavar{evaluateElement}}
388388
\newcommand{\EvaluateElement}[1]{\ensuremath{\EvaluateElementName({#1})}}
389389

390+
\newcommand{\DefEquals}[2]{\ensuremath{{#1}\stackrel{\vartriangle}{=}{#2}}}
391+
\newcommand{\DefEqualsNewline}[2]{
392+
\ensuremath{{#1}\stackrel{\vartriangle}{=}}\\
393+
\ensuremath{{#2}}%
394+
}
395+
390396
% ----------------------------------------------------------------------
391397
% Support for hash valued Location Markers
392398

specification/dartLangSpec.tex

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11267,33 +11267,29 @@ \subsection{Function Expressions}
1126711267
which is used below and in other sections, as follows:
1126811268

1126911269
\begin{itemize}
11270-
\item If $T$ is \code{FutureOr<$S$>} for some $S$ then $\flatten{T} = S$.
11270+
\item{} If $T$ is a type variable $X$ with bound $B$,
11271+
or $T$ is an intersection type
11272+
(\ref{intersectionTypes})
11273+
\code{$X$\,\,\&\,\,$B$},
11274+
then \DefEquals{\flatten{T}}{\flatten{B}}.
1127111275

11272-
\item Otherwise if
11273-
\code{$T <:$ Future}
11274-
then let $S$ be a type such that
11275-
\code{$T <:$ Future<$S$>}
11276-
and for all $R$, if
11277-
\code{$T <:$ Future<$R$>}
11278-
then $S <: R$.
11276+
\item{} If $T$ is \code{$S$?}\ for some $S$
11277+
then \DefEquals{\flatten{T}}{\code{\flatten{S}?}}.
1127911278

11280-
\rationale{%
11281-
This ensures that
11282-
\code{Future<$S$>}
11283-
is the most specific generic instantiation of \code{Future} that is
11284-
a supertype of $T$.
11285-
%% TODO[class-interfaces]: When we have finished the specification of class
11286-
%% interface computations we may have the following property, but it is not
11287-
%% true at this point. Adjust the following by then!
11288-
Note that $S$ is well-defined because of
11289-
the requirements on superinterfaces.%
11290-
}
11279+
\item{} If $T$ is \code{FutureOr<$S$>} then \DefEquals{\flatten{T}}{S}.
1129111280

11292-
Then $\flatten{T} = S$.
11281+
\item{} If $T$ implements \code{Future<$S$>}
11282+
(\ref{interfaceSuperinterfaces})
11283+
then \DefEquals{\flatten{T}}{S}.
1129311284

11294-
\item In any other circumstance, $\flatten{T} = T$.
11285+
\item{} Otherwise, \DefEquals{\flatten{T}}{T}.
1129511286
\end{itemize}
1129611287

11288+
\commentary{%
11289+
This definition guarantees that for any type $T$,
11290+
\code{$T <:$ FutureOr<$\flatten{T}$>}.%
11291+
}
11292+
1129711293
\LMHash{}%
1129811294
\Case{Positional, arrow}
1129911295
The static type of a function literal of the form
@@ -13755,7 +13751,7 @@ \subsubsection{Ordinary Invocation}
1375513751
}
1375613752

1375713753
\commentary{%
13758-
An member access on a type literal
13754+
A member access on a type literal
1375913755
(e.g., \code{C.id()}, \code{C.id}, or \code{C?.id()}),
1376013756
always treats the declaration denoted by the literal as
1376113757
a namespace for accessing static members or constructors.
@@ -15993,11 +15989,18 @@ \subsection{Await Expressions}
1599315989
% NOTICE: Removed the requirement that an error thrown by $e$ is caught in a
1599415990
% future. There is no reason $var x = e; await x;$ and $await e$ should behave
1599515991
% differently, and no implementation actually implemented it.
15996-
If the run-time type of $o$ is a subtype of \code{Future<$T$>},
15997-
then let $f$ be $o$;
15998-
otherwise let $f$ be the result of creating
15999-
a new object using the constructor \code{Future<$T$>.value()}
16000-
with $o$ as its argument.
15992+
Let $R$ be the run-time type of $o$.
15993+
If $R$ implements \code{Future<$S$>} for some $S$
15994+
(\ref{interfaceSuperinterfaces}) then
15995+
it is a dynamic type error if $S$ is not a subtype of $T$.
15996+
Otherwise
15997+
(\commentary{if no run-time error occurred}),
15998+
let $f$ be $o$.
15999+
16000+
Otherwise
16001+
(\commentary{when $R$ does not implement \code{Future}}),
16002+
let $f$ be an object whose run-time type implements \code{Future<$T$>},
16003+
which is completed with the value $o$.
1600116004

1600216005
\LMHash{}%
1600316006
Next, the stream associated with the innermost enclosing asynchronous for loop

0 commit comments

Comments
 (0)