@@ -23606,7 +23606,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23606
23606
\FUNCTION}.
23607
23607
\item
23608
23608
Let $U_1$ and $U_2$ be, respectively,
23609
-
23609
+
23610
23610
\noindent
23611
23611
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23612
23612
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23639,7 +23639,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23639
23639
\noindent
23640
23640
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23641
23641
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23642
-
23642
+
23643
23643
\noindent
23644
23644
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23645
23645
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23653,7 +23653,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23653
23653
\item For each required entry named $n$ in $\metavar{Named}_2$,
23654
23654
$\metavar{Named}_1$ contains an entry named $n$
23655
23655
(\commentary{which may or may not be required}).
23656
- \end{itemize}
23656
+ \end{itemize}
23657
23657
23658
23658
Then \DefEqualsNewline{\UpperBoundType{$U_1$}{$U_2$}}{%
23659
23659
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
@@ -23698,7 +23698,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23698
23698
\item
23699
23699
\DefEqualsNewline{\UpperBoundType{$T_1$}{$S$ \FUNCTION<\ldots>(\ldots)}}{%
23700
23700
\UpperBoundType{$T_1$}{Object}}.
23701
- \item
23701
+ \item
23702
23702
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{FutureOr<$T_2$>}}{%
23703
23703
\code{FutureOr<$T_3$>}},
23704
23704
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23714,7 +23714,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23714
23714
\DefEquals{\UpperBoundType{$T_1$}{FutureOr<$T_2$>}}{%
23715
23715
\code{FutureOr<$T_3$>}},
23716
23716
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
23717
- \item
23717
+ \item
23718
23718
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{$T_2$}}{%
23719
23719
\code{FutureOr<$T_3$>}},
23720
23720
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23861,7 +23861,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23861
23861
%%
23862
23862
\item
23863
23863
Let $U_1$ and $U_2$ be, respectively,
23864
-
23864
+
23865
23865
\noindent
23866
23866
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23867
23867
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23876,7 +23876,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23876
23876
let $T_3$ be \LowerBoundType{$T_1$}{$T_2$},
23877
23877
let $B_{3i}$ be $B_{1i}$, and
23878
23878
let $P_{3i}$ be determined as follows:
23879
-
23879
+
23880
23880
\begin{itemize}
23881
23881
\item $P_{3i}$ is \UpperBoundType{$P_{1i}$}{$P_{2i}$} for
23882
23882
$i \leq \metavar{min}(k, l)$.
@@ -23885,7 +23885,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23885
23885
\item $P_{3i}$ is optional if $P_{1i}$ or $P_{2i}$ is optional,
23886
23886
or if $\metavar{min}(k, l) < i \leq q$.
23887
23887
\end{itemize}
23888
-
23888
+
23889
23889
Then \DefEqualsNewline{\LowerBoundType{$U_1$}{$U_2$}}{%
23890
23890
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
23891
23891
\EXTENDS\,$B_{3m}$>($P_{31}$,\,\ldots,\,$P_{3q}$)}}.
@@ -23903,7 +23903,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23903
23903
\noindent
23904
23904
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23905
23905
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23906
-
23906
+
23907
23907
\noindent
23908
23908
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23909
23909
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -24010,7 +24010,7 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
24010
24010
\commentary{%
24011
24011
For example, the algorithm yields \code{Object} as the standard upper bound of
24012
24012
\code{List<Comparable<int>{}>} and \code{Iterable<int>},
24013
- but it is easy to see that a tighter upper bound exists, e.g.,
24013
+ but it is easy to see that a tighter upper bound exists, e.g.,
24014
24014
\code{Iterable<Comparable<num>{}>}.%
24015
24015
}
24016
24016
@@ -24056,18 +24056,16 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
24056
24056
The least upper bound of $I$ and $J$ is then the sole element of $M_q$.
24057
24057
24058
24058
24059
- \subsubsection{Standard Upper Bound Termination }
24060
- \LMLabel{standardUpperBoundTermination }
24059
+ \subsubsection{Standard Upper Bound Issues }
24060
+ \LMLabel{standardUpperBoundIssues }
24061
24061
24062
- %% TODO(eernst), for review: This section could be turned into a few github
24063
- %% issues, but it seems reasonable to let the user of Dart know about it.
24064
- %% So do we include it, or do we delete the whole section (and create those
24065
- %% github issues)?
24066
- %%
24067
- %% Note that I omitted the symmetry issue: The given example does not
24068
- %% demonstrate any asymmetry (both results have type `List<dynamic>`).
24069
- %% So we should study the symmetry properties a bit more if we keep this
24070
- %% section.
24062
+ %% TODO(eernst), for review: I kept this here (and updated some parts of it)
24063
+ %% in order to ensure that this information is preserved. However, it should
24064
+ %% perhaps not be in the specification. Should it actually be turned into
24065
+ %% a couple of github issues? In any case, it makes sense to communicate
24066
+ %% these properties of the algoritm to anyone who needs to know the language
24067
+ %% in full detail, which could justify keeping it here, or including a
24068
+ %% reference to some other location where the information is available.
24071
24069
24072
24070
\commentary{%
24073
24071
The definition of the standard upper bound for type variables
@@ -24076,9 +24074,7 @@ \subsubsection{Standard Upper Bound Termination}
24076
24074
}
24077
24075
24078
24076
\begin{dartCode}
24079
- \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>() \{
24080
- T x;
24081
- S y;
24077
+ \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>(T x, S y) \{
24082
24078
\VAR{} a = (x == y) ? x : y;
24083
24079
\}
24084
24080
\end{dartCode}
@@ -24095,6 +24091,43 @@ \subsubsection{Standard Upper Bound Termination}
24095
24091
with the current algorithm.%
24096
24092
}
24097
24093
24094
+ \commentary{%
24095
+ The current algorithm is asymmetric.
24096
+ There is an equivalence class of top types,
24097
+ and we correctly choose a canonical representative for bare top types
24098
+ using the \IsMoreTopTypeName{} predicate.
24099
+ However, when two different top types are embedded in two mutual subtypes,
24100
+ we don't correctly choose a canonical representative.%
24101
+ }
24102
+
24103
+ \begin{dartCode}
24104
+ \IMPORT{} 'dart:async';
24105
+ \\
24106
+ \VOID{} main() \{
24107
+ List<FutureOr<Object?>{}> x;
24108
+ List<\DYNAMIC> y;
24109
+
24110
+ var a = (x == y) ? x : y; // List<\DYNAMIC>.
24111
+ var b = (x == y) ? y : x; // List<FutureOr<Object?>{}>.
24112
+ \}
24113
+ \end{dartCode}
24114
+
24115
+ \commentary{%
24116
+ The best solution for this is probably to normalize the types.
24117
+ This is fairly straightforward:
24118
+ We just normalize \code{FutureOr<$T$>} to the normal form of $T$
24119
+ when $T$ is a top type.
24120
+ We can then inductively apply this across the rest of the types.
24121
+ Then, whenever we have mutual subtypes, we just return the normal form.
24122
+ This would be breaking, albeit hopefully only in a minor way.
24123
+
24124
+ A similar treatment would need to be done for the bottom types as well,
24125
+ since there are two equivalences there:
24126
+ A type variable $X$ with bound $T$ is equivalent to \code{Never}
24127
+ if $T$ is equivalent to \code{Never},
24128
+ and \code{FutureOr<Never>} is equivalent to \code{Future<Never>}.%
24129
+ }
24130
+
24098
24131
24099
24132
\subsection{Least and Greatest Closure of Types}
24100
24133
\LMLabel{leastAndGreatestClosureOfTypes}
0 commit comments