@@ -23791,7 +23791,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23791
23791
\FUNCTION}.
23792
23792
\item
23793
23793
Let $U_1$ and $U_2$ be, respectively,
23794
-
23794
+
23795
23795
\noindent
23796
23796
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23797
23797
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23824,7 +23824,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23824
23824
\noindent
23825
23825
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23826
23826
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23827
-
23827
+
23828
23828
\noindent
23829
23829
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23830
23830
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23838,7 +23838,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23838
23838
\item For each required entry named $n$ in $\metavar{Named}_2$,
23839
23839
$\metavar{Named}_1$ contains an entry named $n$
23840
23840
(\commentary{which may or may not be required}).
23841
- \end{itemize}
23841
+ \end{itemize}
23842
23842
23843
23843
Then \DefEqualsNewline{\UpperBoundType{$U_1$}{$U_2$}}{%
23844
23844
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
@@ -23883,7 +23883,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23883
23883
\item
23884
23884
\DefEqualsNewline{\UpperBoundType{$T_1$}{$S$ \FUNCTION<\ldots>(\ldots)}}{%
23885
23885
\UpperBoundType{$T_1$}{Object}}.
23886
- \item
23886
+ \item
23887
23887
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{FutureOr<$T_2$>}}{%
23888
23888
\code{FutureOr<$T_3$>}},
23889
23889
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23899,7 +23899,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23899
23899
\DefEquals{\UpperBoundType{$T_1$}{FutureOr<$T_2$>}}{%
23900
23900
\code{FutureOr<$T_3$>}},
23901
23901
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
23902
- \item
23902
+ \item
23903
23903
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{$T_2$}}{%
23904
23904
\code{FutureOr<$T_3$>}},
23905
23905
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -24046,7 +24046,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24046
24046
%%
24047
24047
\item
24048
24048
Let $U_1$ and $U_2$ be, respectively,
24049
-
24049
+
24050
24050
\noindent
24051
24051
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
24052
24052
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -24061,7 +24061,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24061
24061
let $T_3$ be \LowerBoundType{$T_1$}{$T_2$},
24062
24062
let $B_{3i}$ be $B_{1i}$, and
24063
24063
let $P_{3i}$ be determined as follows:
24064
-
24064
+
24065
24065
\begin{itemize}
24066
24066
\item $P_{3i}$ is \UpperBoundType{$P_{1i}$}{$P_{2i}$} for
24067
24067
$i \leq \metavar{min}(k, l)$.
@@ -24070,7 +24070,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24070
24070
\item $P_{3i}$ is optional if $P_{1i}$ or $P_{2i}$ is optional,
24071
24071
or if $\metavar{min}(k, l) < i \leq q$.
24072
24072
\end{itemize}
24073
-
24073
+
24074
24074
Then \DefEqualsNewline{\LowerBoundType{$U_1$}{$U_2$}}{%
24075
24075
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
24076
24076
\EXTENDS\,$B_{3m}$>($P_{31}$,\,\ldots,\,$P_{3q}$)}}.
@@ -24088,7 +24088,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24088
24088
\noindent
24089
24089
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
24090
24090
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
24091
-
24091
+
24092
24092
\noindent
24093
24093
where $\metavar{Named}_j$ declares a non-empty set of named parameters
24094
24094
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -24195,7 +24195,7 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
24195
24195
\commentary{%
24196
24196
For example, the algorithm yields \code{Object} as the standard upper bound of
24197
24197
\code{List<Comparable<int>{}>} and \code{Iterable<int>},
24198
- but it is easy to see that a tighter upper bound exists, e.g.,
24198
+ but it is easy to see that a tighter upper bound exists, e.g.,
24199
24199
\code{Iterable<Comparable<num>{}>}.%
24200
24200
}
24201
24201
@@ -24241,18 +24241,16 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
24241
24241
The least upper bound of $I$ and $J$ is then the sole element of $M_q$.
24242
24242
24243
24243
24244
- \subsubsection{Standard Upper Bound Termination }
24245
- \LMLabel{standardUpperBoundTermination }
24244
+ \subsubsection{Standard Upper Bound Issues }
24245
+ \LMLabel{standardUpperBoundIssues }
24246
24246
24247
- %% TODO(eernst), for review: This section could be turned into a few github
24248
- %% issues, but it seems reasonable to let the user of Dart know about it.
24249
- %% So do we include it, or do we delete the whole section (and create those
24250
- %% github issues)?
24251
- %%
24252
- %% Note that I omitted the symmetry issue: The given example does not
24253
- %% demonstrate any asymmetry (both results have type `List<dynamic>`).
24254
- %% So we should study the symmetry properties a bit more if we keep this
24255
- %% section.
24247
+ %% TODO(eernst), for review: I kept this here (and updated some parts of it)
24248
+ %% in order to ensure that this information is preserved. However, it should
24249
+ %% perhaps not be in the specification. Should it actually be turned into
24250
+ %% a couple of github issues? In any case, it makes sense to communicate
24251
+ %% these properties of the algoritm to anyone who needs to know the language
24252
+ %% in full detail, which could justify keeping it here, or including a
24253
+ %% reference to some other location where the information is available.
24256
24254
24257
24255
\commentary{%
24258
24256
The definition of the standard upper bound for type variables
@@ -24261,9 +24259,7 @@ \subsubsection{Standard Upper Bound Termination}
24261
24259
}
24262
24260
24263
24261
\begin{dartCode}
24264
- \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>() \{
24265
- T x;
24266
- S y;
24262
+ \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>(T x, S y) \{
24267
24263
\VAR{} a = (x == y) ? x : y;
24268
24264
\}
24269
24265
\end{dartCode}
@@ -24280,6 +24276,43 @@ \subsubsection{Standard Upper Bound Termination}
24280
24276
with the current algorithm.%
24281
24277
}
24282
24278
24279
+ \commentary{%
24280
+ The current algorithm is asymmetric.
24281
+ There is an equivalence class of top types,
24282
+ and we correctly choose a canonical representative for bare top types
24283
+ using the \IsMoreTopTypeName{} predicate.
24284
+ However, when two different top types are embedded in two mutual subtypes,
24285
+ we don't correctly choose a canonical representative.%
24286
+ }
24287
+
24288
+ \begin{dartCode}
24289
+ \IMPORT{} 'dart:async';
24290
+ \\
24291
+ \VOID{} main() \{
24292
+ List<FutureOr<Object?>{}> x;
24293
+ List<\DYNAMIC> y;
24294
+
24295
+ var a = (x == y) ? x : y; // List<\DYNAMIC>.
24296
+ var b = (x == y) ? y : x; // List<FutureOr<Object?>{}>.
24297
+ \}
24298
+ \end{dartCode}
24299
+
24300
+ \commentary{%
24301
+ The best solution for this is probably to normalize the types.
24302
+ This is fairly straightforward:
24303
+ We just normalize \code{FutureOr<$T$>} to the normal form of $T$
24304
+ when $T$ is a top type.
24305
+ We can then inductively apply this across the rest of the types.
24306
+ Then, whenever we have mutual subtypes, we just return the normal form.
24307
+ This would be breaking, albeit hopefully only in a minor way.
24308
+
24309
+ A similar treatment would need to be done for the bottom types as well,
24310
+ since there are two equivalences there:
24311
+ A type variable $X$ with bound $T$ is equivalent to \code{Never}
24312
+ if $T$ is equivalent to \code{Never},
24313
+ and \code{FutureOr<Never>} is equivalent to \code{Future<Never>}.%
24314
+ }
24315
+
24283
24316
24284
24317
\subsection{Least and Greatest Closure of Types}
24285
24318
\LMLabel{leastAndGreatestClosureOfTypes}
0 commit comments