@@ -23056,12 +23056,13 @@ \subsubsection{The Canonical Syntax of Types}
2305623056\rationale{%
2305723057This shows that concrete syntax behaves in such a manner that it is
2305823058unsafe 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.
2306023061
2306123062Similarly, 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.
2306523066
2306623067Consequently, we introduce the notion of the canonical syntax for a type,
2306723068which has the property that each type has a unique syntactic form.
@@ -23077,49 +23078,63 @@ \subsubsection{The Canonical Syntax of Types}
2307723078of the types in a given library $L_1$
2307823079and all libraries \List{L}{2}{n} reachable from $L_1$ via
2307923080one or more import links,
23080- first choose a set of distinct fresh identifiers
23081+ first choose a set of distinct, globally fresh identifiers
2308123082\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:
2308823084
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}
2309523119
2309623120\commentary{%
2309723121Note 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.
2310123124
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.
2311323130}
2311423131
2311523132\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.
2312323138
2312423139\LMHash{}%
2312523140When we say that two types $T_1$ and $T_2$ have the
@@ -23129,6 +23144,36 @@ \subsubsection{The Canonical Syntax of Types}
2312923144have been transformed as described above,
2313023145and the resulting canonical syntaxes are identical.
2313123146
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+
2313223177
2313323178\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
2313423179\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -25851,7 +25896,7 @@ \section*{Appendix: Algorithmic Subtyping}
2585125896\item
2585225897 \textbf{Reflexivity:}
2585325898 if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
25854-
25899+
2585525900 \commentary{%
2585625901 Note that this check is necessary as the base case for primitive types,
2585725902 and type variables, but not for composite types.
@@ -25867,7 +25912,7 @@ \section*{Appendix: Algorithmic Subtyping}
2586725912\item
2586825913 \textbf{Left Top:}
2586925914 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}.
2587125916\item
2587225917 \textbf{Left Bottom:}
2587325918 if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -25903,8 +25948,7 @@ \section*{Appendix: Algorithmic Subtyping}
2590325948 if $T_1$ is \code{FutureOr<$S$>} for some $S$,
2590425949 then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
2590525950 \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.
2590825952 \item
2590925953 Otherwise, the query is false.
2591025954 \end{itemize}
@@ -25947,7 +25991,7 @@ \section*{Appendix: Algorithmic Subtyping}
2594725991 \begin{itemize}
2594825992 \item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
2594925993 \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}.
2595125995 \item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
2595225996 \end{itemize}
2595325997\item
@@ -25957,7 +26001,7 @@ \section*{Appendix: Algorithmic Subtyping}
2595726001 \begin{itemize}
2595826002 \item either \SubtypeNE{T_0}{S_1}.
2595926003 \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}.
2596126005 \item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
2596226006 \end{itemize}
2596326007\item
@@ -25995,7 +26039,10 @@ \section*{Appendix: Algorithmic Subtyping}
2599526039 $S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
2599626040 [$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
2599726041
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+
2599926046 \begin{itemize}
2600026047 \item $p \geq n$.
2600126048 \item $m \geq q$.
@@ -26004,8 +26051,6 @@ \section*{Appendix: Algorithmic Subtyping}
2600426051 \item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
2600526052 \item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
2600626053 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]$.
2600926054 \end{itemize}
2601026055\item
2601126056 \textbf{Named Function Types:}
@@ -26015,7 +26060,7 @@ \section*{Appendix: Algorithmic Subtyping}
2601526060 $U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
2601626061 $X_k$\,\EXTENDS\,$B_{0k}$>(%
2601726062 $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$\})}
2601926064
2602026065 where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
2602126066 and $T_1$ is
@@ -26024,7 +26069,7 @@ \section*{Appendix: Algorithmic Subtyping}
2602426069 $U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
2602526070 $Y_k$\,\EXTENDS\,$B_{1k}$>(%
2602626071 $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$\})}
2602826073
2602926074 where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
2603026075 and the following criteria are all satisfied,
0 commit comments