@@ -24225,7 +24225,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24225
24225
\FUNCTION}.
24226
24226
\item
24227
24227
Let $U_1$ and $U_2$ be, respectively,
24228
-
24228
+
24229
24229
\noindent
24230
24230
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
24231
24231
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -24258,7 +24258,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24258
24258
\noindent
24259
24259
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
24260
24260
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
24261
-
24261
+
24262
24262
\noindent
24263
24263
where $\metavar{Named}_j$ declares a non-empty set of named parameters
24264
24264
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -24272,7 +24272,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24272
24272
\item For each required entry named $n$ in $\metavar{Named}_2$,
24273
24273
$\metavar{Named}_1$ contains an entry named $n$
24274
24274
(\commentary{which may or may not be required}).
24275
- \end{itemize}
24275
+ \end{itemize}
24276
24276
24277
24277
Then \DefEqualsNewline{\UpperBoundType{$U_1$}{$U_2$}}{%
24278
24278
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
@@ -24317,7 +24317,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24317
24317
\item
24318
24318
\DefEqualsNewline{\UpperBoundType{$T_1$}{$S$ \FUNCTION<\ldots>(\ldots)}}{%
24319
24319
\UpperBoundType{$T_1$}{Object}}.
24320
- \item
24320
+ \item
24321
24321
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{FutureOr<$T_2$>}}{%
24322
24322
\code{FutureOr<$T_3$>}},
24323
24323
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -24333,7 +24333,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24333
24333
\DefEquals{\UpperBoundType{$T_1$}{FutureOr<$T_2$>}}{%
24334
24334
\code{FutureOr<$T_3$>}},
24335
24335
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
24336
- \item
24336
+ \item
24337
24337
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{$T_2$}}{%
24338
24338
\code{FutureOr<$T_3$>}},
24339
24339
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -24480,7 +24480,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24480
24480
%%
24481
24481
\item
24482
24482
Let $U_1$ and $U_2$ be, respectively,
24483
-
24483
+
24484
24484
\noindent
24485
24485
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
24486
24486
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -24495,7 +24495,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24495
24495
let $T_3$ be \LowerBoundType{$T_1$}{$T_2$},
24496
24496
let $B_{3i}$ be $B_{1i}$, and
24497
24497
let $P_{3i}$ be determined as follows:
24498
-
24498
+
24499
24499
\begin{itemize}
24500
24500
\item $P_{3i}$ is \UpperBoundType{$P_{1i}$}{$P_{2i}$} for
24501
24501
$i \leq \metavar{min}(k, l)$.
@@ -24504,7 +24504,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24504
24504
\item $P_{3i}$ is optional if $P_{1i}$ or $P_{2i}$ is optional,
24505
24505
or if $\metavar{min}(k, l) < i \leq q$.
24506
24506
\end{itemize}
24507
-
24507
+
24508
24508
Then \DefEqualsNewline{\LowerBoundType{$U_1$}{$U_2$}}{%
24509
24509
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
24510
24510
\EXTENDS\,$B_{3m}$>($P_{31}$,\,\ldots,\,$P_{3q}$)}}.
@@ -24522,7 +24522,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24522
24522
\noindent
24523
24523
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
24524
24524
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
24525
-
24525
+
24526
24526
\noindent
24527
24527
where $\metavar{Named}_j$ declares a non-empty set of named parameters
24528
24528
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -24629,7 +24629,7 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
24629
24629
\commentary{%
24630
24630
For example, the algorithm yields \code{Object} as the standard upper bound of
24631
24631
\code{List<Comparable<int>{}>} and \code{Iterable<int>},
24632
- but it is easy to see that a tighter upper bound exists, e.g.,
24632
+ but it is easy to see that a tighter upper bound exists, e.g.,
24633
24633
\code{Iterable<Comparable<num>{}>}.%
24634
24634
}
24635
24635
@@ -24675,18 +24675,16 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
24675
24675
The least upper bound of $I$ and $J$ is then the sole element of $M_q$.
24676
24676
24677
24677
24678
- \subsubsection{Standard Upper Bound Termination }
24679
- \LMLabel{standardUpperBoundTermination }
24678
+ \subsubsection{Standard Upper Bound Issues }
24679
+ \LMLabel{standardUpperBoundIssues }
24680
24680
24681
- %% TODO(eernst), for review: This section could be turned into a few github
24682
- %% issues, but it seems reasonable to let the user of Dart know about it.
24683
- %% So do we include it, or do we delete the whole section (and create those
24684
- %% github issues)?
24685
- %%
24686
- %% Note that I omitted the symmetry issue: The given example does not
24687
- %% demonstrate any asymmetry (both results have type `List<dynamic>`).
24688
- %% So we should study the symmetry properties a bit more if we keep this
24689
- %% section.
24681
+ %% TODO(eernst), for review: I kept this here (and updated some parts of it)
24682
+ %% in order to ensure that this information is preserved. However, it should
24683
+ %% perhaps not be in the specification. Should it actually be turned into
24684
+ %% a couple of github issues? In any case, it makes sense to communicate
24685
+ %% these properties of the algoritm to anyone who needs to know the language
24686
+ %% in full detail, which could justify keeping it here, or including a
24687
+ %% reference to some other location where the information is available.
24690
24688
24691
24689
\commentary{%
24692
24690
The definition of the standard upper bound for type variables
@@ -24695,9 +24693,7 @@ \subsubsection{Standard Upper Bound Termination}
24695
24693
}
24696
24694
24697
24695
\begin{dartCode}
24698
- \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>() \{
24699
- T x;
24700
- S y;
24696
+ \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>(T x, S y) \{
24701
24697
\VAR{} a = (x == y) ? x : y;
24702
24698
\}
24703
24699
\end{dartCode}
@@ -24714,6 +24710,43 @@ \subsubsection{Standard Upper Bound Termination}
24714
24710
with the current algorithm.%
24715
24711
}
24716
24712
24713
+ \commentary{%
24714
+ The current algorithm is asymmetric.
24715
+ There is an equivalence class of top types,
24716
+ and we correctly choose a canonical representative for bare top types
24717
+ using the \IsMoreTopTypeName{} predicate.
24718
+ However, when two different top types are embedded in two mutual subtypes,
24719
+ we don't correctly choose a canonical representative.%
24720
+ }
24721
+
24722
+ \begin{dartCode}
24723
+ \IMPORT{} 'dart:async';
24724
+ \\
24725
+ \VOID{} main() \{
24726
+ List<FutureOr<Object?>{}> x;
24727
+ List<\DYNAMIC> y;
24728
+
24729
+ var a = (x == y) ? x : y; // List<\DYNAMIC>.
24730
+ var b = (x == y) ? y : x; // List<FutureOr<Object?>{}>.
24731
+ \}
24732
+ \end{dartCode}
24733
+
24734
+ \commentary{%
24735
+ The best solution for this is probably to normalize the types.
24736
+ This is fairly straightforward:
24737
+ We just normalize \code{FutureOr<$T$>} to the normal form of $T$
24738
+ when $T$ is a top type.
24739
+ We can then inductively apply this across the rest of the types.
24740
+ Then, whenever we have mutual subtypes, we just return the normal form.
24741
+ This would be breaking, albeit hopefully only in a minor way.
24742
+
24743
+ A similar treatment would need to be done for the bottom types as well,
24744
+ since there are two equivalences there:
24745
+ A type variable $X$ with bound $T$ is equivalent to \code{Never}
24746
+ if $T$ is equivalent to \code{Never},
24747
+ and \code{FutureOr<Never>} is equivalent to \code{Future<Never>}.%
24748
+ }
24749
+
24717
24750
24718
24751
\subsection{Least and Greatest Closure of Types}
24719
24752
\LMLabel{leastAndGreatestClosureOfTypes}
0 commit comments