Skip to content

Commit e96a60a

Browse files
committed
WIP
1 parent c5492d8 commit e96a60a

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
@@ -23387,19 +23387,19 @@ \subsection{Same Type}
2338723387
\LMLabel{sameType}
2338823388

2338923389
\LMHash{}%
23390-
This section specifies how to soundly determine whether or not two types
23390+
This section specifies how to determine whether or not two types
2339123391
that are encountered during static analysis are the same type.
2339223392

2339323393
\LMHash{}%
23394-
Concrete syntax denoting types gives rise to several difficulties
23394+
Concrete syntax denoting types gives rise to difficulties
2339523395
when used to determine static semantic properties,
2339623396
like subtyping relationships
2339723397
(\ref{subtypes})
2339823398
or upper and lower bounds
2339923399
(\ref{standardUpperBoundsAndStandardLowerBounds}).
2340023400

2340123401
\commentary{%
23402-
Note that the notion of being the same type at run time is different from
23402+
The notion of being the same type at run time is different from
2340323403
the notion of being the same type during static analysis.
2340423404
For example, two distinct type variables \code{X} and \code{Y}
2340523405
might at run time be bound to the same type, e.g.,
@@ -23408,21 +23408,18 @@ \subsection{Same Type}
2340823408
\code{X} and \code{Y} are different types
2340923409
because there is no guarantee that they are always bound to
2341023410
the same type at run time.%
23411-
}
2341223411

23413-
\commentary{%
23414-
The phrases `same type' and `identical syntax' deserves some extra scrutiny.
23415-
If a library $L$ imports the libraries $L_1$ and $L_2$
23416-
(where $L_1$ and $L_2$ are not the same library),
23412+
The phrase `same type' deserves some extra scrutiny.
23413+
If a library $L$ imports the libraries $L_1$ and $L_2$,
2341723414
and both $L_1$ and $L_2$ declare a class \code{C},
2341823415
then the syntax \code{C} may occur as a type during static analysis of $L$
2341923416
in situations where it refers to two distinct types.
2342023417

2342123418
For instance, $L_1$ could declare a variable \code{v}
2342223419
of type \code{C}-in-$L_1$,
2342323420
and $L_2$ could declare a function
23424-
\code{\VOID\,foo(C\,\,c)\,\,\{\}}
23425-
which uses the type \code{C}-in-$L_2$,
23421+
\code{\VOID\,foo(C\,\,c)\,\,\{\ldots\}}
23422+
which refers to the type \code{C}-in-$L_2$,
2342623423
and $L$ could contain the expression \code{foo(v)}.
2342723424

2342823425
Note that even though it would be a compile-time error to use \code{C} in $L$
@@ -23434,137 +23431,25 @@ \subsection{Same Type}
2343423431
depending on the subtyping relations.%
2343523432
}
2343623433

23437-
\rationale{%
23438-
This shows that concrete syntax behaves in such a manner that it is
23439-
unsafe to consider two types to be the same type,
23440-
based on the fact that they are denoted by the same syntax,
23441-
even during the static analysis of a single expression.
23442-
23443-
Similarly, it is incorrect to consider two terms derived from \synt{type}
23444-
as different types based on the fact that they are syntactically different.
23445-
For example, they could be the same type imported with different import
23446-
prefixes.
23447-
23448-
We could say that two identifiers
23449-
(possibly qualified, e.g., \code{myPrefix.C} and \code{C})
23450-
denote the same type
23451-
if they have been resolved to the same declaration.
23452-
23453-
However, we introduce \emph{the explicitly resolved syntax for a type},
23454-
which is basically an explicit representation of this idea,
23455-
in order to make the underlying issues more explicit.
23456-
The explicitly resolved syntax has the property that
23457-
each type has a unique syntactic form
23458-
(except for alpha equivalence, which is defined below).
23459-
We may then consider this unique syntactic form as a static semantic value,
23460-
rather than just a syntactic form which is dependent on
23461-
its location in the program.%
23462-
}
23463-
23464-
\LMHash{}%
23465-
The
23466-
\IndexCustom{explicitly resolved syntax}{type!explicitly resolved syntax of}
23467-
of the types in a given library $L_1$
23468-
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23469-
one or more import links
23470-
is determined as follows.
23471-
First, choose a set of distinct, globally fresh identifiers
23472-
\List{\metavar{prefix}}{1}{n}.
23473-
Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23474-
23475-
\begin{enumerate}
23476-
\item
23477-
For each type variable declared in $L_i$, consistently rename
23478-
it to a globally fresh name.
23479-
\item
23480-
If $D_T$ is a declaration of a class, mixin, or type alias in $L_i$
23481-
whose name $n$ is private,
23482-
and an occurrence of $n$ that resolves to $D$
23483-
exists in a type alias declaration $D_A$ whose name is non-private,
23484-
then perform a consistent renaming of
23485-
all occurrences of $n$ in $L_i$ that resolve to $D_T$
23486-
to a fresh, non-private identifier.
23487-
\commentary{%
23488-
We make $D_T$ public, because it is being leaked anyway.%
23489-
}
23490-
\item
23491-
Add a set of import directives to $L_i$ that imports
23492-
each of the libraries \List{L}{1}{n} with
23493-
the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23494-
23495-
\commentary{%
23496-
This means that every library in the set
23497-
$\{\,\List{L}{1}{n}\,\}$
23498-
imports every other library in that set,
23499-
even itself and system libraries like \code{dart:core}.%
23500-
}
23501-
\item
23502-
Let \id{} be an occurrence of
23503-
a non-private type identifier derived from \synt{typeName}
23504-
that resolves to a library declaration in the library $L_j$
23505-
in the original program;
23506-
\id{} is then transformed to \code{$\metavar{prefix}_j$.\id}.
23507-
Let \code{$p$.\id} be derived from \synt{typeName} such that $p$ is
23508-
an import prefix in the original program
23509-
and \id{} is a non-private identifier,
23510-
and consider the case where \code{$p$.\id} resolves to
23511-
a library declaration in the library $L_j$ in the original program,
23512-
for some $j$;
23513-
\code{$p$.\id} is then transformed to \code{$\metavar{prefix}_j$.\id}.
23514-
\item
23515-
Replace every type in $L_i$ that denotes a type alias
23516-
along with its actual type arguments, if any,
23517-
by its transitive alias expansion
23518-
(\ref{typedef}).
23519-
\commentary{%
23520-
Note that the bodies of type alias declarations
23521-
already use the new prefixes,
23522-
so the results of the alias expansion will also use
23523-
the new prefixes consistently.%
23524-
}
23525-
\end{enumerate}
23526-
23527-
\commentary{%
23528-
In short, this transformation adds a unique prefix to every type name
23529-
which is resolved to a top-level declaration
23530-
(in the same library or in an imported library).
23531-
23532-
This transformation does not change any occurrence of \VOID,
23533-
and does not need to;
23534-
\VOID{} is a reserved word, not a type identifier.
23535-
Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23536-
23537-
Note that the transformation changes terms derived from \synt{type},
23538-
but it does not change expressions, or any other program element
23539-
(except that a \synt{type} can occur in an expression, e.g., \code{<int>[]}).
23540-
In particular, it does not change type literals
23541-
(that is, expressions denoting types).%
23542-
}
23543-
2354423434
\LMHash{}%
23545-
Every \synt{type} in the resulting set of libraries
23546-
is now expressed in a globally unique syntactic form,
23547-
which is the form that we call the
23548-
\IndexCustom{explicitly resolved syntax of}{type!explicitly resolved syntax of}
23549-
said types.
23435+
Hence, when this specification refers to
23436+
a type designated by a term
23437+
that may seem to stand for concrete syntax,
23438+
it is actually using \Index{resolved syntax}.
23439+
Resolved syntax is syntax which is enhanced such that
23440+
every \emph{applied} occurrence of an identifier
23441+
(as opposed to a declaring occurrence)
23442+
carries information about the declaration
23443+
that it has been resolved to denote.
2355023444

2355123445
\LMHash{}%
23552-
When we say that two types $T_1$ and $T_2$ have the
23553-
\IndexCustom{same explicitly resolved syntax}{%
23554-
type!same explicitly resolved syntax},
23555-
it refers to the situation where the current library
23556-
and all libraries which are reachable via one or more imports
23557-
have been transformed as described above,
23558-
and the resulting explicitly resolved syntaxes are textually identical.
23559-
23560-
\LMHash{}%
23561-
We need to introduce one more concept:
23562-
An \Index{alpha conversion} of a type is a consistent renaming
23563-
of the type variables declared in that type.
23446+
An \Index{alpha conversion} of a type is a consistent, non-capturing renaming
23447+
of type variables declared in that type.
2356423448

2356523449
\commentary{%
23566-
In Dart, only function types can be subject to an alpha conversion:
23567-
A function type is the only kind of type that declares type variables.
23450+
In Dart, a function type is
23451+
the only kind of type which can declare type variables,
23452+
so only a generic function type can be subjected to an alpha conversion.
2356823453
For example,
2356923454
\code{List<X>\,\,\FUNCTION<X>({X\,\,arg})}
2357023455
can be turned into
@@ -23573,17 +23458,33 @@ \subsection{Same Type}
2357323458
}
2357423459

2357523460
\LMHash{}%
23576-
Two function types are \Index{alpha equivalent} if{}f
23577-
there exists an alpha conversion that makes them textually identical.
23461+
We can now define what it means to be the same type.
23462+
Two types $S$ and $T$ are the same type when
23463+
at least one of the following criteria holds:
2357823464

23579-
\LMHash{}%
23580-
Finally, we define that two type denotations $T_1$ and $T_2$ are the
23581-
\IndexCustom{same static type}{type!same static}
23582-
if there exist alpha conversions
23583-
that can be applied to the function types
23584-
that occur as subterms of $T_1$ and $T_2$, if any,
23585-
such that the resulting terms $T'_1$ and $T'_2$ have
23586-
the same explicitly resolved syntax.
23465+
\begin{itemize}
23466+
\item $S$ is \VOID{} and $T$ is \VOID.
23467+
\commentary{This is a reserved word and cannot be shadowed.}
23468+
\item $S$ is an identifier or a prefixed identifier which is resolved
23469+
to denote a type-introducing declaration $D_S$,
23470+
and $T$ is an identifier or a prefixed identifier which is resolved
23471+
to denote a type-introducing declaration $D_T$,
23472+
and $D_S$ is the same declaration as $D_T$.
23473+
\item $S$ is of the form \code{$C$<$U_1$, \ldots\ $U_s$>},
23474+
and $T$ is of the form \code{$D$<$V_1$, \ldots\ $V_s$>},
23475+
where $C$ and $D$ have been resolved to denote the same declaration,
23476+
or they are both \code{FutureOr},
23477+
and $U_j$ is the same type as $V_j$ for all $j \in 1 .. s$.
23478+
\item $S$ and $T$ are both positional function types with the same
23479+
number of mandatory parameters and the same number of optional parameters,
23480+
the same return type, and the same type for each of the parameters.
23481+
\item $S$ and $T$ are both named function types with the same
23482+
number of mandatory parameters and the same set of named parameters,
23483+
the same return type, and the same type for each of the parameters,
23484+
and the same subset of the named parameters marked as \REQUIRED.
23485+
\item There exists an alpha conversion of $S$ yielding $S'$, and
23486+
$S'$ and $T$ are the same type.
23487+
\end{itemize}
2358723488

2358823489

2358923490
\section{Reference}

0 commit comments

Comments
 (0)