@@ -23056,12 +23056,13 @@ \subsubsection{The Canonical Syntax of Types}
23056
23056
\rationale{%
23057
23057
This shows that concrete syntax behaves in such a manner that it is
23058
23058
unsafe to consider two types as the same type,
23059
- based on the fact that they are denoted by the same syntax.
23059
+ based on the fact that they are denoted by the same syntax,
23060
+ even during the static analysis of a single expression.
23060
23061
23061
23062
Similarly, it is incorrect to consider two terms derived from \synt{type}
23062
- as different types based on the fact that they are syntactically different,
23063
- as they could in fact be the same type,
23064
- e.g., imported with different import prefixes.%
23063
+ as different types based on the fact that they are syntactically different.
23064
+ They could in fact be the same type,
23065
+ e.g., imported with different import prefixes.
23065
23066
23066
23067
Consequently, we introduce the notion of the canonical syntax for a type,
23067
23068
which has the property that each type has a unique syntactic form.
@@ -23077,49 +23078,63 @@ \subsubsection{The Canonical Syntax of Types}
23077
23078
of the types in a given library $L_1$
23078
23079
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23079
23080
one or more import links,
23080
- first choose a set of distinct fresh identifiers
23081
+ first choose a set of distinct, globally fresh identifiers
23081
23082
\List{\metavar{prefix}}{1}{n}.
23082
- Then transform each library $L_i$, $i \in 1 .. n$,
23083
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23084
- and $L_i$ imports \code{dart:core} explicitly
23085
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23086
- and change all existing imports to use the prefix
23087
- corresponding to the library which is being imported.
23083
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23088
23084
23089
- \LMHash{}%
23090
- Next, transform every identifier expression and every \synt{typeName}
23091
- that refers to an imported declaration or a library declaration
23092
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23093
- and such that every name resolves to the same declaration
23094
- as it did in the original program.
23085
+ \begin{enumerate}
23086
+ \item
23087
+ Add a set of import directives to $L_i$ that imports
23088
+ each of the libraries \List{L}{1}{n} with
23089
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23090
+
23091
+ \commentary{%
23092
+ This means that every library in the set
23093
+ $\{\,\List{L}{1}{n}\,\}$
23094
+ imports every other library in that set,
23095
+ even itself and system libraries like \code{dart:core}.%
23096
+ }
23097
+ \item
23098
+ Let \id{} be a non-private identifier that resolves to
23099
+ a library declaration in the library $L_j$ in the original program;
23100
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23101
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23102
+ an import prefix in the original program,
23103
+ \id{} is a non-private identifier,
23104
+ and \code{$p$.\id} resolves to
23105
+ a library declaration in the library $L_j$ in the original program;
23106
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23107
+ \item
23108
+ %% TODO(eernst): We should rename private names to fresh public names.
23109
+ Replace every type that denotes a type alias
23110
+ by its transitive alias expansion
23111
+ (\ref{typedef}).
23112
+ \commentary{%
23113
+ Note that the bodies of type alias declarations
23114
+ already use the new prefixes,
23115
+ so the results of the alias expansion will also use
23116
+ the new prefixes consistently.%
23117
+ }
23118
+ \end{enumerate}
23095
23119
23096
23120
\commentary{%
23097
23121
Note that this transformation does not change any occurrence of \VOID;
23098
- \VOID{} is a reserved word
23099
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23100
- }
23122
+ \VOID{} is a reserved word, not an identifier.
23123
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23101
23124
23102
- %% TODO(eernst), for review: Rename private names to fresh public names?
23103
- %% Otherwise the type alias could turn into a term containing private names
23104
- %% from different libraries.
23105
- \LMHash{}%
23106
- Finally, replace every type that denotes a type alias
23107
- by its transitive alias expansion
23108
- (\ref{typedef}).
23109
- \commentary{%
23110
- Note that the bodies of type alias declarations already use the new prefixes,
23111
- so the results of the alias expansion will also use
23112
- the new prefixes consistently.%
23125
+ The transformation also does not change identifiers denoting type variables,
23126
+ There is no need to change those identifiers, because
23127
+ no occurrence of such an identifier resolves to a declaration in a
23128
+ different library.%
23129
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23113
23130
}
23114
23131
23115
23132
\LMHash{}%
23116
- Every \synt{type} and type literal in the resulting program
23117
- is now expressed in a globally unique syntactic form.
23118
-
23119
- \rationale{%
23120
- This means that two terms denoting a type will have the same syntactic form
23121
- if and only if they denote the same type.
23122
- }
23133
+ Every \synt{type} and type literal in the resulting set of libraries
23134
+ is now expressed in a globally unique syntactic form,
23135
+ which is the form that we call the
23136
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
23137
+ said types.
23123
23138
23124
23139
\LMHash{}%
23125
23140
When we say that two types $T_1$ and $T_2$ have the
@@ -23129,6 +23144,36 @@ \subsubsection{The Canonical Syntax of Types}
23129
23144
have been transformed as described above,
23130
23145
and the resulting canonical syntaxes are identical.
23131
23146
23147
+ \rationale{%
23148
+ The transformation described here would not be useful in practice
23149
+ (or even possible---we can't edit \code{dart:core}).
23150
+ It only serves to show that we can express types using a syntactic form
23151
+ which is independent of the location.
23152
+ This is in turn needed in order to ensure that operations are well-defined
23153
+ even when they bring syntactic elements from different locations together,
23154
+ such as computations of subtype relationships,
23155
+ and construction of standard upper or lower bounds.
23156
+
23157
+ We could just as well have replaced the concrete syntax by a semantic
23158
+ notion of types,
23159
+ where each entity that denotes a type would be, in some sense,
23160
+ a reference to a specific declaration
23161
+ (this is likely to be the approach used by tool implementations).
23162
+ However, that approach would be somewhat inconvenient in a specification,
23163
+ because we would need to re-build all the structures that the
23164
+ syntax offers.
23165
+ For instance, we would need to support the construction of
23166
+ a semantic type entity for \code{Map<int, String>},
23167
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23168
+ and we would need to support deconstruction of those entities
23169
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23170
+ This would give rise to a lot of mechanism that will simply duplicate
23171
+ the structure of the syntax.
23172
+ So we prefer to show that the syntax \emph{can} be location independent,
23173
+ and that's sufficient to make syntax usable as our representation of
23174
+ static semantic types.%
23175
+ }
23176
+
23132
23177
23133
23178
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23134
23179
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -25851,7 +25896,7 @@ \section*{Appendix: Algorithmic Subtyping}
25851
25896
\item
25852
25897
\textbf{Reflexivity:}
25853
25898
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
25854
-
25899
+
25855
25900
\commentary{%
25856
25901
Note that this check is necessary as the base case for primitive types,
25857
25902
and type variables, but not for composite types.
@@ -25867,7 +25912,7 @@ \section*{Appendix: Algorithmic Subtyping}
25867
25912
\item
25868
25913
\textbf{Left Top:}
25869
25914
if $T_0$ is \DYNAMIC{} or \VOID{}
25870
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
25915
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
25871
25916
\item
25872
25917
\textbf{Left Bottom:}
25873
25918
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -25903,8 +25948,7 @@ \section*{Appendix: Algorithmic Subtyping}
25903
25948
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
25904
25949
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
25905
25950
\item
25906
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
25907
- then the query is true.
25951
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
25908
25952
\item
25909
25953
Otherwise, the query is false.
25910
25954
\end{itemize}
@@ -25947,7 +25991,7 @@ \section*{Appendix: Algorithmic Subtyping}
25947
25991
\begin{itemize}
25948
25992
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
25949
25993
\item or \SubtypeNE{T_0}{S_1}.
25950
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
25994
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
25951
25995
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
25952
25996
\end{itemize}
25953
25997
\item
@@ -25957,7 +26001,7 @@ \section*{Appendix: Algorithmic Subtyping}
25957
26001
\begin{itemize}
25958
26002
\item either \SubtypeNE{T_0}{S_1}.
25959
26003
\item or \SubtypeNE{T_0}{\code{Null}}.
25960
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26004
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
25961
26005
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
25962
26006
\end{itemize}
25963
26007
\item
@@ -25995,7 +26039,10 @@ \section*{Appendix: Algorithmic Subtyping}
25995
26039
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
25996
26040
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
25997
26041
25998
- where each of the following hold:
26042
+ such that each of the following criteria is satisfied,
26043
+ where the $Z_i$ are fresh type variables with bounds
26044
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
26045
+
25999
26046
\begin{itemize}
26000
26047
\item $p \geq n$.
26001
26048
\item $m \geq q$.
@@ -26004,8 +26051,6 @@ \section*{Appendix: Algorithmic Subtyping}
26004
26051
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
26005
26052
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
26006
26053
have the same canonical syntax, for $i \in 0 .. k$.
26007
- \item where the $Z_i$ are fresh type variables with bounds
26008
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
26009
26054
\end{itemize}
26010
26055
\item
26011
26056
\textbf{Named Function Types:}
@@ -26015,7 +26060,7 @@ \section*{Appendix: Algorithmic Subtyping}
26015
26060
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
26016
26061
$X_k$\,\EXTENDS\,$B_{0k}$>(%
26017
26062
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
26018
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26063
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26019
26064
26020
26065
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
26021
26066
and $T_1$ is
@@ -26024,7 +26069,7 @@ \section*{Appendix: Algorithmic Subtyping}
26024
26069
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
26025
26070
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
26026
26071
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
26027
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26072
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26028
26073
26029
26074
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
26030
26075
and the following criteria are all satisfied,
0 commit comments