Files
swift-mirror/docs/Generics/chapters/declarations.tex
Slava Pestov 7ad160a971 docs: Update generics.tex
Overhaul the "Conformance Paths" chapter to use the new notation
for derived requirements.
2024-11-16 22:05:52 -05:00

1236 lines
87 KiB
TeX

\documentclass[../generics]{subfiles}
\begin{document}
\chapter{Declarations}\label{decls}
\lettrine{D}{eclarations} are the \IndexDefinition{declaration}building blocks of Swift programs. In \ChapRef{compilation model}, we started by viewing the user's program as a series of \index{module declaration}module declarations, where a module declaration holds \index{file unit}file units. A file unit further holds a list of \IndexDefinition{top-level declaration}top-level declarations, which correspond to the main divisions in a source file. The different kinds of declarations are categorized into a taxonomy, and we will survey this taxonomy, as we did with types in \ChapRef{types}. Our principal goal will be describing the syntactic representations for declaring generic parameters and stating requirements, which are common to all generic declarations; once we have that, we can proceed to \PartRef{part semantics}.
We begin with two major divisions in the declaration taxonomy:
\begin{enumerate}
\item A \IndexDefinition{value declaration}\emph{value declaration} is a one that can be referenced by name from an \index{expression}expression; this includes variables, functions, and such. Every value declaration has an \IndexDefinition{interface type!value declaration}\emph{interface type}, which is the type assigned to an expression that names this declaration.
\item A \IndexDefinition{type declaration}\emph{type declaration} is one that can be referenced by name from within a \index{type representation}type representation. This includes structs, type aliases, and so on. A type declaration declares a type, called the \IndexDefinition{declared interface type}\emph{declared interface type} of the type declaration.
\end{enumerate}
Not all declarations are value declarations. An \index{extension declaration}extension declaration adds members to an existing nominal type declaration, as we'll see in \ChapRef{extensions}, but an extension does not itself have a name. A \IndexDefinition{top-level code declaration}\emph{top-level code declaration} holds the statements and expressions written at the top level of a source file, and again, it does not have a name, semantically.
\paragraph{Declaration contexts.} Every declaration is contained in a \IndexDefinition{declaration context}\emph{declaration context}, and a declaration context is anything that \emph{contains} declarations. Consider this program:
\begin{Verbatim}
func squares(_ nums: [Int]) -> [Int] {
return nums.map { x in x * x }
}
\end{Verbatim}
The \index{parameter declaration}parameter declaration ``\texttt{x}'' is a child of the closure expression ``\verb|{ x in x * x }|'', and not a direct child of the enclosing function declaration. So a \index{closure expression}closure expression is a declaration context, but not a declaration. On the other hand, a parameter declaration is a declaration, but not a declaration context. Finally, the \texttt{squares()} function itself is both a declaration, and a declaration context.
\paragraph{Type declarations.} Types can be written inside expressions, so every type declaration is also a value declaration. We can understand the relationship between the interface type and declared interface type of a type declaration by looking at this example:
\begin{Verbatim}
struct Horse {}
let myHorse: Horse = Horse()
\end{Verbatim}
The struct declaration \index{horse}\texttt{Horse} is referenced twice, first in the type representation on the left-hand side of ``\texttt{=}'' and then again in the \index{expression}\index{initial value expression}initial value expression on the right. On the left-hand side, it's referenced as a type declaration; we want the \emph{declared interface type}, which is the nominal type \texttt{Horse}, because this type's values are stored inside the \texttt{myHorse} variable. The second reference to \texttt{Horse}, within the \index{call expression}call expression, refers to the \emph{type itself} as a value declaration, so we want the \emph{interface type}, which is the \index{metatype type}metatype \texttt{Horse.Type}. (Recall the diagram from \SecRef{more types}.) When a metatype is the callee in a call expression, we interpret it as looking up the member named \texttt{init}:
\begin{Verbatim}
struct Horse {}
let myHorseType: Horse.Type = Horse.self
let myHorse: Horse = myHorseType.init()
\end{Verbatim}
The interface type of a type declaration always wraps its declared interface type in a metatype type. (It sounds like a mouthful, but the idea is simple.)
\paragraph{Nominal type declarations.}
\IndexDefinition{nominal type declaration}Introduced with the \texttt{struct}, \IndexDefinition{enum declaration}\texttt{enum} and \IndexDefinition{class declaration}\texttt{class} keywords; \IndexSwift{5.5}Swift~5.5 also added \texttt{actor}, which to us is just a class~\cite{se0306}. Nominal type declarations are declaration contexts, and the declarations they contain are called their \IndexDefinition{member declaration}\emph{member declarations}. If a member declaration is a function, we call it a \IndexDefinition{method declaration}\emph{method}, a member variable is a \IndexDefinition{property declaration}\emph{property}, and a \IndexDefinition{member type declaration}\emph{member type declaration} is exactly that.
Structs and classes can contain a special kind of property declaration called a \IndexDefinition{stored property declaration}\emph{stored property declaration}. Struct values directly store their stored properties, while a class value is a reference to a heap allocated \index{boxing}box. Enum values store exactly one element among several; enum declarations instead contain \IndexDefinition{enum element declaration}\emph{enum element declarations}, introduced with the \texttt{case} keyword.
The members of a nominal type declaration are visible to name lookup (\SecRef{name lookup}), both in the nominal type declaration's scope (unqualified lookup) and outside (qualified lookup). \ListingRef{unqualified lookup listing} shows three features we will cover in detail later:
\begin{itemize}
\item Nominal type declarations can conform to protocols (\ChapRef{conformances}).
\item Extensions add members to existing nominal type declarations (\ChapRef{extensions}).
\item A class can inherit from a \index{superclass type}superclass type, and members of the superclass are also visible from the subclass (\SecRef{classinheritance}).
\end{itemize}
\begin{listing}\captionabove{Some behaviors of name lookup}\label{unqualified lookup listing}
\begin{Verbatim}
class Form { static func callee1() {} }
protocol Shape { static func callee2() }
extension Shape { static func callee3() {} }
struct Square: Shape {
class Circle: Form {
static func caller() {
... // unqualified lookup from here
}
}
}
\end{Verbatim}
\end{listing}
The body of \texttt{caller()} can reference \texttt{callee1()}, \texttt{callee2()} or \texttt{callee3()} with a single identifier. To resolve the identifier, unqualified lookup must search through these declaration contexts, starting in the top-left corner:
\begin{center}
\begin{tikzpicture}[x=4.5cm,y=1.5cm]
\node (caller) [class,anchor=mid] at (0,2) {\texttt{\vphantom{p}func caller()}};
\node (Circle) [class,anchor=mid] at (1,2) {\texttt{\vphantom{p}class Circle}};
\node (Square) [class,anchor=mid] at (2,2) {\texttt{struct Square}};
\node (Form) [class,anchor=mid] at (1,1) {\texttt{\vphantom{p}class Form}};
\node (Shape) [class,anchor=mid] at (2,1) {\texttt{protocol Shape}};
\node (extShape) [class,anchor=mid] at (2,0) {\texttt{extension Shape}};
\path [arrow] (caller) edge [above] node {\footnotesize{parent}} (Circle);
\path [arrow] (Circle) edge [above] node {\footnotesize{parent}} (Square);
\path [arrow] (Square) edge [right] node {\footnotesize{conforms to}} (Shape);
\path [arrow] (Circle) edge [right] node {\footnotesize{superclass}} (Form);
\draw [arrow] (Shape) edge [right] node {\footnotesize{extension}} (extShape);
\end{tikzpicture}
\end{center}
We will say more about name lookup in \ChapRef{typeresolution} and \SecRef{direct lookup}.
A nominal type declaration declares a new type with its own name and identity (hence ``nominal''). The declared interface type of a nominal type declaration is called a \index{nominal type}nominal type, which we talked about in \SecRef{fundamental types}:
\begin{Verbatim}
struct Universe { // declared interface type: Universe
struct Galaxy {} // declared interface type: Universe.Galaxy
func solarSystem() {
struct Planet() // declared interface type: Planet
}
}
\end{Verbatim}
The declared interface type of the \texttt{Galaxy} struct is \texttt{Universe.Galaxy}, while the declared interface type of \texttt{Planet} is just \texttt{Planet}, with no parent type. This reflects the semantic difference; \texttt{Galaxy} is visible to qualified lookup as a member of \texttt{Universe}, while \texttt{Planet} is only visible to unqualified lookup within the scope of \texttt{solarSystem()}; we call it a \IndexDefinition{local type declaration}\emph{local type declaration}. \SecRef{nested nominal types} gives more detail about nominal type nesting.
\paragraph{Type alias declarations.} These are introduced by the \IndexDefinition{type alias declaration}\texttt{typealias} keyword. The \IndexDefinition{underlying type}underlying type is written on the right-hand side of ``\texttt{=}'':
\begin{Verbatim}
typealias Hands = Int // one hand is four inches
func measure(horse: Horse) -> Hands {...}
let metatype = Hands.self
\end{Verbatim}
The declared interface type of a type alias declaration is a \index{type alias type}type alias type. The canonical type of this type alias type is just the underlying type. Therefore, if we print the return type of \texttt{measure()} in a diagnostic message, we will print it as ``\texttt{Hands}'', but otherwise it behaves as if it were an \texttt{Int}.
As with all type declarations, the interface type of a type alias declaration is the metatype of its declared interface type. In the above, the expression ``\texttt{Hands.self}'' has the metatype type \texttt{Hands.Type}. This is a sugared type, canonically equal to \texttt{Int.Type}.
While type aliases are declaration contexts, the only declarations a type alias can contain are generic parameter declarations, in the event the type alias is generic.
\paragraph{Other type declarations.}
We've now seen the first two kinds of type declarations. In the next two sections, we expand on this by looking at the declarations of generic parameters, protocols and associated types. At this point, our foray into Swift generics can begin in earnest. Here are all the type declaration kinds and their declared interface types, with a representative specimen of each:
\begin{center}
\begin{tabular}{ll}
\toprule
\textbf{Type declaration}&\textbf{Declared interface type}\\
\midrule
Nominal type declaration:&Nominal type:\\
\verb|struct Horse {...}|&\verb|Horse|\\
\midrule
Type alias declaration:&Type alias type:\\
\verb|typealias Hands = Int|&\verb|Hands|\\
\midrule
Generic parameter declaration:&Generic parameter type:\\
\verb|<T: Sequence>|&\verb|T| (or \rT)\\
\midrule
Protocol declaration:&Protocol type:\\
\verb|protocol Sequence {...}|&\verb|Sequence|\\
\midrule
Associated type declaration:&Dependent member type:\\
\verb|associatedtype Element|&\verb|Self.Element|\\
\bottomrule
\end{tabular}
\end{center}
\section{Generic Parameters}\label{generic params}
Various kinds of declarations can have a \IndexDefinition{generic parameter list}generic parameter list. We call them \IndexDefinition{generic declaration}\emph{generic declarations}. We start with those where the generic parameter list is written in source: \index{struct declaration}structs, \index{enum declaration}enums, \index{class declaration}classes, \IndexDefinition{generic type alias}type aliases, \index{function declaration}functions and \index{constructor declaration}constructors, and \index{subscript declaration}subscripts. In all cases, a \IndexDefinition{parsed generic parameter list}generic parameter list is denoted in source with the \texttt{<...>} syntax following the name of the declaration:
\begin{Verbatim}
struct Outer<T> {...}
\end{Verbatim}
Each comma-separated element in this list is a \IndexDefinition{generic parameter declaration}\emph{generic parameter declaration}; this is a type declaration that declares a generic parameter type. Generic parameter declarations are visible to unqualified lookup in the entire source range of the parent declaration, the one that has the generic parameter list. When generic declarations nest, each inner generic declaration is effectively parameterized by the generic parameters of its outer declarations.
Any declaration kind that can have a generic parameter list is also a \index{declaration context}declaration context in our taxonomy, because it contains other declarations; namely, its generic parameter declarations. We say that a declaration context is a \IndexDefinition{generic context}\emph{generic context} if at least one parent context has a generic parameter list.
The name of a generic parameter declaration plays no role after \index{unqualified lookup}unqualified lookup. Instead, to each generic parameter declaration, we assign a pair of integers (or more accurately, natural numbers; they're non-negative), the \IndexDefinition{depth}\emph{depth} and the \IndexDefinition{index}\emph{index}:
\begin{itemize}
\item The depth selects a generic parameter list; the generic parameters declared by the outermost generic parameter list are at depth zero, and we increment the depth by one for each nested generic parameter list.
\item The index selects a generic parameter within a generic parameter list; we number sibling generic parameter declarations consecutively starting from zero.
\end{itemize}
Let's write some nested generic declarations inside the \texttt{Outer} struct above. In the following, \texttt{two()} is generic over \tT~and~\tU, while \texttt{four()} is generic over~\tT, \texttt{V}, \texttt{W}~and~\texttt{X}:
\begin{Verbatim}
struct Outer<T> {
func two<U>(u: U) -> T {...}
struct Both<V, W> {
func four<X>() -> X {...}
}
}
\end{Verbatim}
When type resolution resolves the type representation ``\tT'' in the return type of \texttt{two()}, it outputs a generic parameter type that prints as ``\tT'', if it appears in a diagnostic for example. This is a \index{sugared type}sugared type. Every generic parameter type also has a canonical form which only records the depth and index; we denote a canonical generic parameter type by ``\ttgp{d}{i}'', where \texttt{d} is the depth and \texttt{i} is the index. Two generic parameter types are canonically equal if they have the same depth and index. This is sound, because the depth and index unambiguously identify a generic parameter within its lexical scope.
Let's enumerate all generic parameters visible within \texttt{two()},
\begin{center}
\begin{tabular}{rll}
\toprule
\textbf{Name:}&\tT&\tU\\
\midrule
\textbf{Depth:}&0&1\\
\textbf{Index:}&0&0\\
\textbf{Type:}&\ttgp{0}{0}&\ttgp{1}{0}\\
\bottomrule
\end{tabular}
\end{center}
and \texttt{four()},
\begin{center}
\begin{tabular}{rllll}
\toprule
\textbf{Name:}&\tT&\texttt{V}&\texttt{W}&\texttt{X}\\
\midrule
\textbf{Depth:}&0&1&1&2\\
\textbf{Index:}&0&0&1&0\\
\textbf{Type:}&\ttgp{0}{0}&\ttgp{1}{0}&\ttgp{1}{1}&\ttgp{2}{0}\\
\bottomrule
\end{tabular}
\end{center}
The generic parameter~\tU\ of \texttt{two()} has the same \index{declared interface type!generic parameter declaration}declared interface type, \ttgp{1}{0}, as the generic parameter~\tV\ of \texttt{four()}. This is not a problem because the source ranges of their parent declarations, \texttt{two()} and \texttt{Both}, do not intersect.
The numbering by depth can be seen in the \index{declared interface type!nested nominal type}declared interface type of a nested generic nominal type declaration. For example, the declared interface type of \texttt{Outer.Both} is the generic nominal type \texttt{Outer<\ttgp{0}{0}>.Both<\ttgp{1}{0}, \ttgp{1}{1}>}.
\paragraph{Implicit generic parameters.} Sometimes the generic parameter list is not written in source. Every protocol declaration has a generic parameter list with a single generic parameter named \IndexSelf\tSelf\ (\SecRef{protocols}), and every extension declaration has a generic parameter list cloned from that of the extended type (\ChapRef{extensions}). These implicit generic parameters can be referenced by name within their scope, just like the generic parameter declarations in a parsed generic parameter list (\SecRef{identtyperepr}).
Function, constructor and subscript declarations can also declare \IndexDefinition{opaque parameter}\emph{opaque parameters} with the \texttt{some} keyword, possibly in combination with a generic parameter list:
\begin{Verbatim}
func pickElement<E>(_ elts: some Sequence<E>) -> E {...}
\end{Verbatim}
An opaque parameter simultaneously declares a parameter value, a generic parameter type that is the type of the value, and a requirement this type must satisfy. Here, we can refer to ``\texttt{elts}'' from an expression inside the function body, but we cannot name the \emph{type} of ``\texttt{elts}'' in a type representation. From \index{expression}expression context however, the type of an opaque parameter can be obtained via the \texttt{type(of:)} special form, which produces a metatype value. This allows for invoking static methods on these types.
The \IndexDefinition{generic parameter list request}\Request{generic parameter list request} appends the opaque parameters to the parsed generic parameter list, so they follow the parsed generic parameters in index order. In \texttt{pickElement()}, the generic parameter \texttt{E} has canonical type~\rT, while the opaque parameter associated with ``\texttt{elts}'' has canonical type~\rU. Opaque parameter declarations also state a constraint type, which imposes a requirement on this unnamed generic parameter. We will discuss this in the next section. Note that when \texttt{some} appears in the return type of a function, it declares an \emph{opaque return type}, which is a related but different feature (\ChapRef{opaqueresult}).
In \ChapRef{genericsig}, we define the generic signature, which records all visible generic parameters of a declaration, independent of surface syntax.
\section{Requirements}\label{requirements}
The requirements of a generic declaration constrain the generic argument types that can be provided by the caller. This endows the generic declaration's type parameters with new capabilities, so they abstract over the concrete types that satisfy those requirements. We use the following encoding for requirements in the theory and implementation.
\begin{definition}\label{requirement def}
A \IndexDefinition{requirement}\emph{requirement} is a triple consisting of a \emph{requirement kind}, a \IndexDefinition{subject type!of requirement}subject type~\tT\ (usually a \index{type parameter}type parameter), and one final piece of information that depends on the requirement kind:
\begin{itemize}
\item A \IndexDefinition{conformance requirement}\textbf{conformance requirement} $\TP$ states that the replacement type for~\tT\ must conform to~\texttt{P}, which must be a protocol, protocol composition, or parameterized protocol type.
\item A \IndexDefinition{superclass requirement}\textbf{superclass requirement} $\TC$ states that the replacement type for~\tT\ must be a subclass of some \index{class type}class type~\tC.
\item A \IndexDefinition{layout requirement}\textbf{layout requirement} $\TAnyObject$ states that the replacement type for~\tT\ must be represented as a single reference-counted pointer at runtime.
\item A \IndexDefinition{same-type requirement}\textbf{same-type requirement} $\TU$ states that the replacement types for \tT~and~\tU\ must be \index{canonical type equality}canonically equal.
\end{itemize}
\end{definition}
When looking at concrete instances of requirements in a self-contained snippet of code, there is no ambiguity in using the same notation for the first three kinds, because the type referenced by the right-hand side determines the requirement kind. When talking about requirements in the abstract, we will explicitly state that~\texttt{P} is some protocol, or~\tC\ is some class, before talking about $\TP$ or $\TC$.
\paragraph{Constraint types.}
Before we introduce the trailing \texttt{where} clause syntax for stating requirements in a fully general way, let's look at the shorthand of stating a \IndexDefinition{constraint type}\emph{constraint type} in the \IndexDefinition{inheritance clause!generic parameter declaration}inheritance clause of a \index{generic parameter declaration}generic parameter declaration:
\begin{Verbatim}
func allEqual<E: Equatable>(_ elements: [E]) {...}
\end{Verbatim}
The generic parameter declaration~\texttt{E} declares the generic parameter type~\rT, and it also states the constraint type \texttt{Equatable}. This is a protocol declared in the standard library, so the stated requirement is the conformance requirement $\ConfReq{\rT}{Equatable}$. More generally, the constraint type is one of the following:
\begin{enumerate}
\item A \index{protocol type!constraint type}protocol type, like \texttt{Equatable}.
\item A \index{parameterized protocol type!constraint type}parameterized protocol type, like \texttt{Sequence<String>}.
\item A \index{protocol composition type!constraint type}protocol composition type, like \texttt{Sequence \& MyClass}.
\item A \index{class type!constraint type}class type, like \texttt{NSObject}.
\item The \Index{AnyObject@\texttt{AnyObject}}\texttt{AnyObject} \index{layout constraint}\emph{layout constraint}, which restricts the possible concrete types to those represented as a single reference-counted pointer.
\end{enumerate}
In the first three cases, the stated requirement becomes a conformance requirement. Otherwise, it is a superclass or layout requirement. In all cases, the subject type of the requirement is the \index{declared interface type!generic parameter declaration}declared interface type of the generic parameter.
\begin{example}
Notice how the generic parameter \texttt{B} of \texttt{open()} states the constraint type \texttt{Box<C>}, and this refers to the second generic parameter, \tC:
\begin{Verbatim}
func open<B: Box<C>, C>(box: B) -> C {
return box.contents!
}
class Box<Contents> {
var contents: Contents? = nil
}
\end{Verbatim}
This illustrates a property of the \index{scope tree}scope tree: generic parameters are visible in the entire \index{source range}source range of a generic declaration, including in the \index{generic parameter list}generic parameter list itself.
The declaration of \texttt{open()} thus states the superclass requirement $\ConfReq{\rT}{Box<\rU>}$. Here is a possible usage of \texttt{open()}, which we leave unexplained:
\begin{Verbatim}
struct Vegetable {}
class FarmBox: Box<Vegetable> {}
let vegetable: Vegetable = open(box: FarmBox())
\end{Verbatim}
\end{example}
\paragraph{Opaque parameters.}
An opaque parameter declaration is written with a \index{constraint type!opaque parameter}constraint type after the \texttt{some} keyword (\SecRef{generic params}). This specifies a conformance, superclass or layout requirement on the \index{opaque parameter}generic parameter type introduced by the opaque parameter declaration. For example, the following two declarations are equivalent:
\begin{Verbatim}
func pickElement<E>(_ elts: some Sequence<E>) -> E {...}
func pickElement<E, S: Sequence<E>>(_ elts: S) -> E {...}
\end{Verbatim}
We will see later that constraint types also appear in various other positions, and in all cases, they state a requirement with some distinguished subject type:
\begin{enumerate}
\item In the inheritance clause of a protocol or associated type (\SecRef{protocols}).
\item Following the \texttt{some} keyword in return position, where it declares an opaque return type (\ChapRef{opaqueresult}).
\item Following the \texttt{any} keyword that references an existential type (\ChapRef{existentialtypes}), with the exception that the constraint type cannot be a class by itself (for example, we allow ``\verb|any NSObject & Equatable|'', but ``\verb|any NSObject|'' is just ``\texttt{NSObject}'').
\end{enumerate}
\paragraph{Trailing where clauses.} Requirements can also be stated in a \IndexDefinition{where clause@\texttt{where} clause}\index{trailing where clause@trailing \texttt{where} clause|see{\texttt{where} clause}}\texttt{where} clause attached to the generic declaration. This allows generality that cannot be expressed using the inheritance clause of a generic parameter alone.
A \texttt{where} clause entry defines a requirement whose subject type is written explicitly, so that \index{dependent member type!in requirements}dependent member types can be be subject to requirements; here, we state two requirements, $\rTSequence$ and $\ConfReq{\rT.Element}{Comparable}$:
\begin{Verbatim}
func isSorted<S>(_: S) where S: Sequence, S.Element: Comparable {...}
\end{Verbatim}
A \texttt{where} clause can also state a same-type requirement. In the next example, we state two conformance requirements using the inheritance clause syntax, another conformance requirement, and the same-type requirement $\SameReq{\rT.Element}{\rU.Element}$:
\begin{Verbatim}
func merge<S1: Sequence, S2: Sequence>(_: S1, _: S2) -> [S1.Element]
where S1: Comparable, S1.Element == S2.Element {...}
\end{Verbatim}
Note that there is no way to refer to an opaque parameter type within the function's \Index{where clause@\texttt{where} clause!opaque parameter}\texttt{where} clause, but every declaration using opaque parameters can always be rewritten into an equivalent one using named generic parameters, so no generality is lost.
We saw in \ChapRef{types} that when the parser reads a type annotation in the source, it constructs a \index{type representation}type representation, a lower-level syntactic object which must be \index{type resolution}resolved to obtain a \index{type}type. Similarly, requirements have a syntactic form, called a \IndexDefinition{requirement representation}\emph{requirement representation}. The parser constructs requirement representations while reading a \texttt{where} clause. The relationship between the syntactic and semantic entities is shown in this diagram:
\begin{center}
\begin{tikzpicture}[node distance=1cm]
\node (ReqRepr) [data] {Requirement representation};
\node (TypeRepr) [data, below=of ReqRepr] {Type representation};
\node (Req) [data, right=2cm of ReqRepr] {Requirement};
\node (Type) [data, below=of Req] {Type};
\draw [arrow] (ReqRepr) -- (TypeRepr);
\draw [arrow] (Req) -- (Type);
\path [arrow] (ReqRepr) edge [left] node {\footnotesize{contains}} (TypeRepr);
\path [arrow] (Req) edge [right] node {\footnotesize{contains}} (Type);
\path [arrow] (ReqRepr) edge [above] node {\footnotesize{resolves to}} (Req);
\path [arrow] (TypeRepr) edge [below] node {\footnotesize{resolves to}} (Type);
\end{tikzpicture}
\end{center}
There are only two kinds of requirement representations, because the ``\texttt{:}'' form cannot distinguish conformance, superclass and layout requirements until we resolve the type representation on the right-hand side:
\begin{enumerate}
\item A \IndexDefinition{constraint requirement representation}\textbf{constraint requirement representation} ``\texttt{T:\ C}'', where \tT\ and \tC\ are type representations.
\item A \IndexDefinition{same-type requirement representation}\textbf{same-type requirement representation} ``\texttt{T == U}'', where \tT\ and \tU\ are type representations.
\end{enumerate}
Recall that a conformance requirement has a protocol type, protocol composition type, or parameterized protocol type on the right-hand side (\SecRef{fundamental types}). In the case of a protocol composition, we decompose the requirement into simpler requirements, one for each member of the composition. For example, if \texttt{MyClass} is a class, the requirement $\ConfReq{\rT}{Sequence~\&~MyClass}$ splits up as $\rTSequence$ and $\ConfReq{\rT}{MyClass}$, the latter being a superclass requirement. The empty protocol composition, written \Index{Any@\texttt{Any}}\texttt{Any}, is a trivial case; stating a conformance requirement to \texttt{Any} does nothing in a \texttt{where} clause, but it is allowed. Parameterized protocol types also decompose, as we'll see in~\SecRef{protocols}.
In the next section, we will introduce a formal system for derived requirements, where we will assume that only conformance requirements to protocol types remain, and that the subject type of a requirement is always a type parameter, and not an arbitrary type. \SecRef{requirement desugaring} will show how we eliminate these unnecessary forms of generality.
\paragraph{Contextually-generic declarations.} A generic declaration nested inside of another generic declaration can state a \texttt{where} clause, without introducing new generic parameters of its own. This is called a \IndexDefinition{contextually-generic declaration}\emph{contextually-generic declaration}:
\begin{Verbatim}
enum LinkedList<Element> {...}
extension LinkedList {
func sum() -> Element where Element: AdditiveArithmetic {...}
}
\end{Verbatim}
There is no semantic distinction between attaching a \texttt{where} clause to a member of a type, or moving the member to a \index{constrained extension}constrained extension (\SecRef{constrained extensions}), so the above is equivalent to the following:
\begin{Verbatim}
extension LinkedList where Element: AdditiveArithmetic {
func sum() -> Element {...}
}
\end{Verbatim}
\index{mangling}
However, for historical reasons, these two declarations have distinct \index{mangling!contextually-generic declaration}mangled symbol names, so the above is not an \index{ABI}ABI-compatible transformation.
\medskip
In \ChapRef{genericsig}, we will see that the generic signature of a declaration records all of its requirements, regardless of they were stated in source.
\paragraph{History.} The syntax described in this section has evolved over time:
\begin{itemize}
\item The \texttt{where} clause used to be written within the ``\texttt{<}'' and ``\texttt{>}'', but was moved to the current \Index{where clause@\texttt{where} clause!history}``trailing'' position in \IndexSwift{3.0}Swift 3 \cite{se0081}.
\item Generic type aliases were introduced in \IndexSwift{3.0}Swift 3 \cite{se0048}.
\item \index{protocol composition type!history}Protocol compositions involving class types were introduced in \IndexSwift{4.0}Swift 4 \cite{se0156}.
\item Generic \index{subscript declaration!history}subscripts were introduced in \IndexSwift{4.0}Swift 4 \cite{se0148}.
\item Implementation limitations prevented the \texttt{where} clause from stating requirements that constrain outer generic parameters until Swift 3, and \index{contextually-generic declaration!history}contextually-generic declarations were not allowed until \IndexSwift{5.3}Swift 5.3 \cite{se0261}.
\item \index{opaque parameter!history}Opaque parameter declarations were introduced in \IndexSwift{5.7}Swift 5.7 \cite{se0341}.
\end{itemize}
\section{Protocols}\label{protocols}
The \texttt{protocol} keyword introduces a \IndexDefinition{protocol declaration}\emph{protocol declaration}, which is a special kind of nominal type declaration. The members of a protocol, with the exception of type aliases, are requirements that must be witnessed by corresponding members in a \index{conforming type}conforming type. The protocol's properties, subscripts, and methods are called \IndexDefinition{value requirement}\emph{value requirements}. They don't have bodies, but are otherwise like member declarations of a concrete nominal type. The declared interface type of a protocol declaration is a \index{protocol type}protocol type.
Every protocol has an implicit generic parameter list with a single generic parameter named \IndexDefinition{protocol Self type@protocol \tSelf\ type}\tSelf, which abstracts over the conforming type. The declared interface type of \tSelf\ is always~\rT; protocols cannot be nested in other generic contexts (\SecRef{nested nominal types}), nor can they declare any other generic parameters.
The \texttt{associatedtype} keyword introduces an \IndexDefinition{associated type declaration}\emph{associated type declaration}, which can only appear inside of a protocol. The declared interface type is a \index{dependent member type!associated type declaration}dependent member type (\SecRef{fundamental types}). Specifically, the \index{declared interface type!associated type declaration}declared interface type of an associated type~\texttt{A} in a protocol~\texttt{P} is the \index{bound dependent member type!associated type declaration}bound dependent member type denoted \texttt{Self.[P]A}, formed from the base type of~\tSelf\ together with~\texttt{A}. A nominal type conforming to this protocol must declare a type witness for each associated type (\SecRef{type witnesses}).
Protocols can also state \IndexDefinition{associated requirement}\emph{associated requirements} on their \tSelf\ type and its dependent member types. The conforming type and its type witnesses must satisfy the protocol's associated requirements. We will review all the ways of stating associated requirements now.
\paragraph{Protocol inheritance clauses.}
A protocol can have an \index{inheritance clause!protocol declaration}inheritance clause with a list of one or more comma-separated \index{constraint type!protocol inheritance clause}constraint types. Each inheritance clause entry states an associated requirement with a subject type of \tSelf. These are additional requirements the conforming type itself must satisfy in order to conform.
An associated conformance requirement with a subject type of \tSelf\ establishes a \index{protocol inheritance|see{inherited protocol}}\IndexDefinition{inherited protocol}\emph{protocol inheritance} relationship. The protocol stating the requirement is the \emph{derived protocol}, and the protocol on the right-hand side is the \emph{base protocol}. The derived protocol is said to \emph{inherit} from (or sometimes, \emph{refine}) the base protocol. A \index{qualified lookup!protocol inheritance}qualified lookup will search through all base protocols, when the lookup begins at a derived protocol or one of its concrete conforming types.
For example, the standard library's \texttt{Collection} protocol inherits from \texttt{Sequence} by stating the associated requirement $\ConfReq{Self}{Sequence}$:
\begin{Verbatim}
protocol Collection: Sequence {...}
\end{Verbatim}
Protocols can restrict their conforming types to those with a reference-counted pointer representation by stating an \texttt{AnyObject} layout constraint in the inheritance clause:
\begin{Verbatim}
protocol BoxProtocol: AnyObject {...}
\end{Verbatim}
Protocols can also limit their conforming types to subclasses of some superclass:
\begin{Verbatim}
class Plant {}
class Animal {}
protocol Duck: Animal {}
class MockDuck: Plant, Duck {} // error: not a subclass of Animal
\end{Verbatim}
A protocol is \IndexDefinition{class-constrained protocol}\emph{class-constrained} if the $\ConfReq{Self}{AnyObject}$ \index{associated layout requirement}associated layout requirement is either explicitly stated, or a consequence of some other associated requirement. We'll say more about the semantics of protocol inheritance clauses and name lookup in \SecRef{requirement sig}, \SecRef{identtyperepr}, and \ChapRef{building generic signatures}.
\paragraph{Primary associated types.}
A protocol can declare a list of \IndexDefinition{primary associated type}\emph{primary associated types} with a syntax resembling that of a generic parameter list:
\begin{Verbatim}
protocol IteratorProtocol<Element> {
associatedtype Element
mutating func next() -> Element?
}
\end{Verbatim}
While generic parameter lists introduce new generic parameter declarations, the entries in the primary associated type list reference an \emph{existing} associated type declaration, either in the protocol itself, or some base protocol.
A \index{parameterized protocol type}\emph{parameterized protocol type} can be formed from a reference to a protocol with primary associated types, by taking a list of generic argument types, one for each primary associated type. On the right-hand side of a conformance requirement, a parameterized protocol type decomposes into a conformance requirement to the protocol, followed by a series of same-type requirements. The following are equivalent:
\begin{Verbatim}
func sumOfSquares<I>(_: I) -> Int
where I: IteratorProtocol<Int> {...}
func sumOfSquares<I>(_: I) -> Int
where I: IteratorProtocol, I.Element == Int {...}
\end{Verbatim}
More details appear in \SecRef{requirement desugaring}. Parameterized protocol types and primary associated types were added to the language in \IndexSwift{5.7}Swift~5.7~\cite{se0346}.
\paragraph{Associated requirements.}
An associated type declaration can have an \IndexDefinition{inheritance clause!associated type declaration}inheritance clause, consisting of one or more comma-separated constraint types. Each entry defines a requirement on the declared interface type of the associated type declaration, so we get $\ConfReq{Self.Data}{Codable}$ and $\ConfReq{Self.Data}{Hashable}$ below:
\begin{Verbatim}
associatedtype Data: Codable, Hashable
\end{Verbatim}
An associated type declaration can also have a trailing \Index{where clause@\texttt{where} clause!associated type declaration}\texttt{where} clause, which allows associated requirements to be stated in full generality. The standard library \texttt{Sequence} protocol showcases both primary associated types, and associated requirements:
\begin{Verbatim}
protocol Sequence<Element> {
associatedtype Iterator: IteratorProtocol
associatedtype Element where Element == Iterator.Element
func makeIterator() -> Iterator
}
\end{Verbatim}
The associated conformance requirement on \texttt{Self.Iterator} could have been stated using a \texttt{where} clause instead:
\begin{Verbatim}
associatedtype Iterator where Iterator: IteratorProtocol
\end{Verbatim}
A \Index{where clause@\texttt{where} clause!protocol declaration}\texttt{where} clause can also be attached to the protocol itself; there is no semantic difference between that and attaching it to an associated type declaration:
\begin{Verbatim}
protocol Sequence where Iterator: IteratorProtocol,
Element == Iterator.Element {...}
\end{Verbatim}
Finally, we can explicitly qualify the member types with \tSelf:
\begin{Verbatim}
protocol Sequence where Self.Iterator: IteratorProtocol,
Self.Element == Self.Iterator.Element {...}
\end{Verbatim}
In all cases, we state the same two associated requirements. Our notation is to append a subscript with the protocol name declaring the requirement:
\begin{gather*}
\ConfReq{Self.Iterator}{IteratorProtocol}_\texttt{Sequence}\\
\SameReq{Self.Element}{Self.Iterator.Element}_\texttt{Sequence}
\end{gather*}
Let's summarize all the ways of stating associated requirements in a protocol~\texttt{P}:
\begin{itemize}
\item The protocol can state an inheritance clause. Each entry defines a conformance, superclass or layout requirement with a subject type of \tSelf.
\item An associated type declaration \texttt{A} can state an inheritance clause. Each entry defines a conformance, superclass or layout requirement with a subject type of \texttt{Self.[P]A}.
\item Arbitrary associated requirements can be stated in \Index{where clause@\texttt{where} clause!protocol declaration}trailing \texttt{where} clauses, attached to the protocol or any of its associated types, in any combination.
\end{itemize}
A protocol's associated requirements are collected in its requirement signature, which we will see is dual to a generic signature in some sense (\SecRef{requirement sig}). How concrete types satisfy the requirement signature will be discussed in \ChapRef{conformances}.
\paragraph{Self requirements.}
The \Index{where clause@\texttt{where} clause!protocol declaration}\texttt{where} clause of a protocol method or subscript requirement cannot constrain \tSelf\ or its associated types. For example, the following protocol is rejected, because there would be no way to implement the \texttt{minElement()} requirement in a concrete conforming type whose \texttt{Element} type is \emph{not} \texttt{Comparable}:
\begin{Verbatim}
protocol SetProtocol {
associatedtype Element // we want `where Element: Comparable' here
func minElement() -> Element where Element: Comparable // error
}
\end{Verbatim}
\paragraph{History.}
Older releases of Swift permitted protocols and associated types to state constraint types in their inheritance clauses, but more general associated requirements did not exist. Associated requirements were introduced when the trailing \texttt{where} clause syntax was generalized to associated types and protocols in \IndexSwift{4.0}Swift~4~\cite{se0142}.
\section{Functions}\label{function decls}
A \IndexDefinition{function declaration}function declaration can appear at the top level of a source file, as a member of a nominal type or extension (which we recall is called a method declaration), or as a \IndexDefinition{local function declaration}\emph{local function} nested inside of another function. In this section, we will describe the computation of the interface type of a function declaration, and then conclude with a discussion how closure expressions and local functions capture values.
The \IndexDefinition{interface type request}\Request{interface type request} computes the interface type of a function declaration. This is a \index{function type}function type or \index{generic function type}generic function type, constructed from the interface types of the function's parameter declarations, together with its return type, and generic signature, if any. If no return type is given, it becomes the empty tuple type~\texttt{()}:
\begin{Verbatim}
func f(x: Int, y: String) -> Bool {...}
// Interface type: (Int, String) -> Bool
func g() {...}
// Interface type: () -> ()
\end{Verbatim}
\paragraph{Method declarations.}
In addition to the formal parameters declared in its parameter list, a method declaration also has an implicit \texttt{self} parameter, to receive the value on the left-hand side of the ``\texttt{.}'' in the \index{method call expression}method call expression. The interface type of a method declaration is a function type which receives the \IndexDefinition{self parameter declaration}\texttt{self} parameter, and returns another function which then takes the method's formal parameters. The ``\texttt{->}'' syntax for a function type associates to the right, so \verb|A -> B -> C| means \verb|A -> (B -> C)|:
\begin{Verbatim}
struct Universe {
func wormhole(x: Int, y: String) -> Bool {...}
// Interface type: (Universe) -> (Int, String) -> Bool
static func bigBang() {}
// Interface type: (Universe.Type) -> () -> ()
mutating func teleport() {}
// Interface type: (inout Universe) -> () -> ()
}
\end{Verbatim}
The interface type of the \texttt{self} parameter is derived as follows:
\begin{itemize}
\item We start with the \IndexDefinition{self interface type}\emph{self interface type} of the method's parent declaration context. In a struct, enum or class, this is the same as the \index{declared interface type!self interface type}declared interface type. In a protocol, this is the protocol \IndexSelf\tSelf\ type (\SecRef{protocols}). In an extension, the self interface type is that of the extended type.
\item If the method is declared inside a class, and if it returns the \Index{dynamic Self type@dynamic \tSelf\ type}dynamic \tSelf\ type, we wrap the type in the dynamic \tSelf\ type (\SecRef{misc types}).
\item If the method is \IndexDefinition{static method declaration}\texttt{static}, we wrap the type in a \index{metatype type}metatype.
\item If the method is \texttt{mutating}, we pass the \texttt{self} parameter \texttt{inout}.
\end{itemize}
\begin{figure}[b!]\captionabove{The method call \texttt{universe.wormhole(x:~1, y:~"hi")}}\label{method call expr}
\begin{center}
\begin{tikzpicture}[%
grow via three points={one child at (0.5,-0.7) and
two children at (0.5,-0.7) and (0.5,-1.4)},
edge from parent path={[->] (\tikzparentnode.south) |- (\tikzchildnode.west)}]
\node [class] {\vphantom{p}call: \texttt{universe.wormhole(x:~1, y:~"hi")}}
child { node [class] {\vphantom{p}self call: \texttt{universe.wormhole}}
child { node [class] {\vphantom{p}callee: \texttt{Universe.wormhole}}}
child { node [class] {\vphantom{p}declaration reference: \texttt{universe}}}}
child [missing] {}
child [missing] {}
child { node [class] {\vphantom{p}argument list: \texttt{(x:~1, y:~"hi")}}
child { node [class] {\vphantom{p}literal: \texttt{1}}}
child { node [class] {\vphantom{p}literal: \texttt{"hi"}}}}
child [missing] {}
child [missing] {}
child [missing] {};
\end{tikzpicture}
\end{center}
\end{figure}
Let's compare the interface type of a method declaration with the structure of a method call expression in the abstract syntax tree, shown in \FigRef{method call expr}:
\begin{itemize}
\item The outer expression's callee, \texttt{universe.wormhole}, is itself a call expression, so we must evaluate this inner call expression first.
The inner call expression applies the argument \texttt{universe} to the \texttt{self} parameter of \texttt{Universe.wormhole()}. This represents the method lookup. The return type of the inner call expression is \verb|(Int, String) -> Bool|.
\item The outer call expression applies the argument list \verb|(x: 1, y: "hi")| to the result of the inner call expression. This represents the method call itself, with a return type of \texttt{Bool}.
\end{itemize}
The extra function call disappears in \index{SILGen}SILGen, where we lower a method to a SIL function that receives all formal parameters and the \texttt{self} parameter at once.
A partially-applied method reference, such as \texttt{universe.wormhole}, can also be used as a value of type \verb|(Int, String) -> Bool|. This binds the \texttt{self} parameter but does not call the method. We handle this by wrapping the method reference in a closure that invokes the method; this closure has the same type as the method reference. In the \index{lambda calculus}lambda calculus formalism, this is what's known as \index{eta expansion}\emph{$\eta$-expansion}:
\begin{Verbatim}
{ x, y in universe.wormhole(x: x, y: y) }
\end{Verbatim}
The \index{unapplied function reference}unapplied form, \texttt{Universe.wormhole}, desugars into a closure returning a closure:
\begin{Verbatim}
{ mySelf in { x y in mySelf.wormhole(x: x, y: y) } }
\end{Verbatim}
This desugaring simplifies SILGen, because we only need to implement a lowering for fully-applied method calls that pass all formal parameters and \texttt{self} at once.
\begin{wrapfigure}[25]{l}{17.2em}
\begin{minipage}{17em}
\begin{Verbatim}
struct Example {
func instanceMethod() {}
static func staticMethod() {}
struct Lookup {
func innerMethod() {}
func test() {
instanceMethod() // bad
staticMethod() // ok
innerMethod() // ok
}
}
func anotherMethod(x: Int) {
struct Local {
func test() {
print(x) // bad
}
}
}
}
\end{Verbatim}
\end{minipage}
\end{wrapfigure}
All function declarations must be followed by a body in the source language, except for protocol requirements. A function body can contain statements, expressions, and other declarations. (Unlike types and declarations, we will not exhaustively cover all statements and expressions in this book.) The example on the left shows some call expressions.
In a method body, an unqualified reference to a member of the innermost nominal type declaration is interpreted as having an implicit ``\texttt{self.}'' qualification. Thus, instance methods can refer to other instance methods this way, and static methods can refer to other static methods.
An unqualified reference to a member of an outer nominal type can only be made if the member is static, because there is no ``outer \texttt{self} value'' to invoke the method with; a \emph{value} of the nested type does not contain a \emph{value} of its parent type.
For the same reason, methods inside \index{local type declaration}local types cannot refer to local variables declared outside of the local type. (Contrast this with \index{Java}Java inner classes for example, which can be declared as \texttt{static} or instance members of their outer class; a non-\texttt{static} inner class captures a ``\texttt{this}'' reference from the outer class. Inner classes nested in methods can also capture local variables in Java.)
\paragraph{Constructor declarations.}
\IndexDefinition{constructor declaration}Constructor declarations are introduced with the \texttt{init} keyword. The parent context of a constructor must be a nominal type or extension.
From the outside, the interface type of a constructor looks like a static method that returns a new instance of the type, but inside the constructor, \texttt{self} is the instance being initialized, so the interface type of \texttt{self} is the nominal type, and not its metatype. In a struct or enum, \texttt{self} is also \texttt{inout}. Constructors can delegate to other constructors in various ways. To model the delegation with a call expression, the \IndexDefinition{initializer interface type}\emph{initializer interface type} describes the type of an in-place initialization at a location provided by the caller:
\begin{Verbatim}
struct Universe {
init(age: Int) {...}
// Interface type: (Universe.Type) -> (Int) -> Universe
// Initializer interface type: (inout Universe) -> (Int) -> Universe
}
\end{Verbatim}
\paragraph{Destructor declarations.}
\IndexDefinition{destructor declaration}Destructor declarations are introduced with the \texttt{deinit} keyword. They can only appear inside classes. They have no formal parameters, no generic parameter list, no \texttt{where} clause, and no return type.
\paragraph{Local contexts.}
A \IndexDefinition{local context}\emph{local context} is any declaration context that is not a module, source file, type declaration or extension. Swift allows variable, function and type declarations to appear in local context. The following are local contexts:
\begin{itemize}
\item \index{top-level code declaration}Top-level code declarations.
\item Function declarations.
\item \index{closure expression}Closure expressions.
\item If a variable is not itself in local context (for example, it's a member of a nominal type declaration), then its \index{initial value expression}initial value expression defines a new local context.
\item \index{subscript declaration}Subscript and \index{enum element declaration}enum element declarations declarations are local contexts, because they can contain parameter declarations (and also a generic parameter list, in the case of a subscript).
\end{itemize}
Local functions and closures can \IndexDefinition{captured value}\emph{capture} references to other local declarations from outer scopes. We use the standard technique of \IndexDefinition{closure conversion}\emph{closure conversion} to lower functions with captured values into ones without. We can understand this process as introducing an additional parameter for each captured value, followed by a walk to replace references to captured values with references to the corresponding parameters in the function body. In Swift, this is part of \index{SILGen}SILGen's lowering process, and not a separate transformation on the abstract syntax tree.
The \IndexDefinition{capture info request}\Request{capture info request} computes the list of declarations captured by the given function and all of its nested local functions and closure expressions.
\begin{wrapfigure}[10]{l}{10.6em}
\begin{minipage}{10.5em}
\begin{Verbatim}
func f() {
let x = 0, y = 0
func g() {
var z = 0
print(x)
func h() {
print(y, z)
}
}
}
\end{Verbatim}
\end{minipage}
\end{wrapfigure}
Consider the three nested functions shown on the left. We proceed to compute their captures from the inside out.
The innermost function~\texttt{h()} captures \texttt{y}~and~\texttt{z}. The middle function~\texttt{g()} captures~\texttt{x}. It also captures~\texttt{y}, because~\texttt{h()} captures~\texttt{y}, but it does not capture~\texttt{z}, because~\texttt{z} is declared by~\texttt{g()} itself. Finally,~\texttt{f()} is declared at the top level, so it does not have any captures.
We can summarize this as follows (see \AppendixRef{math summary} for a summary of set notation):
% FIXME
\begin{quote}
\qquad\qquad
\begin{tabular}{lll}
\toprule
\textbf{Function}&\textbf{Captures}\\
\midrule
\texttt{f()}&$\varnothing$\\
\texttt{g()}&$\{\texttt{x},\,\texttt{y}\}$\\
\texttt{h()}&$\{\texttt{y},\,\texttt{z}\}$\\
\bottomrule
\end{tabular}
\end{quote}
\bigskip
\begin{algorithm}[Compute closure captures]\label{closure captures algorithm}
As input, takes the type-checked body of a \index{closure function}closure expression or \index{local function declaration}local function~$F$. Outputs the \index{set}set of captures of~$F$.
\begin{enumerate}
\item Initialize the return value with an \index{empty set}empty set, $C\leftarrow\varnothing$.
\item Recursively walk the type-checked body of $F$ and handle each element:
\item (Declaration references) If $F$ contains an expression that references some local variable or local function~$d$ by name, let $\texttt{PARENT}(d)$ denote the declaration context containing~$d$. This is either $F$ itself, or some outer local context, because we found $d$ by unqualified lookup from~$F$.
If $\texttt{PARENT}(d)\neq F$, set $C\leftarrow C\cup\{d\}$.
\item (Nested closures) If $F$ contains a nested closure expression or local function $F^\prime\!$, then any captures of $F^\prime$ not declared by~$F$ are also captures of~$F$.
Recursively compute the captures of $F^\prime\!$. For each $d$ captured by $F^\prime$ such that $\texttt{PARENT}(d)\neq F$, set $C\leftarrow C\cup\{d\}$.
\item (Local types) If $F$ contains a local type, do not walk into the children of the local type. Local types do not capture values; we enforce this below.
\item (Diagnose) After the recursive walk, consider each element $d\in C$. If the path of parent declaration contexts from $F$ to $d$ contains a nominal type declaration, we have an unsupported capture inside a local type. Diagnose an error.
\item Return $C$.
\end{enumerate}
\end{algorithm}
\begin{wrapfigure}[9]{r}{16.5em}
\begin{minipage}{16.5em}
\begin{Verbatim}
func f() {
let x = 0, y = 0, z = 0
func g() { print(x); h() }
func h() { print(y); g() }
func i() { print(z); h() }
}
\end{Verbatim}
\end{minipage}
\end{wrapfigure}
Local functions can also reference each other recursively. Consider the functions shown on the right and notice how \texttt{f()} and \texttt{g()} are mutually recursive. At runtime, we cannot represent this by forming two closure contexts where each one retains the other, because then neither context will ever be released.
We use a second algorithm to obtain the list of \IndexDefinition{lowered captures}\emph{lowered captures}, by replacing any captured local functions with their corresponding capture lists, repeating this until fixed point. The final list contains variable declarations only. With our example, the captures and lowered captures of each function are as follows:
\begin{center}
\begin{tabular}{lll}
\toprule
\textbf{Function}&\textbf{Captures}&\textbf{Lowered}\\
\midrule
\texttt{f()}&$\varnothing$&$\varnothing$\\
\texttt{g()}&$\{\texttt{x},\,\texttt{h()}\}$&$\{\texttt{x},\,\texttt{y}\}$\\
\texttt{h()}&$\{\texttt{y},\,\texttt{g()}\}$&$\{\texttt{x},\,\texttt{y}\}$\\
\texttt{i()}&$\{\texttt{z},\,\texttt{h()}\}$&$\{\texttt{x},\,\texttt{y},\,\texttt{z}\}$\\
\bottomrule
\end{tabular}
\end{center}
(As a special case, if a set of local functions reference each other but capture no other state from the outer declaration context, their lowered captures will be empty, so no runtime context allocation is necessary.)
\begin{algorithm}[Compute lowered closure captures]\label{lowered closure captures algorithm}
As input takes the type-checked body of a \index{closure function}closure expression or \index{local function declaration}local function~$F$. Outputs the \index{set}set of variable declarations transitively captured by~$F$.
\begin{enumerate}
\item Initialize the set $C\leftarrow\varnothing$; this will be the return value. Initialize an empty worklist. Initialize an empty visited set. Add $F$ to the worklist.
\item If the worklist is empty, return $C$. Otherwise, remove the next function $F$ from the worklist.
\item If $F$ is in the visited set, go back to Step~2. Otherwise, add $F$ to the visited set.
\item Compute the captures of~$F$ using \AlgRef{closure captures algorithm} and consider each capture~$d$. If~$d$ is a local variable declaration, set $C\leftarrow C\cup\{d\}$. If~$d$ is a local function declaration, add~$d$ to the worklist.
\item Go back to Step~2.
\end{enumerate}
\end{algorithm}
This completely explains captures of \texttt{let} variables, but mutable \texttt{var} variables and \texttt{inout} parameters merit further explanation.
A \index{non-escaping function type}\emph{non-escaping} closure can capture a \texttt{var} or \texttt{inout} by simply capturing the memory address of the storage location. This is safe, because a non-escaping closure cannot outlive the dynamic extent of the storage location.
An \index{escaping function type}\texttt{@escaping} closure can also capture a \texttt{var}, which requires promoting the \texttt{var} to a \index{boxing}heap-allocated box with a reference count, with all variable accesses indirecting through the box. The below example can be found in every \index{Lisp}Lisp textbook. Each invocation of \texttt{counter()} allocates a new counter value on the heap, and returns three closures that reference the box; the box itself is completely hidden by the abstraction:
\begin{Verbatim}
func counter() -> (read: () -> Int, inc: () -> (), dec: () -> ()) {
var count = 0 // promoted to a box
return ({ count }, { count += 1 }, { count -= 1 })
}
\end{Verbatim}
Before \IndexSwift{3.0}Swift~3.0, \texttt{@escaping} closures were permitted to capture \texttt{inout} parameters as well. To make this safe, the contents of the \texttt{inout} parameter were first copied into a heap-allocated box, which was captured by the closure. The contents of this box were then copied back before the function returned to its caller. This was essentially equivalent to doing the following transform, where we introduced \verb|_n| by hand:
\begin{Verbatim}
func changeValue(_ n: inout Int) {
var _n = n // copy the value
let escapingFn = {
_n += 1 // capture the box
}
n = _n // write it back
}
\end{Verbatim}
In this scheme, if the closure outlives the dynamic extent of the \texttt{inout} parameter, any subsequent writes from within the closure are silently dropped. This was a source of user confusion, so Swift~3.0 banned \texttt{inout} captures from escaping closures instead~\cite{se0035}.
In SIL, a closure is represented abstractly, as the result of this partial application operation. The mechanics of how the partially-applied function value actually stores its captures---the partially-applied arguments---are left up to IRGen. In IRGen, we allocate space for storing the captures (either on the stack for a \index{non-escaping function type}non-escaping function type, otherwise it's on the heap for \texttt{@escaping}), and then we emit a thunk, which takes a pointer to the context as an argument, unpacks the captured values from the context, and passes them as individual arguments to the original function. This thunk together with the context forms a \IndexDefinition{thick function}\emph{thick function} value which can then be passed around.
If nothing is captured (or if all captured values are zero bytes in size), we can pass a null pointer as the context, without performing a heap allocation. If there is exactly one captured value and this value can be represented as a reference-counted pointer, we can also elide the allocation by passing the captured value as the context pointer instead. For example, if a closure's single capture is an instance of a \index{class type}class type, nothing is allocated. If the single capture is the heap-allocated box that wraps a \texttt{var}, we must still allocate the box for the \texttt{var}, but we avoid a second context allocation.
\section{Storage}\label{other decls}
\IndexDefinition{storage declaration}
\index{l-value type}
Storage declarations represent locations that can be read and written.
\paragraph{Parameter declarations.} Functions, enum elements and subscripts can have parameter lists; each parameter is represented by a \IndexDefinition{parameter declaration}parameter declaration. Parameter declarations are a kind of variable declaration.
\paragraph{Variable declarations.} \IndexDefinition{variable declaration}Variables that are not parameters are introduced with \texttt{var} and \texttt{let}. A variable might either be \emph{stored} or \emph{computed}; the behavior of a computed variable is given by its accessor implementations. The interface type of a variable is the stored value type, possibly wrapped in a reference storage type if the variable is declared as \texttt{weak} or \texttt{unowned}. The \IndexDefinition{value interface type}\emph{value interface type} of a variable is the storage type without any wrapping.
\IndexDefinition{pattern binding declaration}
\IndexDefinition{pattern binding entry}
\IndexDefinition{pattern}
\IndexDefinition{initial value expression}
Variable declarations are always created alongside a \emph{pattern binding declaration} which represents the various ways in which variables can be bound to values in Swift. A pattern binding declaration consists of one or more \emph{pattern binding entries}. Each pattern binding entry has a \emph{pattern} and an optional \emph{initial value expression}. A pattern declares zero or more variables.
Here is a pattern binding declaration with a single entry that does not declare any variables:
\begin{Verbatim}
let _ = ignored()
\end{Verbatim}
Here is a pattern binding declaration with a single entry, where the pattern declares a single variable:
\begin{Verbatim}
let x = 123
\end{Verbatim}
We can write a more complex pattern, for example storing the first element of a tuple while discarding the second element:
\begin{Verbatim}
let (x, _) = (123, "hello")
\end{Verbatim}
Here is a pattern binding declaration with a single entry, whose pattern delares two variables \texttt{x} and \texttt{y}:
\begin{Verbatim}
let (x, y) = (123, "hello")
\end{Verbatim}
Here is a pattern binding declaration with two entries, declaring \texttt{x} and \texttt{y} respectively:
\begin{Verbatim}
let x = 123, y = "hello"
\end{Verbatim}
And finally, here we have two pattern binding declarations, where each pattern binding declaration has a single entry declaring a single variable:
\begin{Verbatim}
let x = 123
let y = "hello"
\end{Verbatim}
When a pattern binding declaration appears outside of a local context, each entry must declare at least one variable, so we reject both of the following:
\begin{Verbatim}
let _ = 123
struct S {
let _ = "hello"
}
\end{Verbatim}
\index{typed pattern}
\index{tuple pattern}
A funny quirk of the pattern grammar is that typed patterns and tuple patterns do not compose in the way one might think. If ``\texttt{let x:~Int}'' is a typed pattern declaring a variable \texttt{x} type with annotation \texttt{Int}, and ``\texttt{let (x, y)}'' is a tuple pattern declaring two variables \texttt{x} and \texttt{y}, we might expect ``\texttt{let~(x:~Int,~y:~String)}'' to declare two variables \texttt{x} and \texttt{y} with type annotations \texttt{Int} and \texttt{String} respectively; what actually happens is we get a tuple pattern declaring two variables named \texttt{Int} and \texttt{String} that binds a two-element tuple with \emph{labels} \texttt{x} and \texttt{y}:
\begin{Verbatim}
let (x: Int, y: String) = (x: 123, y: "hello")
print(Int) // huh? prints 123
print(String) // weird! prints "hello"
\end{Verbatim}
\paragraph{Subscript declarations.} \IndexDefinition{subscript declaration}Subscripts are introduced with the \texttt{subscript} keyword. They can only appear as members of nominal types and extensions. The interface type of a subscript is a function type taking the index parameters and returning the storage type. The value interface type of a subscript is just the storage type. For historical reasons, the interface type of a subscript does not include the \tSelf\ clause, the way that method declarations do. Subscripts can either be instance or static members; static subscripts were introduced in \IndexSwift{5.1}Swift~5.1 \cite{se0254}.
\paragraph{Accessor declarations.}
Each storage declaration has a \IndexDefinition{accessor declaration}set of accessor declarations, which are a special kind of function declaration. The accessor declarations are siblings of the storage declaration in the declaration context hierarchy. The interface type of an accessor depends the accessor kind. For example, getters return the value, and setters take the new value as a parameter. Property accessors do not take any other parameters; subscript accessors also take the subscript's index parameters. We will not need any more details about accessor and storage declarations in this book.
\section{Source Code Reference}\label{declarationssourceref}
Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/Decl.h}
\item \SourceFile{include/swift/AST/DeclContext.h}
\item \SourceFile{lib/AST/Decl.cpp}
\item \SourceFile{lib/AST/DeclContext.cpp}
\end{itemize}
Other source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/DeclNodes.def}
\item \SourceFile{include/swift/AST/ASTVisitor.h}
\item \SourceFile{include/swift/AST/ASTWalker.h}
\end{itemize}
\IndexSource{declaration}
\apiref{Decl}{class}
Base class of declarations. \FigRef{declhierarchy} shows various subclasses, which correspond to the different kinds of declarations defined previously in this chapter.
\begin{figure}\captionabove{The \texttt{Decl} class hierarchy}\label{declhierarchy}
\begin{center}
\begin{tikzpicture}[%
grow via three points={one child at (0.5,-0.7) and
two children at (0.5,-0.7) and (0.5,-1.4)},
edge from parent path={[->] (\tikzparentnode.south) |- (\tikzchildnode.west)}]
\node [class] {\texttt{\vphantom{p}Decl}}
child { node [class] {\texttt{\vphantom{p}ValueDecl}}
child { node [class] {\texttt{\vphantom{p}TypeDecl}}
child { node [class] {\texttt{\vphantom{p}NominalTypeDecl}}
child { node [class] {\texttt{\vphantom{p}StructDecl}}}
child { node [class] {\texttt{\vphantom{p}EnumDecl}}}
child { node [class] {\texttt{\vphantom{p}ClassDecl}}}
child { node [class] {\texttt{\vphantom{p}ProtocolDecl}}}
}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child { node [class] {\texttt{\vphantom{p}TypeAliasDecl}}}
child { node [class] {\texttt{\vphantom{p}AbstractTypeParamDecl}}
child { node [class] {\texttt{\vphantom{p}GenericTypeParamDecl}}}
child { node [class] {\texttt{\vphantom{p}AssociatedTypeDecl}}}
}
}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child { node [class] {\texttt{\vphantom{p}AbstractFunctionDecl}}
child { node [class] {\texttt{\vphantom{p}FuncDecl}}
child { node [class] {\texttt{\vphantom{p}AccessorDecl}}}
}
child [missing] {}
child { node [class] {\texttt{\vphantom{p}ConstructorDecl}}}
child { node [class] {\texttt{\vphantom{p}DestructorDecl}}}
}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child { node [class] {\texttt{\vphantom{p}AbstractStorageDecl}}
child { node [class] {\texttt{\vphantom{p}VarDecl}}
child { node [class] {\texttt{\vphantom{p}ParamDecl}}}
}
child [missing] {}
child { node [class] {\texttt{\vphantom{p}SubscriptDecl}}}
}
child [missing] {}
child [missing] {}
child [missing] {}
}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child [missing] {}
child { node [class] {\texttt{\vphantom{p}ExtensionDecl}}};
\end{tikzpicture}
\end{center}
\end{figure}
\IndexSource{synthesized declaration}
Instances are always allocated in the permanent arena of the \texttt{ASTContext}, either when the declaration is parsed or synthesized. The top-level \verb|isa<>|, \verb|cast<>| and \verb|dyn_cast<>| template functions support dynamic casting from \texttt{Decl *} to any of its subclasses.
\begin{itemize}
\item \texttt{getDeclContext()} returns the parent \texttt{DeclContext} of this declaration.
\item \texttt{getInnermostDeclContext()} if this declaration is also a declaration context, returns the declaration as a \texttt{DeclContext}, otherwise returns the parent \texttt{DeclContext}.
\item \texttt{getASTContext()} returns the singleton AST context from a declaration.
\end{itemize}
\index{visitor pattern}
\IndexSource{declaration kind}
\index{exhaustive switch}
\index{statement}
\index{expression}
\index{type representation}
\paragraph{Visitors.}
To exhaustively handle each kind of declaration, the simplest way is to switch over the kind, which is an instance of the \texttt{DeclKind} enum, like this:
\begin{Verbatim}
Decl *decl = ...;
switch (decl->getKind()) {
case DeclKind::Struct: {
auto *structDecl = decl->castTo<StructDecl>();
...
}
case DeclKind::Enum:
...
case DeclKind::Class:
...
}
\end{Verbatim}
However, just as with types, is can be more convenient to use the visitor pattern, by subclassing \texttt{ASTVisitor} and overriding various \texttt{visit\emph{Kind}Decl()} methods. The visitor's \texttt{visit()} method performs the switch and dynamic cast dance above, and calls each method:
\begin{Verbatim}
class MyVisitor: public ASTVisitor<MyVisitor> {
public:
void visitStructDecl(StructType *decl) {
...
}
};
MyVisitor visitor;
Decl *decl = ...;
visitor.visit(decl);
\end{Verbatim}
The \texttt{ASTVisitor} also defines various methods corresponding to abstract base classes in the \texttt{Decl} hierarchy, so for example an override of \texttt{visitNominalTypeDecl()} will handle all nominal type declarations at once. The \texttt{ASTVisitor} is more general than just visiting declarations; it also supports visiting statements, expressions, and type representations.
A more elaborate form is implemented by the \texttt{ASTWalker}. While the visitor visits a single declaration, the walker traverses nested declarations, statements and expressions in a pre-order walk.
\IndexSource{value declaration}
\apiref{ValueDecl}{class}
Base class of named declarations.
\IndexSource{interface type}
\begin{itemize}
\item \texttt{getDeclName()} returns the declaration's name.
\item \texttt{getInterfaceType()} returns the declaration's interface type.
\end{itemize}
\subsection*{Type Declarations}
\IndexSource{type declaration}
\IndexSource{declared interface type}
\apiref{TypeDecl}{class}
Base class of type declarations.
\begin{itemize}
\item \texttt{getDeclaredInterfaceType()} returns the type of an instance of this declaration.
\end{itemize}
\IndexSource{nominal type declaration}
\IndexSource{struct declaration}
\IndexSource{enum declaration}
\IndexSource{class declaration}
\IndexSource{nominal type declaration}
\IndexSource{self interface type}
\apiref{NominalTypeDecl}{class}
Base class of nominal type declarations. Also a \texttt{DeclContext}.
\begin{itemize}
\item \texttt{getSelfInterfaceType()} returns the self interface type of the declaration context (\SecRef{function decls}). Different from the declared interface type for protocols, where the declared interface type is a nominal but the declared self type is the generic parameter \tSelf.
\item \texttt{getDeclaredType()} returns the type of an instance of this declaration, without generic arguments. If the declaration is generic, this is an \IndexSource{unbound generic type}unbound generic type. If this declaration is not generic, this is a nominal type. This is occasionally used in diagnostics instead of the declared interface type, when the generic parameter types are irrelevant.
\end{itemize}
\IndexSource{type alias declaration}
\IndexSource{underlying type}
\apiref{TypeAliasDecl}{class}
A type alias declaration. Also a \texttt{DeclContext}.
\begin{itemize}
\item \texttt{getDeclaredInterfaceType()} returns the underlying type of the type alias declaration, wrapped in type alias type sugar.
\item \texttt{getUnderlyingType()} returns the underlying type of the type alias declaration, without wrapping it in type alias type sugar.
\end{itemize}
\subsection*{Declaration Contexts}
\IndexSource{declaration context}
\apiref{DeclContext}{class}
Base class for declaration contexts. The top-level \verb|isa<>|, \verb|cast<>| and \verb|dyn_cast<>| template functions also support dynamic casting from a \texttt{DeclContext *} to any of its subclasses. See also \SecRef{genericsigsourceref}.
\IndexSource{closure expression}
\IndexSource{source file}
\IndexSource{file unit}
There are a handful of subclasses which are not also subclasses of \texttt{Decl *}:
\begin{itemize}
\item \texttt{ClosureExpr}.
\item \texttt{FileUnit} and its various subclasses, such as \texttt{SourceFile}.
\item A few other less interesting ones found in the source.
\end{itemize}
Utilities for understanding the nesting of declaration contexts:
\begin{itemize}
\item \texttt{getAsDecl()} if declaration context is also a declaration, returns the declaration, otherwise returns \texttt{nullptr}.
\item \texttt{getParent()} returns the parent declaration context.
\item \texttt{isModuleScopeContext()} returns true if this is a \texttt{ModuleDecl} or \texttt{FileUnit}.
\item \texttt{isTypeContext()} returns true if this is a nominal type declaration or an extension.
\item \texttt{isLocalContext()} returns true if this is not a module scope context or type context.
\item \texttt{getParentModule()} returns the module declaration at the root of the hierarchy.
\item \texttt{getModuleScopeContext()} returns the innermost parent which is a \texttt{ModuleDecl} or \texttt{FileUnit}.
\item \texttt{getParentSourceFile()} returns the innermost parent which is a source file, or \texttt{nullptr} if this declaration context was not parsed from source.
\item \texttt{getInnermostDeclarationDeclContext()} returns the innermost parent which is also a declaration, or \texttt{nullptr}.
\item \texttt{getInnermostDeclarationTypeContext()} returns the innermost parent which is also a nominal type or extension, or \texttt{nullptr}.
\end{itemize}
Operations on type contexts:
\begin{itemize}
\item \texttt{getSelfNominalDecl()} returns the nominal type declaration if this is a type context, or \texttt{nullptr}.
\item \texttt{getSelfStructDecl()} as above but result is a \texttt{StructDecl *} or \texttt{nullptr}.
\item \texttt{getSelfEnumDecl()} as above but result is a \texttt{EnumDecl *} or \texttt{nullptr}.
\item \texttt{getSelfClassDecl()} as above but result is a \texttt{ClassDecl *} or \texttt{nullptr}.
\item \texttt{getSelfProtocolDecl()} as above but result is a \texttt{ProtocolDecl *} or \texttt{nullptr}.
\item \texttt{getDeclaredInterfaceType()} delegates to the method on \texttt{NominalTypeDecl} or \texttt{ExtensionDecl} as appropriate.
\item \texttt{getSelfInterfaceType()} is similar.
\end{itemize}
Generic parameters and requirements:
\begin{itemize}
\item \texttt{isGenericContext()} answers true if either this generic context or one of its parents has a generic parameter list.
\item \texttt{isInnermostContextGeneric()} answers if this declaration context itself has a generic parameter list. Compare with \texttt{isGenericContext()}.
\end{itemize}
\subsection*{Generic Contexts}
Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/GenericParamList.h}
\item \SourceFile{include/swift/AST/Requirement.h}
\item \SourceFile{lib/AST/GenericParamList.cpp}
\item \SourceFile{lib/AST/NameLookup.cpp}
\item \SourceFile{lib/AST/Requirement.cpp}
\end{itemize}
\IndexSource{generic context}
\IndexSource{generic declaration}
\IndexSource{parsed generic parameter list}
\apiref{GenericContext}{class}
Subclass of \texttt{DeclContext}. Base class for declaration kinds which can have a generic parameter list. See also \SecRef{genericsigsourceref}.
\begin{itemize}
\item \texttt{getParsedGenericParams()} returns the declaration's parsed generic parameter list, or \texttt{nullptr}.
\item \texttt{getGenericParams()} returns the declaration's full generic parameter list, which includes any implicit generic parameters. Evaluates a \texttt{GenericParamListRequest}.
\item \texttt{isGeneric()} answers if this declaration has a generic parameter list. This is equivalent to calling \texttt{DeclContext::isInnermostContextGeneric()}. Compare with \texttt{DeclContext::isGenericContext()}.
\item \texttt{getGenericContextDepth()} returns the \IndexSource{depth}depth of the declaration's generic parameter list, or \texttt{(unsigned)-1} if neither this declaration nor any outer declaration is generic.
\item \texttt{getTrailingWhereClause()} returns the declaration's trailing \texttt{where} clause, or \texttt{nullptr}.
\end{itemize}
Trailing \texttt{where} clauses are not preserved in serialized generic contexts. Most code should look at \texttt{GenericContext::getGenericSignature()} instead (\SecRef{genericsigsourceref}), except when actually building the generic signature.
\IndexSource{generic parameter list}
\apiref{GenericParamList}{class}
A generic parameter list.
\begin{itemize}
\item \texttt{getParams()} returns an array of generic parameter declarations.
\item \texttt{getOuterParameters()} returns the outer generic parameter list, linking multiple generic parameter lists for the same generic context. Only used for extensions of nested generic types.
\end{itemize}
\IndexSource{protocol Self type@protocol \tSelf\ type}
\apiref{GenericParamListRequest}{class}
This \IndexSource{generic parameter list request}request creates the full generic parameter list for a declaration. Kicked off from \texttt{GenericContext::getGenericParams()}.
\begin{itemize}
\item For protocols, this creates the implicit \tSelf\ parameter.
\item For functions and subscripts, calls \texttt{createOpaqueParameterGenericParams()} to walk the formal parameter list and look for \texttt{OpaqueTypeRepr}s.
\item For extensions, calls \texttt{createExtensionGenericParams()} which clones the generic parameter lists of the extended nominal itself and all of its outer generic contexts, and links them together via \texttt{GenericParamList::getOuterParameters()}.
\end{itemize}
\IndexSource{generic parameter declaration}
\apiref{GenericTypeParamDecl}{class}
A generic parameter declaration.
\begin{itemize}
\item \IndexSource{depth}\texttt{getDepth()} returns the depth of the generic parameter declaration.
\item \IndexSource{index}\texttt{getIndex()} returns the index of the generic parameter declaration.
\item \texttt{getName()} returns the name of the generic parameter declaration.
\item \texttt{getDeclaredInterfaceType()} returns the \IndexSource{sugared type}sugared generic parameter type for this declaration, which prints as the generic parameter's name.
\item \texttt{isOpaque()} answers if this generic parameter is associated with an \IndexSource{opaque parameter}opaque parameter.
\item \texttt{getOpaqueTypeRepr()} returns the associated \texttt{OpaqueReturnTypeRepr} if this is an opaque parameter, otherwise \texttt{nullptr}.
\item \texttt{getInherited()} returns the generic parameter declaration's \IndexSource{inheritance clause!generic parameter declaration}inheritance clause.
\end{itemize}
Inheritance clauses are not preserved in serialized generic parameter declarations. Requirements stated on generic parameter declarations are part of the corresponding generic context's generic signature, so except when actually building the generic signature, most code uses \texttt{GenericContext::getGenericSignature()} instead (\SecRef{genericsigsourceref}).
\apiref{GenericTypeParamType}{class}
A \IndexSource{generic parameter type}generic parameter type.
\begin{itemize}
\item \texttt{getDepth()} returns the depth of the generic parameter declaration.
\item \texttt{getIndex()} returns the index of the generic parameter declaration.
\item \texttt{getName()} returns the name of the generic parameter declaration if this is the sugared form, otherwise returns a string of the form ``\ttgp{d}{i}''.
\end{itemize}
\IndexSource{where clause@\texttt{where} clause}
\apiref{TrailingWhereClause}{class}
The syntactic representation of a trailing \texttt{where} clause.
\begin{itemize}
\item \texttt{getRequirements()} returns an array of \texttt{RequirementRepr}.
\end{itemize}
\IndexSource{requirement representation}
\apiref{RequirementRepr}{class}
The syntactic representation of a requirement in a trailing \texttt{where} clause.
\begin{itemize}
\item \texttt{getKind()} returns a \texttt{RequirementReprKind}.
\item \texttt{getFirstTypeRepr()} returns the first \texttt{TypeRepr} of a same-type requirement.
\item \texttt{getSecondTypeRepr()} returns the second \texttt{TypeRepr} of a same-type requirement.
\item \texttt{getSubjectTypeRepr()} returns the first \texttt{TypeRepr} of a constraint or layout requirement.
\item \texttt{getConstraintTypeRepr()} returns the second \texttt{TypeRepr} of a constraint requirement.
\item \texttt{getLayoutConstraint()} returns the layout constraint of a layout requirement.
\end{itemize}
\apiref{RequirementReprKind}{enum class}
\begin{itemize}
\item \texttt{RequirementRepr::TypeConstraint}
\item \texttt{RequirementRepr::SameType}
\item \texttt{RequirementRepr::LayoutConstraint}
\end{itemize}
\apiref{WhereClauseOwner}{class}
Represents a reference to some set of requirement representations which can be resolved to requirements, for example a trailing \texttt{where} clause. This is used by various requests, such as the \texttt{RequirementRequest} below, and the \texttt{InferredGenericSignatureRequest} in \SecRef{buildinggensigsourceref}.
\begin{itemize}
\item \texttt{getRequirements()} returns an array of \texttt{RequirementRepr}.
\item \texttt{visitRequirements()} resolves each requirement representation and invokes a callback with the \texttt{RequirementRepr} and resolved \texttt{Requirement}.
\end{itemize}
\apiref{RequirementRequest}{class}
Request which can be evaluated to resolve a single requirement representation in a \texttt{WhereClauseOwner}. Used by \texttt{WhereClauseOwner::visitRequirements()}.
\IndexSource{protocol declaration}
\IndexSource{primary associated type}
\apiref{ProtocolDecl}{class}
A protocol declaration.
\begin{itemize}
\item \texttt{getTrailingWhereClause()} returns this protocol \IndexSource{where clause@\texttt{where} clause!protocol declaration}\texttt{where} clause, or \texttt{nullptr}.
\item \texttt{getAssociatedTypes()} returns an array of all associated type declarations in this protocol.
\item \texttt{getPrimaryAssociatedTypes()} returns an array of all primary associated type declarations in this protocol.
\item \texttt{getInherited()} returns this protocol's \IndexSource{inheritance clause!protocol declaration}inheritance clause.
\end{itemize}
Trailing \texttt{where} clauses and inheritance clauses are not preserved in serialized protocol declarations. Except when actually building the requirement signature, most code uses \texttt{ProtocolDecl::getRequirementSignature()} instead (\SecRef{genericsigsourceref}).
The last four utility methods operate on the requirement signature, so are safe to use on deserialized protocols:
\begin{itemize}
\item \texttt{getInheritedProtocols()} returns an array of all protocols directly \IndexSource{inherited protocol}inherited by this protocol, computed from the inheritance clause.
\item \texttt{inheritsFrom()} determines if this protocol inherits from the given protocol, possibly transitively.
\item \texttt{getSuperclassDecl()} returns the protocol's superclass declaration.
\end{itemize}
\apiref{AssociatedTypeDecl}{class}
An \IndexSource{associated type declaration}associated type declaration.
\begin{itemize}
\item \texttt{getTrailingWhereClause()} returns this associated type's trailing \IndexSource{where clause@\texttt{where} clause!associated type declaration}\texttt{where} clause, or \texttt{nullptr}.
\item \texttt{getInherited()} returns this associated type's \IndexSource{inheritance clause!associated type declaration}inheritance clause.
\end{itemize}
Trailing \texttt{where} clauses and inheritance clauses are not preserved in serialized associated type declarations. Requirements on associated types are part of a protocol's requirement signature, so except when actually building the requirement signature, most code uses \texttt{ProtocolDecl::getRequirementSignature()} instead (\SecRef{genericsigsourceref}).
\subsection*{Function Declarations}
\IndexSource{function declaration}
\IndexSource{method self parameter}
\apiref{AbstractFunctionDecl}{class}
Base class of function-like declarations. Also a \texttt{DeclContext}.
\begin{itemize}
\item \texttt{getImplicitSelfDecl()} returns the implicit \texttt{self} parameter, if there is one.
\item \texttt{getParameters()} returns the function's parameter list.
\item \texttt{getMethodInterfaceType()} returns the type of a method without the \tSelf\ clause.
\item \texttt{getResultInterfaceType()} returns the return type of this function or method.
\end{itemize}
\apiref{ParameterList}{class}
The parameter list of \texttt{AbstractFunctionDecl}, \texttt{EnumElementDecl} or \texttt{SubscriptDecl}.
\begin{itemize}
\item \texttt{size()} returns the number of parameters.
\item \texttt{get()} returns the \texttt{ParamDecl} at the given index.
\end{itemize}
\IndexSource{constructor declaration}
\apiref{ConstructorDecl}{class}
Constructor declarations.
\begin{itemize}
\item \texttt{getInitializerInterfaceType()} returns the initializer interface type, used when type checking \texttt{super.init()} delegation.
\end{itemize}
\subsection*{Closure Conversion}
Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/CaptureInfo.h}
\item \SourceFile{include/swift/SIL/TypeLowering.h}
\item \SourceFile{lib/AST/CaptureInfo.cpp}
\item \SourceFile{lib/Sema/TypeCheckCaptures.cpp}
\item \SourceFile{lib/SIL/IR/TypeLowering.cpp}
\end{itemize}
\IndexSource{captured value}
\IndexSource{closure conversion}
\apiref{CaptureInfo}{class}
An immutable list of captured values.
\apiref{CaptureInfoRequest::evaluate}{method}
Computes the \texttt{CaptureInfo}. This is \AlgRef{closure captures algorithm}.
\apiref{TypeLowering::getLoweredLocalCaptures()}{method}
Computes the lowered \texttt{CaptureInfo}. This is \AlgRef{lowered closure captures algorithm}.
\subsection*{Storage Declarations}
\IndexSource{storage declaration}
\apiref{AbstractStorageDecl}{class}
Base class for storage declarations.
\begin{itemize}
\item \texttt{getValueInterfaceType()} returns the type of the stored value, without \texttt{weak} or \texttt{unowned} storage qualifiers.
\end{itemize}
\IndexSource{variable declaration}
\IndexSource{property declaration}
\IndexSource{local variable declaration}
\apiref{VarDecl}{class}
Subclass of \texttt{AbstractStorageDecl}.
\IndexSource{subscript declaration}
\apiref{SubscriptDecl}{class}
Subclass of \texttt{AbstractStorageDecl} and \texttt{DeclContext}.
\end{document}