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