@@ -23250,7 +23250,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23250
23250
\FUNCTION}.
23251
23251
\item
23252
23252
Let $U_1$ and $U_2$ be, respectively,
23253
-
23253
+
23254
23254
\noindent
23255
23255
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23256
23256
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23283,7 +23283,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23283
23283
\noindent
23284
23284
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23285
23285
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23286
-
23286
+
23287
23287
\noindent
23288
23288
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23289
23289
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23297,7 +23297,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23297
23297
\item For each required entry named $n$ in $\metavar{Named}_2$,
23298
23298
$\metavar{Named}_1$ contains an entry named $n$
23299
23299
(\commentary{which may or may not be required}).
23300
- \end{itemize}
23300
+ \end{itemize}
23301
23301
23302
23302
Then \DefEqualsNewline{\UpperBoundType{$U_1$}{$U_2$}}{%
23303
23303
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
@@ -23342,7 +23342,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23342
23342
\item
23343
23343
\DefEqualsNewline{\UpperBoundType{$T_1$}{$S$ \FUNCTION<\ldots>(\ldots)}}{%
23344
23344
\UpperBoundType{$T_1$}{Object}}.
23345
- \item
23345
+ \item
23346
23346
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{FutureOr<$T_2$>}}{%
23347
23347
\code{FutureOr<$T_3$>}},
23348
23348
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23358,7 +23358,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23358
23358
\DefEquals{\UpperBoundType{$T_1$}{FutureOr<$T_2$>}}{%
23359
23359
\code{FutureOr<$T_3$>}},
23360
23360
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
23361
- \item
23361
+ \item
23362
23362
\DefEquals{\UpperBoundType{FutureOr<$T_1$>}{$T_2$}}{%
23363
23363
\code{FutureOr<$T_3$>}},
23364
23364
where $T_3$ = \UpperBoundType{$T_1$}{$T_2$}.
@@ -23505,7 +23505,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23505
23505
%%
23506
23506
\item
23507
23507
Let $U_1$ and $U_2$ be, respectively,
23508
-
23508
+
23509
23509
\noindent
23510
23510
\code{$T_1$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{11}$,\,\ldots,\,$X_m$\,%
23511
23511
\EXTENDS\,$B_{1m}$>($P_{11}$,\,\ldots,\,$P_{1k}$)}
@@ -23520,7 +23520,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23520
23520
let $T_3$ be \LowerBoundType{$T_1$}{$T_2$},
23521
23521
let $B_{3i}$ be $B_{1i}$, and
23522
23522
let $P_{3i}$ be determined as follows:
23523
-
23523
+
23524
23524
\begin{itemize}
23525
23525
\item $P_{3i}$ is \UpperBoundType{$P_{1i}$}{$P_{2i}$} for
23526
23526
$i \leq \metavar{min}(k, l)$.
@@ -23529,7 +23529,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23529
23529
\item $P_{3i}$ is optional if $P_{1i}$ or $P_{2i}$ is optional,
23530
23530
or if $\metavar{min}(k, l) < i \leq q$.
23531
23531
\end{itemize}
23532
-
23532
+
23533
23533
Then \DefEqualsNewline{\LowerBoundType{$U_1$}{$U_2$}}{%
23534
23534
\code{$T_3$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{31}$,\,\ldots,\,$X_m$\,%
23535
23535
\EXTENDS\,$B_{3m}$>($P_{31}$,\,\ldots,\,$P_{3q}$)}}.
@@ -23547,7 +23547,7 @@ \subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23547
23547
\noindent
23548
23548
\code{$T_2$\,\FUNCTION<$X_1$\,\EXTENDS\,$B_{21}$,\,\ldots,\,$X_m$\,%
23549
23549
\EXTENDS\,$B_{2m}$>($P_{21}$,\,\ldots,\,$P_{2k}$,\,$\metavar{Named}_2$)}
23550
-
23550
+
23551
23551
\noindent
23552
23552
where $\metavar{Named}_j$ declares a non-empty set of named parameters
23553
23553
with names $\metavar{NamesOfNamed}_j$, $j \in 1 .. 2$,
@@ -23654,7 +23654,7 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
23654
23654
\commentary{%
23655
23655
For example, the algorithm yields \code{Object} as the standard upper bound of
23656
23656
\code{List<Comparable<int>{}>} and \code{Iterable<int>},
23657
- but it is easy to see that a tighter upper bound exists, e.g.,
23657
+ but it is easy to see that a tighter upper bound exists, e.g.,
23658
23658
\code{Iterable<Comparable<num>{}>}.%
23659
23659
}
23660
23660
@@ -23700,18 +23700,16 @@ \subsubsection{The Standard Upper Bound of Distinct Interface Types}
23700
23700
The least upper bound of $I$ and $J$ is then the sole element of $M_q$.
23701
23701
23702
23702
23703
- \subsubsection{Standard Upper Bound Termination }
23704
- \LMLabel{standardUpperBoundTermination }
23703
+ \subsubsection{Standard Upper Bound Issues }
23704
+ \LMLabel{standardUpperBoundIssues }
23705
23705
23706
- %% TODO(eernst), for review: This section could be turned into a few github
23707
- %% issues, but it seems reasonable to let the user of Dart know about it.
23708
- %% So do we include it, or do we delete the whole section (and create those
23709
- %% github issues)?
23710
- %%
23711
- %% Note that I omitted the symmetry issue: The given example does not
23712
- %% demonstrate any asymmetry (both results have type `List<dynamic>`).
23713
- %% So we should study the symmetry properties a bit more if we keep this
23714
- %% section.
23706
+ %% TODO(eernst), for review: I kept this here (and updated some parts of it)
23707
+ %% in order to ensure that this information is preserved. However, it should
23708
+ %% perhaps not be in the specification. Should it actually be turned into
23709
+ %% a couple of github issues? In any case, it makes sense to communicate
23710
+ %% these properties of the algoritm to anyone who needs to know the language
23711
+ %% in full detail, which could justify keeping it here, or including a
23712
+ %% reference to some other location where the information is available.
23715
23713
23716
23714
\commentary{%
23717
23715
The definition of the standard upper bound for type variables
@@ -23720,9 +23718,7 @@ \subsubsection{Standard Upper Bound Termination}
23720
23718
}
23721
23719
23722
23720
\begin{dartCode}
23723
- \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>() \{
23724
- T x;
23725
- S y;
23721
+ \VOID{} foo<T \EXTENDS{} List<S>, S \EXTENDS{} List<T>>(T x, S y) \{
23726
23722
\VAR{} a = (x == y) ? x : y;
23727
23723
\}
23728
23724
\end{dartCode}
@@ -23739,6 +23735,43 @@ \subsubsection{Standard Upper Bound Termination}
23739
23735
with the current algorithm.%
23740
23736
}
23741
23737
23738
+ \commentary{%
23739
+ The current algorithm is asymmetric.
23740
+ There is an equivalence class of top types,
23741
+ and we correctly choose a canonical representative for bare top types
23742
+ using the \IsMoreTopTypeName{} predicate.
23743
+ However, when two different top types are embedded in two mutual subtypes,
23744
+ we don't correctly choose a canonical representative.%
23745
+ }
23746
+
23747
+ \begin{dartCode}
23748
+ \IMPORT{} 'dart:async';
23749
+ \\
23750
+ \VOID{} main() \{
23751
+ List<FutureOr<Object?>{}> x;
23752
+ List<\DYNAMIC> y;
23753
+
23754
+ var a = (x == y) ? x : y; // List<\DYNAMIC>.
23755
+ var b = (x == y) ? y : x; // List<FutureOr<Object?>{}>.
23756
+ \}
23757
+ \end{dartCode}
23758
+
23759
+ \commentary{%
23760
+ The best solution for this is probably to normalize the types.
23761
+ This is fairly straightforward:
23762
+ We just normalize \code{FutureOr<$T$>} to the normal form of $T$
23763
+ when $T$ is a top type.
23764
+ We can then inductively apply this across the rest of the types.
23765
+ Then, whenever we have mutual subtypes, we just return the normal form.
23766
+ This would be breaking, albeit hopefully only in a minor way.
23767
+
23768
+ A similar treatment would need to be done for the bottom types as well,
23769
+ since there are two equivalences there:
23770
+ A type variable $X$ with bound $T$ is equivalent to \code{Never}
23771
+ if $T$ is equivalent to \code{Never},
23772
+ and \code{FutureOr<Never>} is equivalent to \code{Future<Never>}.%
23773
+ }
23774
+
23742
23775
23743
23776
\subsection{Least and Greatest Closure of Types}
23744
23777
\LMLabel{leastAndGreatestClosureOfTypes}
0 commit comments