@@ -23939,12 +23939,13 @@ \subsubsection{The Canonical Syntax of Types}
23939
23939
\rationale{%
23940
23940
This shows that concrete syntax behaves in such a manner that it is
23941
23941
unsafe to consider two types as the same type,
23942
- based on the fact that they are denoted by the same syntax.
23942
+ based on the fact that they are denoted by the same syntax,
23943
+ even during the static analysis of a single expression.
23943
23944
23944
23945
Similarly, it is incorrect to consider two terms derived from \synt{type}
23945
- as different types based on the fact that they are syntactically different,
23946
- as they could in fact be the same type,
23947
- e.g., imported with different import prefixes.%
23946
+ as different types based on the fact that they are syntactically different.
23947
+ They could in fact be the same type,
23948
+ e.g., imported with different import prefixes.
23948
23949
23949
23950
Consequently, we introduce the notion of the canonical syntax for a type,
23950
23951
which has the property that each type has a unique syntactic form.
@@ -23960,49 +23961,63 @@ \subsubsection{The Canonical Syntax of Types}
23960
23961
of the types in a given library $L_1$
23961
23962
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23962
23963
one or more import links,
23963
- first choose a set of distinct fresh identifiers
23964
+ first choose a set of distinct, globally fresh identifiers
23964
23965
\List{\metavar{prefix}}{1}{n}.
23965
- Then transform each library $L_i$, $i \in 1 .. n$,
23966
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23967
- and $L_i$ imports \code{dart:core} explicitly
23968
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23969
- and change all existing imports to use the prefix
23970
- corresponding to the library which is being imported.
23966
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23971
23967
23972
- \LMHash{}%
23973
- Next, transform every identifier expression and every \synt{typeName}
23974
- that refers to an imported declaration or a library declaration
23975
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23976
- and such that every name resolves to the same declaration
23977
- as it did in the original program.
23968
+ \begin{enumerate}
23969
+ \item
23970
+ Add a set of import directives to $L_i$ that imports
23971
+ each of the libraries \List{L}{1}{n} with
23972
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23973
+
23974
+ \commentary{%
23975
+ This means that every library in the set
23976
+ $\{\,\List{L}{1}{n}\,\}$
23977
+ imports every other library in that set,
23978
+ even itself and system libraries like \code{dart:core}.%
23979
+ }
23980
+ \item
23981
+ Let \id{} be a non-private identifier that resolves to
23982
+ a library declaration in the library $L_j$ in the original program;
23983
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23984
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23985
+ an import prefix in the original program,
23986
+ \id{} is a non-private identifier,
23987
+ and \code{$p$.\id} resolves to
23988
+ a library declaration in the library $L_j$ in the original program;
23989
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23990
+ \item
23991
+ %% TODO(eernst): We should rename private names to fresh public names.
23992
+ Replace every type that denotes a type alias
23993
+ by its transitive alias expansion
23994
+ (\ref{typedef}).
23995
+ \commentary{%
23996
+ Note that the bodies of type alias declarations
23997
+ already use the new prefixes,
23998
+ so the results of the alias expansion will also use
23999
+ the new prefixes consistently.%
24000
+ }
24001
+ \end{enumerate}
23978
24002
23979
24003
\commentary{%
23980
24004
Note that this transformation does not change any occurrence of \VOID;
23981
- \VOID{} is a reserved word
23982
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23983
- }
24005
+ \VOID{} is a reserved word, not an identifier.
24006
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23984
24007
23985
- %% TODO(eernst), for review: Rename private names to fresh public names?
23986
- %% Otherwise the type alias could turn into a term containing private names
23987
- %% from different libraries.
23988
- \LMHash{}%
23989
- Finally, replace every type that denotes a type alias
23990
- by its transitive alias expansion
23991
- (\ref{typedef}).
23992
- \commentary{%
23993
- Note that the bodies of type alias declarations already use the new prefixes,
23994
- so the results of the alias expansion will also use
23995
- the new prefixes consistently.%
24008
+ The transformation also does not change identifiers denoting type variables,
24009
+ There is no need to change those identifiers, because
24010
+ no occurrence of such an identifier resolves to a declaration in a
24011
+ different library.%
24012
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23996
24013
}
23997
24014
23998
24015
\LMHash{}%
23999
- Every \synt{type} and type literal in the resulting program
24000
- is now expressed in a globally unique syntactic form.
24001
-
24002
- \rationale{%
24003
- This means that two terms denoting a type will have the same syntactic form
24004
- if and only if they denote the same type.
24005
- }
24016
+ Every \synt{type} and type literal in the resulting set of libraries
24017
+ is now expressed in a globally unique syntactic form,
24018
+ which is the form that we call the
24019
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
24020
+ said types.
24006
24021
24007
24022
\LMHash{}%
24008
24023
When we say that two types $T_1$ and $T_2$ have the
@@ -24012,6 +24027,36 @@ \subsubsection{The Canonical Syntax of Types}
24012
24027
have been transformed as described above,
24013
24028
and the resulting canonical syntaxes are identical.
24014
24029
24030
+ \rationale{%
24031
+ The transformation described here would not be useful in practice
24032
+ (or even possible---we can't edit \code{dart:core}).
24033
+ It only serves to show that we can express types using a syntactic form
24034
+ which is independent of the location.
24035
+ This is in turn needed in order to ensure that operations are well-defined
24036
+ even when they bring syntactic elements from different locations together,
24037
+ such as computations of subtype relationships,
24038
+ and construction of standard upper or lower bounds.
24039
+
24040
+ We could just as well have replaced the concrete syntax by a semantic
24041
+ notion of types,
24042
+ where each entity that denotes a type would be, in some sense,
24043
+ a reference to a specific declaration
24044
+ (this is likely to be the approach used by tool implementations).
24045
+ However, that approach would be somewhat inconvenient in a specification,
24046
+ because we would need to re-build all the structures that the
24047
+ syntax offers.
24048
+ For instance, we would need to support the construction of
24049
+ a semantic type entity for \code{Map<int, String>},
24050
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
24051
+ and we would need to support deconstruction of those entities
24052
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
24053
+ This would give rise to a lot of mechanism that will simply duplicate
24054
+ the structure of the syntax.
24055
+ So we prefer to show that the syntax \emph{can} be location independent,
24056
+ and that's sufficient to make syntax usable as our representation of
24057
+ static semantic types.%
24058
+ }
24059
+
24015
24060
24016
24061
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
24017
24062
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -27435,7 +27480,7 @@ \section*{Appendix: Algorithmic Subtyping}
27435
27480
\item
27436
27481
\textbf{Reflexivity:}
27437
27482
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
27438
-
27483
+
27439
27484
\commentary{%
27440
27485
Note that this check is necessary as the base case for primitive types,
27441
27486
and type variables, but not for composite types.
@@ -27451,7 +27496,7 @@ \section*{Appendix: Algorithmic Subtyping}
27451
27496
\item
27452
27497
\textbf{Left Top:}
27453
27498
if $T_0$ is \DYNAMIC{} or \VOID{}
27454
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
27499
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
27455
27500
\item
27456
27501
\textbf{Left Bottom:}
27457
27502
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -27487,8 +27532,7 @@ \section*{Appendix: Algorithmic Subtyping}
27487
27532
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
27488
27533
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
27489
27534
\item
27490
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
27491
- then the query is true.
27535
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
27492
27536
\item
27493
27537
Otherwise, the query is false.
27494
27538
\end{itemize}
@@ -27531,7 +27575,7 @@ \section*{Appendix: Algorithmic Subtyping}
27531
27575
\begin{itemize}
27532
27576
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
27533
27577
\item or \SubtypeNE{T_0}{S_1}.
27534
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
27578
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
27535
27579
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
27536
27580
\end{itemize}
27537
27581
\item
@@ -27541,7 +27585,7 @@ \section*{Appendix: Algorithmic Subtyping}
27541
27585
\begin{itemize}
27542
27586
\item either \SubtypeNE{T_0}{S_1}.
27543
27587
\item or \SubtypeNE{T_0}{\code{Null}}.
27544
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
27588
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
27545
27589
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
27546
27590
\end{itemize}
27547
27591
\item
@@ -27579,7 +27623,10 @@ \section*{Appendix: Algorithmic Subtyping}
27579
27623
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
27580
27624
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
27581
27625
27582
- where each of the following hold:
27626
+ such that each of the following criteria is satisfied,
27627
+ where the $Z_i$ are fresh type variables with bounds
27628
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
27629
+
27583
27630
\begin{itemize}
27584
27631
\item $p \geq n$.
27585
27632
\item $m \geq q$.
@@ -27588,8 +27635,6 @@ \section*{Appendix: Algorithmic Subtyping}
27588
27635
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
27589
27636
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
27590
27637
have the same canonical syntax, for $i \in 0 .. k$.
27591
- \item where the $Z_i$ are fresh type variables with bounds
27592
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
27593
27638
\end{itemize}
27594
27639
\item
27595
27640
\textbf{Named Function Types:}
@@ -27599,7 +27644,7 @@ \section*{Appendix: Algorithmic Subtyping}
27599
27644
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
27600
27645
$X_k$\,\EXTENDS\,$B_{0k}$>(%
27601
27646
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
27602
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
27647
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
27603
27648
27604
27649
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
27605
27650
and $T_1$ is
@@ -27608,7 +27653,7 @@ \section*{Appendix: Algorithmic Subtyping}
27608
27653
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
27609
27654
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
27610
27655
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
27611
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
27656
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
27612
27657
27613
27658
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
27614
27659
and the following criteria are all satisfied,
0 commit comments