Skip to content

Commit 99edde4

Browse files
committed
WIP
1 parent da6d419 commit 99edde4

File tree

1 file changed

+47
-146
lines changed

1 file changed

+47
-146
lines changed

specification/dartLangSpec.tex

Lines changed: 47 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -23328,19 +23328,19 @@ \subsection{Same Type}
2332823328
\LMLabel{sameType}
2332923329

2333023330
\LMHash{}%
23331-
This section specifies how to soundly determine whether or not two types
23331+
This section specifies how to determine whether or not two types
2333223332
that are encountered during static analysis are the same type.
2333323333

2333423334
\LMHash{}%
23335-
Concrete syntax denoting types gives rise to several difficulties
23335+
Concrete syntax denoting types gives rise to difficulties
2333623336
when used to determine static semantic properties,
2333723337
like subtyping relationships
2333823338
(\ref{subtypes})
2333923339
or upper and lower bounds
2334023340
(\ref{standardUpperBoundsAndStandardLowerBounds}).
2334123341

2334223342
\commentary{%
23343-
Note that the notion of being the same type at run time is different from
23343+
The notion of being the same type at run time is different from
2334423344
the notion of being the same type during static analysis.
2334523345
For example, two distinct type variables \code{X} and \code{Y}
2334623346
might at run time be bound to the same type, e.g.,
@@ -23349,21 +23349,18 @@ \subsection{Same Type}
2334923349
\code{X} and \code{Y} are different types
2335023350
because there is no guarantee that they are always bound to
2335123351
the same type at run time.%
23352-
}
2335323352

23354-
\commentary{%
23355-
The phrases `same type' and `identical syntax' deserves some extra scrutiny.
23356-
If a library $L$ imports the libraries $L_1$ and $L_2$
23357-
(where $L_1$ and $L_2$ are not the same library),
23353+
The phrase `same type' deserves some extra scrutiny.
23354+
If a library $L$ imports the libraries $L_1$ and $L_2$,
2335823355
and both $L_1$ and $L_2$ declare a class \code{C},
2335923356
then the syntax \code{C} may occur as a type during static analysis of $L$
2336023357
in situations where it refers to two distinct types.
2336123358

2336223359
For instance, $L_1$ could declare a variable \code{v}
2336323360
of type \code{C}-in-$L_1$,
2336423361
and $L_2$ could declare a function
23365-
\code{\VOID\,foo(C\,\,c)\,\,\{\}}
23366-
which uses the type \code{C}-in-$L_2$,
23362+
\code{\VOID\,foo(C\,\,c)\,\,\{\ldots\}}
23363+
which refers to the type \code{C}-in-$L_2$,
2336723364
and $L$ could contain the expression \code{foo(v)}.
2336823365

2336923366
Note that even though it would be a compile-time error to use \code{C} in $L$
@@ -23375,137 +23372,25 @@ \subsection{Same Type}
2337523372
depending on the subtyping relations.%
2337623373
}
2337723374

23378-
\rationale{%
23379-
This shows that concrete syntax behaves in such a manner that it is
23380-
unsafe to consider two types to be the same type,
23381-
based on the fact that they are denoted by the same syntax,
23382-
even during the static analysis of a single expression.
23383-
23384-
Similarly, it is incorrect to consider two terms derived from \synt{type}
23385-
as different types based on the fact that they are syntactically different.
23386-
For example, they could be the same type imported with different import
23387-
prefixes.
23388-
23389-
We could say that two identifiers
23390-
(possibly qualified, e.g., \code{myPrefix.C} and \code{C})
23391-
denote the same type
23392-
if they have been resolved to the same declaration.
23393-
23394-
However, we introduce \emph{the explicitly resolved syntax for a type},
23395-
which is basically an explicit representation of this idea,
23396-
in order to make the underlying issues more explicit.
23397-
The explicitly resolved syntax has the property that
23398-
each type has a unique syntactic form
23399-
(except for alpha equivalence, which is defined below).
23400-
We may then consider this unique syntactic form as a static semantic value,
23401-
rather than just a syntactic form which is dependent on
23402-
its location in the program.%
23403-
}
23404-
23405-
\LMHash{}%
23406-
The
23407-
\IndexCustom{explicitly resolved syntax}{type!explicitly resolved syntax of}
23408-
of the types in a given library $L_1$
23409-
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23410-
one or more import links
23411-
is determined as follows.
23412-
First, choose a set of distinct, globally fresh identifiers
23413-
\List{\metavar{prefix}}{1}{n}.
23414-
Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23415-
23416-
\begin{enumerate}
23417-
\item
23418-
For each type variable declared in $L_i$, consistently rename
23419-
it to a globally fresh name.
23420-
\item
23421-
If $D_T$ is a declaration of a class, mixin, or type alias in $L_i$
23422-
whose name $n$ is private,
23423-
and an occurrence of $n$ that resolves to $D$
23424-
exists in a type alias declaration $D_A$ whose name is non-private,
23425-
then perform a consistent renaming of
23426-
all occurrences of $n$ in $L_i$ that resolve to $D_T$
23427-
to a fresh, non-private identifier.
23428-
\commentary{%
23429-
We make $D_T$ public, because it is being leaked anyway.%
23430-
}
23431-
\item
23432-
Add a set of import directives to $L_i$ that imports
23433-
each of the libraries \List{L}{1}{n} with
23434-
the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23435-
23436-
\commentary{%
23437-
This means that every library in the set
23438-
$\{\,\List{L}{1}{n}\,\}$
23439-
imports every other library in that set,
23440-
even itself and system libraries like \code{dart:core}.%
23441-
}
23442-
\item
23443-
Let \id{} be an occurrence of
23444-
a non-private type identifier derived from \synt{typeName}
23445-
that resolves to a library declaration in the library $L_j$
23446-
in the original program;
23447-
\id{} is then transformed to \code{$\metavar{prefix}_j$.\id}.
23448-
Let \code{$p$.\id} be derived from \synt{typeName} such that $p$ is
23449-
an import prefix in the original program
23450-
and \id{} is a non-private identifier,
23451-
and consider the case where \code{$p$.\id} resolves to
23452-
a library declaration in the library $L_j$ in the original program,
23453-
for some $j$;
23454-
\code{$p$.\id} is then transformed to \code{$\metavar{prefix}_j$.\id}.
23455-
\item
23456-
Replace every type in $L_i$ that denotes a type alias
23457-
along with its actual type arguments, if any,
23458-
by its transitive alias expansion
23459-
(\ref{typedef}).
23460-
\commentary{%
23461-
Note that the bodies of type alias declarations
23462-
already use the new prefixes,
23463-
so the results of the alias expansion will also use
23464-
the new prefixes consistently.%
23465-
}
23466-
\end{enumerate}
23467-
23468-
\commentary{%
23469-
In short, this transformation adds a unique prefix to every type name
23470-
which is resolved to a top-level declaration
23471-
(in the same library or in an imported library).
23472-
23473-
This transformation does not change any occurrence of \VOID,
23474-
and does not need to;
23475-
\VOID{} is a reserved word, not a type identifier.
23476-
Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23477-
23478-
Note that the transformation changes terms derived from \synt{type},
23479-
but it does not change expressions, or any other program element
23480-
(except that a \synt{type} can occur in an expression, e.g., \code{<int>[]}).
23481-
In particular, it does not change type literals
23482-
(that is, expressions denoting types).%
23483-
}
23484-
2348523375
\LMHash{}%
23486-
Every \synt{type} in the resulting set of libraries
23487-
is now expressed in a globally unique syntactic form,
23488-
which is the form that we call the
23489-
\IndexCustom{explicitly resolved syntax of}{type!explicitly resolved syntax of}
23490-
said types.
23376+
Hence, when this specification refers to
23377+
a type designated by a term
23378+
that may seem to stand for concrete syntax,
23379+
it is actually using \Index{resolved syntax}.
23380+
Resolved syntax is syntax which is enhanced such that
23381+
every \emph{applied} occurrence of an identifier
23382+
(as opposed to a declaring occurrence)
23383+
carries information about the declaration
23384+
that it has been resolved to denote.
2349123385

2349223386
\LMHash{}%
23493-
When we say that two types $T_1$ and $T_2$ have the
23494-
\IndexCustom{same explicitly resolved syntax}{%
23495-
type!same explicitly resolved syntax},
23496-
it refers to the situation where the current library
23497-
and all libraries which are reachable via one or more imports
23498-
have been transformed as described above,
23499-
and the resulting explicitly resolved syntaxes are textually identical.
23500-
23501-
\LMHash{}%
23502-
We need to introduce one more concept:
23503-
An \Index{alpha conversion} of a type is a consistent renaming
23504-
of the type variables declared in that type.
23387+
An \Index{alpha conversion} of a type is a consistent, non-capturing renaming
23388+
of type variables declared in that type.
2350523389

2350623390
\commentary{%
23507-
In Dart, only function types can be subject to an alpha conversion:
23508-
A function type is the only kind of type that declares type variables.
23391+
In Dart, a function type is
23392+
the only kind of type which can declare type variables,
23393+
so only a generic function type can be subjected to an alpha conversion.
2350923394
For example,
2351023395
\code{List<X>\,\,\FUNCTION<X>({X\,\,arg})}
2351123396
can be turned into
@@ -23514,17 +23399,33 @@ \subsection{Same Type}
2351423399
}
2351523400

2351623401
\LMHash{}%
23517-
Two function types are \Index{alpha equivalent} if{}f
23518-
there exists an alpha conversion that makes them textually identical.
23402+
We can now define what it means to be the same type.
23403+
Two types $S$ and $T$ are the same type when
23404+
at least one of the following criteria holds:
2351923405

23520-
\LMHash{}%
23521-
Finally, we define that two type denotations $T_1$ and $T_2$ are the
23522-
\IndexCustom{same static type}{type!same static}
23523-
if there exist alpha conversions
23524-
that can be applied to the function types
23525-
that occur as subterms of $T_1$ and $T_2$, if any,
23526-
such that the resulting terms $T'_1$ and $T'_2$ have
23527-
the same explicitly resolved syntax.
23406+
\begin{itemize}
23407+
\item $S$ is \VOID{} and $T$ is \VOID.
23408+
\commentary{This is a reserved word and cannot be shadowed.}
23409+
\item $S$ is an identifier or a prefixed identifier which is resolved
23410+
to denote a type-introducing declaration $D_S$,
23411+
and $T$ is an identifier or a prefixed identifier which is resolved
23412+
to denote a type-introducing declaration $D_T$,
23413+
and $D_S$ is the same declaration as $D_T$.
23414+
\item $S$ is of the form \code{$C$<$U_1$, \ldots\ $U_s$>},
23415+
and $T$ is of the form \code{$D$<$V_1$, \ldots\ $V_s$>},
23416+
where $C$ and $D$ have been resolved to denote the same declaration,
23417+
or they are both \code{FutureOr},
23418+
and $U_j$ is the same type as $V_j$ for all $j \in 1 .. s$.
23419+
\item $S$ and $T$ are both positional function types with the same
23420+
number of mandatory parameters and the same number of optional parameters,
23421+
the same return type, and the same type for each of the parameters.
23422+
\item $S$ and $T$ are both named function types with the same
23423+
number of mandatory parameters and the same set of named parameters,
23424+
the same return type, and the same type for each of the parameters,
23425+
and the same subset of the named parameters marked as \REQUIRED.
23426+
\item There exists an alpha conversion of $S$ yielding $S'$, and
23427+
$S'$ and $T$ are the same type.
23428+
\end{itemize}
2352823429

2352923430

2353023431
\section{Reference}

0 commit comments

Comments
 (0)