@@ -23339,7 +23339,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23339
23339
\FUNCTION}.
23340
23340
\item
23341
23341
Let $U_1$ and $U_2$ be, respectively,
23342
-
23342
+
23343
23343
\noindent
23344
23344
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23345
23345
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23372,7 +23372,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23372
23372
\noindent
23373
23373
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23374
23374
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23375
-
23375
+
23376
23376
\noindent
23377
23377
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23378
23378
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23386,7 +23386,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23386
23386
\item For each required entry named $n$ in $\metavar{Named}_2$,
23387
23387
$\metavar{Named}_1$ contains an entry named $n$
23388
23388
(\commentary{which may or may not be required}).
23389
- \end{itemize}
23389
+ \end{itemize}
23390
23390
23391
23391
Then \DefEqualsNewline{\UpperBoundType{$U_1$}{$U_2$}}{%
23392
23392
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
@@ -23431,7 +23431,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23431
23431
\item
23432
23432
\DefEqualsNewline{\UpperBoundType{$T_1$}{$S$ \FUNCTION<\ldots>(\ldots)}}{%
23433
23433
\UpperBoundType{$T_1$}{Object}}.
23434
- \item
23434
+ \item
23435
23435
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{FutureOr<$T_2$>}}{%
23436
23436
\code{FutureOr<$T_3$>}},
23437
23437
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23447,7 +23447,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23447
23447
\DefEquals{\UpperBoundType{$T_1$}{FutureOr<$T_2$>}}{%
23448
23448
\code{FutureOr<$T_3$>}},
23449
23449
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
23450
- \item
23450
+ \item
23451
23451
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{$T_2$}}{%
23452
23452
\code{FutureOr<$T_3$>}},
23453
23453
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23594,7 +23594,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23594
23594
%%
23595
23595
\item
23596
23596
Let $U_1$ and $U_2$ be, respectively,
23597
-
23597
+
23598
23598
\noindent
23599
23599
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23600
23600
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23609,7 +23609,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23609
23609
let $T_3$ be \LowerBoundType{$T_1$}{$T_2$},
23610
23610
let $B_{3i}$ be $B_{1i}$, and
23611
23611
let $P_{3i}$ be determined as follows:
23612
-
23612
+
23613
23613
\begin{itemize}
23614
23614
\item $P_{3i}$ is \UpperBoundType{$P_{1i}$}{$P_{2i}$} for
23615
23615
$i \leq \metavar{min}(k, l)$.
@@ -23618,7 +23618,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23618
23618
\item $P_{3i}$ is optional if $P_{1i}$ or $P_{2i}$ is optional,
23619
23619
or if $\metavar{min}(k, l) < i \leq q$.
23620
23620
\end{itemize}
23621
-
23621
+
23622
23622
Then \DefEqualsNewline{\LowerBoundType{$U_1$}{$U_2$}}{%
23623
23623
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
23624
23624
\EXTENDS\,$B_{3m}$>($P_{31}$,\,\ldots,\,$P_{3q}$)}}.
@@ -23636,7 +23636,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23636
23636
\noindent
23637
23637
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23638
23638
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23639
-
23639
+
23640
23640
\noindent
23641
23641
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23642
23642
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23743,7 +23743,7 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
23743
23743
\commentary{%
23744
23744
For example, the algorithm yields \code{Object} as the standard upper bound of
23745
23745
\code{List<Comparable<int>{}>} and \code{Iterable<int>},
23746
- but it is easy to see that a tighter upper bound exists, e.g.,
23746
+ but it is easy to see that a tighter upper bound exists, e.g.,
23747
23747
\code{Iterable<Comparable<num>{}>}.%
23748
23748
}
23749
23749
@@ -23789,18 +23789,16 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
23789
23789
The least upper bound of $I$ and $J$ is then the sole element of $M_q$.
23790
23790
23791
23791
23792
- \subsubsection{Standard Upper Bound Termination }
23793
- \LMLabel{standardUpperBoundTermination }
23792
+ \subsubsection{Standard Upper Bound Issues }
23793
+ \LMLabel{standardUpperBoundIssues }
23794
23794
23795
- %% TODO(eernst), for review: This section could be turned into a few github
23796
- %% issues, but it seems reasonable to let the user of Dart know about it.
23797
- %% So do we include it, or do we delete the whole section (and create those
23798
- %% github issues)?
23799
- %%
23800
- %% Note that I omitted the symmetry issue: The given example does not
23801
- %% demonstrate any asymmetry (both results have type `List<dynamic>`).
23802
- %% So we should study the symmetry properties a bit more if we keep this
23803
- %% section.
23795
+ %% TODO(eernst), for review: I kept this here (and updated some parts of it)
23796
+ %% in order to ensure that this information is preserved. However, it should
23797
+ %% perhaps not be in the specification. Should it actually be turned into
23798
+ %% a couple of github issues? In any case, it makes sense to communicate
23799
+ %% these properties of the algoritm to anyone who needs to know the language
23800
+ %% in full detail, which could justify keeping it here, or including a
23801
+ %% reference to some other location where the information is available.
23804
23802
23805
23803
\commentary{%
23806
23804
The definition of the standard upper bound for type variables
@@ -23809,9 +23807,7 @@ \subsubsection{Standard Upper Bound Termination}
23809
23807
}
23810
23808
23811
23809
\begin{dartCode}
23812
- \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>() \{
23813
- T x;
23814
- S y;
23810
+ \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>(T x, S y) \{
23815
23811
\VAR{} a = (x == y) ? x : y;
23816
23812
\}
23817
23813
\end{dartCode}
@@ -23828,6 +23824,43 @@ \subsubsection{Standard Upper Bound Termination}
23828
23824
with the current algorithm.%
23829
23825
}
23830
23826
23827
+ \commentary{%
23828
+ The current algorithm is asymmetric.
23829
+ There is an equivalence class of top types,
23830
+ and we correctly choose a canonical representative for bare top types
23831
+ using the \IsMoreTopTypeName{} predicate.
23832
+ However, when two different top types are embedded in two mutual subtypes,
23833
+ we don't correctly choose a canonical representative.%
23834
+ }
23835
+
23836
+ \begin{dartCode}
23837
+ \IMPORT{} 'dart:async';
23838
+ \\
23839
+ \VOID{} main() \{
23840
+ List<FutureOr<Object?>{}> x;
23841
+ List<\DYNAMIC> y;
23842
+
23843
+ var a = (x == y) ? x : y; // List<\DYNAMIC>.
23844
+ var b = (x == y) ? y : x; // List<FutureOr<Object?>{}>.
23845
+ \}
23846
+ \end{dartCode}
23847
+
23848
+ \commentary{%
23849
+ The best solution for this is probably to normalize the types.
23850
+ This is fairly straightforward:
23851
+ We just normalize \code{FutureOr<$T$>} to the normal form of $T$
23852
+ when $T$ is a top type.
23853
+ We can then inductively apply this across the rest of the types.
23854
+ Then, whenever we have mutual subtypes, we just return the normal form.
23855
+ This would be breaking, albeit hopefully only in a minor way.
23856
+
23857
+ A similar treatment would need to be done for the bottom types as well,
23858
+ since there are two equivalences there:
23859
+ A type variable $X$ with bound $T$ is equivalent to \code{Never}
23860
+ if $T$ is equivalent to \code{Never},
23861
+ and \code{FutureOr<Never>} is equivalent to \code{Future<Never>}.%
23862
+ }
23863
+
23831
23864
23832
23865
\subsection{Least and Greatest Closure of Types}
23833
23866
\LMLabel{leastAndGreatestClosureOfTypes}
0 commit comments