@@ -23185,12 +23185,13 @@ \subsubsection{The Canonical Syntax of Types}
23185
23185
\rationale{%
23186
23186
This shows that concrete syntax behaves in such a manner that it is
23187
23187
unsafe to consider two types as the same type,
23188
- based on the fact that they are denoted by the same syntax.
23188
+ based on the fact that they are denoted by the same syntax,
23189
+ even during the static analysis of a single expression.
23189
23190
23190
23191
Similarly, it is incorrect to consider two terms derived from \synt{type}
23191
- as different types based on the fact that they are syntactically different,
23192
- as they could in fact be the same type,
23193
- e.g., imported with different import prefixes.%
23192
+ as different types based on the fact that they are syntactically different.
23193
+ They could in fact be the same type,
23194
+ e.g., imported with different import prefixes.
23194
23195
23195
23196
Consequently, we introduce the notion of the canonical syntax for a type,
23196
23197
which has the property that each type has a unique syntactic form.
@@ -23206,49 +23207,63 @@ \subsubsection{The Canonical Syntax of Types}
23206
23207
of the types in a given library $L_1$
23207
23208
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23208
23209
one or more import links,
23209
- first choose a set of distinct fresh identifiers
23210
+ first choose a set of distinct, globally fresh identifiers
23210
23211
\List{\metavar{prefix}}{1}{n}.
23211
- Then transform each library $L_i$, $i \in 1 .. n$,
23212
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23213
- and $L_i$ imports \code{dart:core} explicitly
23214
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23215
- and change all existing imports to use the prefix
23216
- corresponding to the library which is being imported.
23212
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23217
23213
23218
- \LMHash{}%
23219
- Next, transform every identifier expression and every \synt{typeName}
23220
- that refers to an imported declaration or a library declaration
23221
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23222
- and such that every name resolves to the same declaration
23223
- as it did in the original program.
23214
+ \begin{enumerate}
23215
+ \item
23216
+ Add a set of import directives to $L_i$ that imports
23217
+ each of the libraries \List{L}{1}{n} with
23218
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23219
+
23220
+ \commentary{%
23221
+ This means that every library in the set
23222
+ $\{\,\List{L}{1}{n}\,\}$
23223
+ imports every other library in that set,
23224
+ even itself and system libraries like \code{dart:core}.%
23225
+ }
23226
+ \item
23227
+ Let \id{} be a non-private identifier that resolves to
23228
+ a library declaration in the library $L_j$ in the original program;
23229
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23230
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23231
+ an import prefix in the original program,
23232
+ \id{} is a non-private identifier,
23233
+ and \code{$p$.\id} resolves to
23234
+ a library declaration in the library $L_j$ in the original program;
23235
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23236
+ \item
23237
+ %% TODO(eernst): We should rename private names to fresh public names.
23238
+ Replace every type that denotes a type alias
23239
+ by its transitive alias expansion
23240
+ (\ref{typedef}).
23241
+ \commentary{%
23242
+ Note that the bodies of type alias declarations
23243
+ already use the new prefixes,
23244
+ so the results of the alias expansion will also use
23245
+ the new prefixes consistently.%
23246
+ }
23247
+ \end{enumerate}
23224
23248
23225
23249
\commentary{%
23226
23250
Note that this transformation does not change any occurrence of \VOID;
23227
- \VOID{} is a reserved word
23228
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23229
- }
23251
+ \VOID{} is a reserved word, not an identifier.
23252
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23230
23253
23231
- %% TODO(eernst), for review: Rename private names to fresh public names?
23232
- %% Otherwise the type alias could turn into a term containing private names
23233
- %% from different libraries.
23234
- \LMHash{}%
23235
- Finally, replace every type that denotes a type alias
23236
- by its transitive alias expansion
23237
- (\ref{typedef}).
23238
- \commentary{%
23239
- Note that the bodies of type alias declarations already use the new prefixes,
23240
- so the results of the alias expansion will also use
23241
- the new prefixes consistently.%
23254
+ The transformation also does not change identifiers denoting type variables,
23255
+ There is no need to change those identifiers, because
23256
+ no occurrence of such an identifier resolves to a declaration in a
23257
+ different library.%
23258
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23242
23259
}
23243
23260
23244
23261
\LMHash{}%
23245
- Every \synt{type} and type literal in the resulting program
23246
- is now expressed in a globally unique syntactic form.
23247
-
23248
- \rationale{%
23249
- This means that two terms denoting a type will have the same syntactic form
23250
- if and only if they denote the same type.
23251
- }
23262
+ Every \synt{type} and type literal in the resulting set of libraries
23263
+ is now expressed in a globally unique syntactic form,
23264
+ which is the form that we call the
23265
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
23266
+ said types.
23252
23267
23253
23268
\LMHash{}%
23254
23269
When we say that two types $T_1$ and $T_2$ have the
@@ -23258,6 +23273,36 @@ \subsubsection{The Canonical Syntax of Types}
23258
23273
have been transformed as described above,
23259
23274
and the resulting canonical syntaxes are identical.
23260
23275
23276
+ \rationale{%
23277
+ The transformation described here would not be useful in practice
23278
+ (or even possible---we can't edit \code{dart:core}).
23279
+ It only serves to show that we can express types using a syntactic form
23280
+ which is independent of the location.
23281
+ This is in turn needed in order to ensure that operations are well-defined
23282
+ even when they bring syntactic elements from different locations together,
23283
+ such as computations of subtype relationships,
23284
+ and construction of standard upper or lower bounds.
23285
+
23286
+ We could just as well have replaced the concrete syntax by a semantic
23287
+ notion of types,
23288
+ where each entity that denotes a type would be, in some sense,
23289
+ a reference to a specific declaration
23290
+ (this is likely to be the approach used by tool implementations).
23291
+ However, that approach would be somewhat inconvenient in a specification,
23292
+ because we would need to re-build all the structures that the
23293
+ syntax offers.
23294
+ For instance, we would need to support the construction of
23295
+ a semantic type entity for \code{Map<int, String>},
23296
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23297
+ and we would need to support deconstruction of those entities
23298
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23299
+ This would give rise to a lot of mechanism that will simply duplicate
23300
+ the structure of the syntax.
23301
+ So we prefer to show that the syntax \emph{can} be location independent,
23302
+ and that's sufficient to make syntax usable as our representation of
23303
+ static semantic types.%
23304
+ }
23305
+
23261
23306
23262
23307
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23263
23308
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -25980,7 +26025,7 @@ \section*{Appendix: Algorithmic Subtyping}
25980
26025
\item
25981
26026
\textbf{Reflexivity:}
25982
26027
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
25983
-
26028
+
25984
26029
\commentary{%
25985
26030
Note that this check is necessary as the base case for primitive types,
25986
26031
and type variables, but not for composite types.
@@ -25996,7 +26041,7 @@ \section*{Appendix: Algorithmic Subtyping}
25996
26041
\item
25997
26042
\textbf{Left Top:}
25998
26043
if $T_0$ is \DYNAMIC{} or \VOID{}
25999
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
26044
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
26000
26045
\item
26001
26046
\textbf{Left Bottom:}
26002
26047
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -26032,8 +26077,7 @@ \section*{Appendix: Algorithmic Subtyping}
26032
26077
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
26033
26078
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
26034
26079
\item
26035
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
26036
- then the query is true.
26080
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
26037
26081
\item
26038
26082
Otherwise, the query is false.
26039
26083
\end{itemize}
@@ -26076,7 +26120,7 @@ \section*{Appendix: Algorithmic Subtyping}
26076
26120
\begin{itemize}
26077
26121
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
26078
26122
\item or \SubtypeNE{T_0}{S_1}.
26079
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26123
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26080
26124
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26081
26125
\end{itemize}
26082
26126
\item
@@ -26086,7 +26130,7 @@ \section*{Appendix: Algorithmic Subtyping}
26086
26130
\begin{itemize}
26087
26131
\item either \SubtypeNE{T_0}{S_1}.
26088
26132
\item or \SubtypeNE{T_0}{\code{Null}}.
26089
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26133
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26090
26134
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26091
26135
\end{itemize}
26092
26136
\item
@@ -26124,7 +26168,10 @@ \section*{Appendix: Algorithmic Subtyping}
26124
26168
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
26125
26169
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
26126
26170
26127
- where each of the following hold:
26171
+ such that each of the following criteria is satisfied,
26172
+ where the $Z_i$ are fresh type variables with bounds
26173
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
26174
+
26128
26175
\begin{itemize}
26129
26176
\item $p \geq n$.
26130
26177
\item $m \geq q$.
@@ -26133,8 +26180,6 @@ \section*{Appendix: Algorithmic Subtyping}
26133
26180
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
26134
26181
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
26135
26182
have the same canonical syntax, for $i \in 0 .. k$.
26136
- \item where the $Z_i$ are fresh type variables with bounds
26137
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
26138
26183
\end{itemize}
26139
26184
\item
26140
26185
\textbf{Named Function Types:}
@@ -26144,7 +26189,7 @@ \section*{Appendix: Algorithmic Subtyping}
26144
26189
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
26145
26190
$X_k$\,\EXTENDS\,$B_{0k}$>(%
26146
26191
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
26147
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26192
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26148
26193
26149
26194
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
26150
26195
and $T_1$ is
@@ -26153,7 +26198,7 @@ \section*{Appendix: Algorithmic Subtyping}
26153
26198
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
26154
26199
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
26155
26200
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
26156
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26201
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26157
26202
26158
26203
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
26159
26204
and the following criteria are all satisfied,
0 commit comments