@@ -23468,7 +23468,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23468
23468
\FUNCTION}.
23469
23469
\item
23470
23470
Let $U_1$ and $U_2$ be, respectively,
23471
-
23471
+
23472
23472
\noindent
23473
23473
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23474
23474
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23501,7 +23501,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23501
23501
\noindent
23502
23502
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23503
23503
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23504
-
23504
+
23505
23505
\noindent
23506
23506
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23507
23507
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23515,7 +23515,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23515
23515
\item For each required entry named $n$ in $\metavar{Named}_2$,
23516
23516
$\metavar{Named}_1$ contains an entry named $n$
23517
23517
(\commentary{which may or may not be required}).
23518
- \end{itemize}
23518
+ \end{itemize}
23519
23519
23520
23520
Then \DefEqualsNewline{\UpperBoundType{$U_1$}{$U_2$}}{%
23521
23521
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
@@ -23560,7 +23560,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23560
23560
\item
23561
23561
\DefEqualsNewline{\UpperBoundType{$T_1$}{$S$ \FUNCTION<\ldots>(\ldots)}}{%
23562
23562
\UpperBoundType{$T_1$}{Object}}.
23563
- \item
23563
+ \item
23564
23564
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{FutureOr<$T_2$>}}{%
23565
23565
\code{FutureOr<$T_3$>}},
23566
23566
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23576,7 +23576,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23576
23576
\DefEquals{\UpperBoundType{$T_1$}{FutureOr<$T_2$>}}{%
23577
23577
\code{FutureOr<$T_3$>}},
23578
23578
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
23579
- \item
23579
+ \item
23580
23580
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{$T_2$}}{%
23581
23581
\code{FutureOr<$T_3$>}},
23582
23582
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23723,7 +23723,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23723
23723
%%
23724
23724
\item
23725
23725
Let $U_1$ and $U_2$ be, respectively,
23726
-
23726
+
23727
23727
\noindent
23728
23728
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23729
23729
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23738,7 +23738,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23738
23738
let $T_3$ be \LowerBoundType{$T_1$}{$T_2$},
23739
23739
let $B_{3i}$ be $B_{1i}$, and
23740
23740
let $P_{3i}$ be determined as follows:
23741
-
23741
+
23742
23742
\begin{itemize}
23743
23743
\item $P_{3i}$ is \UpperBoundType{$P_{1i}$}{$P_{2i}$} for
23744
23744
$i \leq \metavar{min}(k, l)$.
@@ -23747,7 +23747,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23747
23747
\item $P_{3i}$ is optional if $P_{1i}$ or $P_{2i}$ is optional,
23748
23748
or if $\metavar{min}(k, l) < i \leq q$.
23749
23749
\end{itemize}
23750
-
23750
+
23751
23751
Then \DefEqualsNewline{\LowerBoundType{$U_1$}{$U_2$}}{%
23752
23752
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
23753
23753
\EXTENDS\,$B_{3m}$>($P_{31}$,\,\ldots,\,$P_{3q}$)}}.
@@ -23765,7 +23765,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23765
23765
\noindent
23766
23766
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23767
23767
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23768
-
23768
+
23769
23769
\noindent
23770
23770
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23771
23771
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23872,7 +23872,7 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
23872
23872
\commentary{%
23873
23873
For example, the algorithm yields \code{Object} as the standard upper bound of
23874
23874
\code{List<Comparable<int>{}>} and \code{Iterable<int>},
23875
- but it is easy to see that a tighter upper bound exists, e.g.,
23875
+ but it is easy to see that a tighter upper bound exists, e.g.,
23876
23876
\code{Iterable<Comparable<num>{}>}.%
23877
23877
}
23878
23878
@@ -23918,18 +23918,16 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
23918
23918
The least upper bound of $I$ and $J$ is then the sole element of $M_q$.
23919
23919
23920
23920
23921
- \subsubsection{Standard Upper Bound Termination }
23922
- \LMLabel{standardUpperBoundTermination }
23921
+ \subsubsection{Standard Upper Bound Issues }
23922
+ \LMLabel{standardUpperBoundIssues }
23923
23923
23924
- %% TODO(eernst), for review: This section could be turned into a few github
23925
- %% issues, but it seems reasonable to let the user of Dart know about it.
23926
- %% So do we include it, or do we delete the whole section (and create those
23927
- %% github issues)?
23928
- %%
23929
- %% Note that I omitted the symmetry issue: The given example does not
23930
- %% demonstrate any asymmetry (both results have type `List<dynamic>`).
23931
- %% So we should study the symmetry properties a bit more if we keep this
23932
- %% section.
23924
+ %% TODO(eernst), for review: I kept this here (and updated some parts of it)
23925
+ %% in order to ensure that this information is preserved. However, it should
23926
+ %% perhaps not be in the specification. Should it actually be turned into
23927
+ %% a couple of github issues? In any case, it makes sense to communicate
23928
+ %% these properties of the algoritm to anyone who needs to know the language
23929
+ %% in full detail, which could justify keeping it here, or including a
23930
+ %% reference to some other location where the information is available.
23933
23931
23934
23932
\commentary{%
23935
23933
The definition of the standard upper bound for type variables
@@ -23938,9 +23936,7 @@ \subsubsection{Standard Upper Bound Termination}
23938
23936
}
23939
23937
23940
23938
\begin{dartCode}
23941
- \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>() \{
23942
- T x;
23943
- S y;
23939
+ \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>(T x, S y) \{
23944
23940
\VAR{} a = (x == y) ? x : y;
23945
23941
\}
23946
23942
\end{dartCode}
@@ -23957,6 +23953,43 @@ \subsubsection{Standard Upper Bound Termination}
23957
23953
with the current algorithm.%
23958
23954
}
23959
23955
23956
+ \commentary{%
23957
+ The current algorithm is asymmetric.
23958
+ There is an equivalence class of top types,
23959
+ and we correctly choose a canonical representative for bare top types
23960
+ using the \IsMoreTopTypeName{} predicate.
23961
+ However, when two different top types are embedded in two mutual subtypes,
23962
+ we don't correctly choose a canonical representative.%
23963
+ }
23964
+
23965
+ \begin{dartCode}
23966
+ \IMPORT{} 'dart:async';
23967
+ \\
23968
+ \VOID{} main() \{
23969
+ List<FutureOr<Object?>{}> x;
23970
+ List<\DYNAMIC> y;
23971
+
23972
+ var a = (x == y) ? x : y; // List<\DYNAMIC>.
23973
+ var b = (x == y) ? y : x; // List<FutureOr<Object?>{}>.
23974
+ \}
23975
+ \end{dartCode}
23976
+
23977
+ \commentary{%
23978
+ The best solution for this is probably to normalize the types.
23979
+ This is fairly straightforward:
23980
+ We just normalize \code{FutureOr<$T$>} to the normal form of $T$
23981
+ when $T$ is a top type.
23982
+ We can then inductively apply this across the rest of the types.
23983
+ Then, whenever we have mutual subtypes, we just return the normal form.
23984
+ This would be breaking, albeit hopefully only in a minor way.
23985
+
23986
+ A similar treatment would need to be done for the bottom types as well,
23987
+ since there are two equivalences there:
23988
+ A type variable $X$ with bound $T$ is equivalent to \code{Never}
23989
+ if $T$ is equivalent to \code{Never},
23990
+ and \code{FutureOr<Never>} is equivalent to \code{Future<Never>}.%
23991
+ }
23992
+
23960
23993
23961
23994
\subsection{Least and Greatest Closure of Types}
23962
23995
\LMLabel{leastAndGreatestClosureOfTypes}
0 commit comments