forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.tex
953 lines (743 loc) · 73.7 KB
/
types.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
\documentclass[../generics]{subfiles}
\begin{document}
\chapter{Types}\label{types}
\lettrine{R}{easoning about types} is a central concern in the implementation of a statically typed language. In Swift, various syntactic forms such as \texttt{Int}, \texttt{Array<String>} and \texttt{(Bool) -> ()} denote references to types. A \index{type representation}\emph{type representation} is the syntactic form of a type annotation written in source, as constructed by the parser. A \IndexDefinition{type}\emph{type} is a higher-level semantic object. Types are constructed from type representations by \index{type}\emph{type resolution}. They can also be built and taken apart directly.
\medskip
\begin{wrapfigure}[13]{l}{5.5cm}
\begin{center}
\textbf{A type representation:}
\end{center}
\begin{tikzpicture}
\node (ArrayInt) [type] {\texttt{Array<Int>}};
\node (Int) [type,below=of ArrayInt] {\texttt{\vphantom{y}Int}};
\node (ArrayId) [decl,right=of ArrayInt] {``\texttt{Array}''};
\node (IntId) [decl,below=of ArrayId] {``\texttt{\vphantom{y}Int}''};
\draw [arrow] (ArrayInt) -- (ArrayId);
\draw [arrow] (Int) -- (IntId);
\draw [arrow] (ArrayInt) -- (Int);
\begin{scope}[on background layer]
\node (Foo)[fit=(ArrayId) (IntId), inner sep=5pt, rounded corners, draw=gray, dashed] {};
\end{scope}
\node (Label) [below=of Foo] {identifiers};
\draw [arrow, thick] (Label) -- (Foo);
\end{tikzpicture}
\end{wrapfigure}
Suppose the text ``\texttt{Array<Int>}'' appears in a valid position of the language grammar. First, the \index{lexer}lexer splits the input text into a tokens: ``\texttt{Array}'', ``\texttt{<}'', ``\texttt{Int}'', and ``\texttt{>}''. The \index{parser}parser inspects each token and builds a type representation.
The parsed type representation \texttt{Array<Int>} has a \index{tree}tree structure, combining the identifier ``\texttt{Array}'' with the type representation \texttt{Int}. The latter is a leaf node just storing an identifier. As syntactic objects, type representations only store identifiers, which bear no relation to actual type declarations. The ``shape'' of a tree node is determined by the type representation's \IndexDefinition{type representation kind}\emph{kind}, corresponding to syntactic productions.
\medskip
\begin{wrapfigure}[13]{r}{6.5cm}
\begin{center}
\textbf{A type:}
\end{center}
\begin{tikzpicture}
\node (ArrayInt) [type] {\texttt{Array<Int>}};
\node (Int) [type,below=of ArrayInt] {\texttt{\vphantom{y}Int}};
\node (ArrayDecl) [decl,right=of ArrayInt] {\texttt{struct Array}};
\node (IntDecl) [decl,below=of ArrayDecl] {\texttt{\vphantom{y}struct Int}};
\draw [arrow] (ArrayInt) -- (ArrayDecl);
\draw [arrow] (Int) -- (IntDecl);
\draw [arrow] (ArrayInt) -- (Int);
\begin{scope}[on background layer]
\node[fit=(ArrayDecl) (IntDecl), inner sep=5pt, rounded corners, draw=gray, dashed] {};
\end{scope}
\node (Label) [below=of Foo] {type declarations};
\draw [arrow, thick] (Label) -- (Foo);
\end{tikzpicture}
\end{wrapfigure}
Type resolution calls upon name lookup to find type declarations for \texttt{Array} and \texttt{Int}, and validates the generic arguments, to produce a semantic type object.
The generic nominal type \texttt{Array<Int>} points at the \texttt{Array} type declaration, and contains a child node for its generic argument, which is the type \texttt{Int}. The latter type also points at the declaration of \texttt{Int}, and not just an identifier.
Types are categorized by \IndexDefinition{type kind}\emph{kind}, just like type representations. Each kind has a constructor operation to form a new type from \IndexDefinition{structural components}\emph{structural components}, and corresponding operations to take an existing type apart.
\paragraph{Categorization by kind.}
Type representation kinds are given by various productions in the grammar, such as identifiers, function type representations ``\texttt{(Int) -> ()}'', tuple type representations ``\texttt{(Bool, String)}'', and so on. The latter two correspond directly to function types and tuple types, but type kinds are more fine-grained in general, as we can see if we consider identifier type representations. An identifier type representation ``\texttt{Element}'' can resolve to one of several kinds of types; we consider a few now.
\begin{wrapfigure}[6]{r}{4cm}
\begin{tikzpicture}
\node (Element) [type, rectangle split, rectangle split parts=2] {\texttt{Element}\nodepart{two}nominal type};
\node (Decl) [decl, rectangle split, rectangle split parts=2, below=of Element] {\texttt{struct Element}\nodepart{two}\vphantom{y}nominal declaration};
\draw [arrow] (Element) -- (Decl);
\end{tikzpicture}
\end{wrapfigure}
\medskip
One possibility is that the identifier names a nominal type declaration. In this case, the resolved type is a \textbf{nominal type} pointing at this declaration.
\medskip
\noindent
\begin{minipage}{26.5em}
\begin{Verbatim}
struct Element {...}
var x: Element
\end{Verbatim}
\end{minipage}
\medskip
The type checker can then perform further qualified lookups to find members of ``\texttt{x}'', query the stored properties of the struct to determine its layout, and so on.
\begin{wrapfigure}[4]{l}{4.8cm}
\begin{tikzpicture}
\node (Element) [type, rectangle split, rectangle split parts=4] {\texttt{Element}\nodepart{two}generic parameter type\nodepart{three}depth 0\nodepart{four}\vphantom{p}index 0};
\end{tikzpicture}
\end{wrapfigure}
\medskip
The identifier might instead name a generic parameter from an outer scope, in which case the resolved type is a \index{generic parameter type}\textbf{generic parameter type}.
\medskip
\noindent
\begin{minipage}{24.5em}
\begin{Verbatim}
struct Container<Element> {
var x: Element
}
\end{Verbatim}
\end{minipage}
\medskip
Generic parameters are declared in a generic parameter list attached to a declaration. They are scoped to the body of this declaration, and can be uniquely identified by a pair of integers, the \emph{depth} and \emph{index}. Generic parameter types can also store a name, but the name only has significance when printed in diagnostics.
\medskip
\begin{wrapfigure}[8]{r}{3cm}
\begin{tikzpicture}
\node (Element) [type, rectangle split, rectangle split parts=2] {\texttt{Element}\nodepart{two}type alias type};
\node (Int) [type, rectangle split, rectangle split parts=2, below=of Element] {\texttt{Int}\nodepart{two}nominal type};
\draw [arrow] (Element) -- (Int);
\end{tikzpicture}
\end{wrapfigure}
Yet another possibility is that the identifier names a type alias declaration. In this case, a special \textbf{type alias type} is returned, which wraps the \emph{underlying type} \texttt{Int}. It behaves like \texttt{Int} in all ways, except that it can be printed back as ``\texttt{Element}''.
\medskip
\noindent
\begin{minipage}{29em}
\begin{Verbatim}
typealias Element = Int
var x: Element
\end{Verbatim}
\end{minipage}
\medskip
Outside of type resolution, type representations do not play a big role in the compiler, so we punt on the topic of type representations until Chapter~\ref{typeresolution} and just focus on types for now. For our current purposes, it suffices to say that type resolution is really just one possible mechanism by which types are constructed. The expression checker builds types by solving a constraint system, and the generics system builds types via substitution, to give two examples.
\paragraph{Structural components.} A type is constructed from structural components, which may either be other types, or non-type information. Common examples include: nominal types, which consist of a pointer to a declaration, together with a list of \index{generic argument}generic argument types; \index{tuple type}tuple types, which have element types and labels; and \index{function type}function types, which contain parameter types, return types, and various additional bits like \texttt{@escaping} and \texttt{inout}. We will give a full accounting of all type kinds and their structural components in the second half of this chapter.
Once created, types are immutable. To say that a type \emph{contains} another type means that the latter appears as a structural component of the former, perhaps nested several levels deep. We will often talk about \emph{replacing} a type contained by another type. This is understood as constructing a new type with the same kind as the original type, preserving all structural components except for the one being replaced. The original type is never mutated directly.
More generally, types can be transformed by taking the type apart by kind, recursively transforming each structural component, and forming a new type of the same kind from the new components. To preview Chapter~\ref{substmaps}, if \texttt{Element} is a generic parameter type, the type \texttt{Array<Int>} can be formed from \texttt{Array<Element>} by replacing \texttt{Element} with \texttt{Int}; this is called \emph{type substitution}. The compiler provides various utilities to simplify the task of implementing recursive walks and transformations over kinds of types; type substitution is one example of such a transformation.
\paragraph{Canonical types.} It is possible for two types to differ by their spelling, and yet be equivalent semantically:
\begin{itemize}
\item The Swift language defines some shorthands for common types, such as \texttt{T?} for \texttt{Optional<T>}, \texttt{[T]} for \texttt{Array<T>}, and \texttt{[K:\ V]} for \texttt{Dictionary<K, V>}.
\item \index{type alias declaration}Type alias declarations introduce a new name for some existing underlying type, equivalent to writing out the \index{underlying type}underlying type in place of the type alias. The standard library, for example, declares a type alias \IndexDefinition{Void type@\texttt{Void} type}\texttt{Void} with underlying type \texttt{()}.
\item Another form of fiction along these lines is the preservation of generic parameter names. \index{generic parameter type}Generic parameter types written in source have a name, like ``\texttt{Element},'' and should be printed back as such in diagnostics, but internally they are uniquely identified in their generic signature by a pair of integers, the \index{depth}depth and the \index{index}index. This is detailed in Chapter~\ref{generic declarations}.
\end{itemize}
These constructions are the so-called \IndexDefinition{sugared type}\emph{sugared types}. A sugared type has a desugaring into a more primitive form in terms of its structural components. The compiler constructs type sugar in \index{type resolution}type resolution, and attempts to preserve it as much as possible when transforming types. Preserving sugar in diagnostics can be especially helpful with more complex type aliases and such.
A \IndexDefinition{canonical type}\emph{canonical type} is a type that does not recursively contain any sugared types. Type sugar has no semantic effect, for the most part. For example, it would not make sense to define two overloads of the same function that only differ by sugared types. For this reason, many operations on types compute the canonical type first to avoid having to consider sugared types in case analysis. After type checking, compiler passes such as \index{SILGen}SILGen and \index{IRGen}IRGen only deal with canonical types. The Swift runtime reifies canonical types as \index{runtime type metadata}runtime type metadata.
The compiler can transform an arbitrary type into a canonical type by the process of \emph{canonicalization}, which recursively replaces sugared types with their desugared form; in this way, \texttt{[(Int?, Void)]} becomes \verb|Array<(Optional<Int>, ())>|. This operation is very cheap; each type caches a pointer to its canonical type, which is computed as needed (so types are not completely immutable, as we said previously; but the mutability cannot be observed from outside).
One notable exception where the type checker does depend on type sugar is the rule for default initialization of variables: if the variable's type is declared as the sugared optional type \texttt{T?} for some \texttt{T}, the variable's \index{initial value expression}initial value \index{expression}expression is assumed to be \texttt{nil} if none was provided. Spelling the type as \texttt{Optional<T>} avoids the default initialization behavior:
\begin{Verbatim}
var x: Int?
print(x) // prints `nil'
var y: Optional<Int>
print(y) // error: use of uninitialized variable `y'
\end{Verbatim}
Another exception is \index{requirement inference}requirement inference with a \index{generic type alias}generic type alias (Section~\ref{requirementinference}).
\paragraph{Type equality.} Types are uniquely allocated, which is made possible by them being immutable. A type \texttt{(Int) -> ()} has a unique pointer identity within a compilation; inside the tuple type \texttt{((Int) -> (), (Int) -> ())}, the two element types have the same pointer value in memory. From this, three levels of equality are defined on types:
\begin{enumerate}
\item \IndexDefinition{type pointer equality}\textbf{Type pointer equality} checks if two types are exactly equal as trees.
\item \IndexDefinition{canonical type equality}\textbf{Canonical type equality} checks if two types are equal after sugar is removed.
\item \index{reduced type equality}\textbf{Reduced type equality} checks if two types have the same \index{reduced type}reduced type with respect to the same-type requirements of a generic signature.
\end{enumerate}
Each level of equality implies the next, so $(1)\Rightarrow(2)$ and $(2)\Rightarrow(3)$. If both types are canonical, then (1) and (2) coincide; if both are reduced, (1), (2) and (3) all coincide. Type pointer equality is only infrequently used, precisely because it is too strict; we usually do not want to consider two types to be distinct if they only differ by sugar.
\begin{figure}\captionabove{Some examples of type equality}\label{type equality fig}
\begin{tikzpicture}[every fit/.style={rounded corners, draw=gray, dashed}]
\node [matrix, column sep=5em] {
\node (a) [type] {\texttt{Key?}};&&\\
&\node (aa) [type] {\texttt{Optional<\ttgp{0}{0}>}};&\\
\node (b) [type] {\texttt{Optional<Key>}};&&\\
&&\node (aaa) [type] {\texttt{Optional<\ttgp{0}{0}>}};\\
\node (c) [type] {\texttt{Value?}};&&\\
&\node (bb) [type] {\texttt{Optional<\ttgp{0}{1}>}};&\\
\node (d) [type] {\texttt{Optional<Value>}};&&\\
&&\\
};
\begin{scope}[on background layer]
\node (ab) [fit=(a) (b), inner sep=5pt] {};
\node (cd) [fit=(c) (d), inner sep=5pt] {};
\node (aabb) [fit=(aa) (bb), inner sep=5pt] {};
\node (aaaa) [fit=(aaa), inner sep=5pt] {};
\end{scope}
\node (label1) [below=of cd] {sugared types};
\node (label2) [below=of aabb] {canonical types};
\node (label3) [below=of aaaa] {reduced types};
\draw [arrow, thick] (label1) -- (cd);
\draw [arrow, thick] (label2) -- (aabb);
\draw [arrow, thick] (label3) -- (aaaa);
\end{tikzpicture}
\end{figure}
Figure~\ref{type equality fig} demonstrates type equality in the following extension declaration, where the \texttt{Key} (\ttgp{0}{0}) and \texttt{Value} (\ttgp{0}{1}) generic parameters of \texttt{Dictionary} are declared equivalent with a same-type requirement:
\begin{Verbatim}
extension Dictionary where Key == Value {
func foo(a: Key?, b: Optional<Key>, c: Value?, d: Optional<Value>) {}
}
\end{Verbatim}
Consider the four types \texttt{Key?}, \texttt{Optional<Key>}, \texttt{Value?}, and \texttt{Optional<Value>}:
\begin{itemize}
\item All four are distinct under type pointer equality.
\item The first two have the canonical type \texttt{Optional<\ttgp{0}{0}>}. Thus, the first two are equal under canonical type equality.
\item The last two have the canonical type \texttt{Optional<\ttgp{0}{1}>}. Again, they are equal to each other under canonical type equality (but distinct from the first two).
\item When we consider the generic signature of the extension, we're left with just one reduced type, because both canonical types reduce to \texttt{Optional<\ttgp{0}{0}>} via the same-type requirement. Thus, all four of the original types are equal under reduced type equality.
\end{itemize}
Intuitively, reduced type equality means ``equivalent as a consequence of one or more same-type requirements.'' In Section~\ref{derived req} we make this notion precise via the derived requirements formalism, and then define reduced type equality in Section~\ref{reducedtypes}. Presenting a computable algorithm for finding reduced types is one of the overarching goals of this book; key developments take place in Section~\ref{rewritesystemintro} and Chapter~\ref{symbols terms rules}.
\section{Fundamental Types}\label{fundamental types}
We've looked at some behaviors of types in general, and informally introduced a few kinds. We now give a full accounting of all kinds of types, starting from those most important from the point of view of the generics implementation.
\paragraph{Nominal types.}
A \IndexDefinition{nominal type}\emph{nominal type} is declared by a non-generic \IndexDefinition{struct type}struct, \IndexDefinition{enum type}enum or \IndexDefinition{class type}class declaration, such as \texttt{Int}. A \IndexDefinition{generic nominal type}\emph{generic nominal type} is declared by a generic struct, enum or class declaration. They have these structural components:
\begin{itemize}
\item A pointer to the \index{nominal type declaration}nominal type declaration.
\item A \index{parent type}parent type, if the nominal type declaration is nested inside of another nominal type declaration.
\item A list of \index{generic arguments}generic arguments, if the nominal type declaration is generic.
\end{itemize}
\begin{wrapfigure}[9]{r}{5cm}
\begin{center}\textbf{Nominal type nesting}\end{center}
\begin{tikzpicture}
\node (Inner) [type] {\texttt{Outer<Float>.Inner}};
\node (Outer) [type, below=of Inner] {\texttt{Outer<Float>}};
\node (Float) [type, below=of Outer] {\texttt{Float}};
\draw [arrow] (Inner) -- (Outer) node[midway, left] {\scriptsize{parent type}};
\draw [arrow] (Outer) -- (Float) node[midway, left] {\scriptsize{generic argument}};
\end{tikzpicture}
\end{wrapfigure}
The parent type records the generic arguments of outer nominal type declarations. For example, with the below declarations, we can form the nominal type \texttt{Outer<Float>.Inner}:
\medskip
\noindent
\begin{minipage}{24em}
\begin{Verbatim}
struct Outer<T> {
struct Inner {}
}
\end{Verbatim}
\end{minipage}
\medskip
A nominal type declaration defines a family of nominal types, all sharing the same declaration and parent type structure, but having different generic arguments. Each of these types is a \index{specialized type}\emph{specialized type} of the nominal type declaration.
\begin{wrapfigure}[13]{l}{5cm}
\begin{center}\textbf{Declared interface type}\end{center}
\begin{tikzpicture}
\node (Inner) [type] {\texttt{Outer<\ttgp{0}{0}>.Inner}};
\node (Outer) [type, below=of Inner] {\texttt{Outer<\ttgp{0}{0}>}};
\node (Float) [type, below=of Outer] {\texttt{\ttgp{0}{0}}};
\draw [arrow] (Inner) -- (Outer) node[midway, left] {\scriptsize{parent type}};
\draw [arrow] (Outer) -- (Float) node[midway, left] {\scriptsize{generic argument}};
\end{tikzpicture}
\end{wrapfigure}
\smallskip
The specialized type where each generic argument is set to the corresponding generic parameter type is the \index{declared interface type}\emph{declared interface type} of the nominal type declaration. It is ``universal'': any specialized type is obtainable from the declared interface type by assigning a replacement type to each generic parameter type. This assignment is known as a \index{substitution map}\emph{substitution map}, and the substitution map defined by the generic arguments of a specialized type is its \index{context substitution map}\emph{context substitution map} (Section~\ref{contextsubstmap}). Finally, in the case where neither the nominal type declaration nor any of its parents are generic, the declaration defines just one \index{fully concrete type}\emph{fully concrete} specialized type, with an empty context substitution map.
\begin{figure}[b!]\captionabove{Bound and unbound dependent member types}\label{type params fig}
\begin{center}
\begin{tabular}{c@{\hskip 2em}c}
\begin{tikzpicture}
\node (tab) [type] {\texttt{\strut \ttgp{0}{0}.[P]A.[Q]B}};
\node (ta) [type,below=of tab] {\texttt{\strut \ttgp{0}{0}.[P]A}};
\node (t) [type,below=of ta] {\texttt{\strut \ttgp{0}{0}}};
\node (b) [decl,right=of tab] {\texttt{\strut associatedtype B}};
\node (a) [decl,below=of b] {\texttt{\strut associatedtype A}};
\draw [arrow] (tab) -- (ta) node[midway, left] {\scriptsize{base type}};
\draw [arrow] (ta) -- (t) node[midway, left] {\scriptsize{base type}};
\draw [arrow] (tab) -- (b);
\draw [arrow] (ta) -- (a);
\begin{scope}[on background layer]
\node (Foo) [draw=gray, dashed, rounded corners, fit=(a) (b), inner sep=5pt] {};
\end{scope}
\node (Label) [below=of Foo, yshift=-20] {\strut associated type declarations};
\draw [arrow, thick] (Label) -- (Foo);
\end{tikzpicture}&
\begin{tikzpicture}
\node (tab) [type] {\texttt{\strut \ttgp{0}{0}.A.B}};
\node (ta) [type,below=of tab] {\texttt{\strut \ttgp{0}{0}.A}};
\node (t) [type,below=of ta] {\texttt{\strut \ttgp{0}{0}}};
\node (b) [decl,right=of tab] {``\texttt{\strut B}''};
\node (a) [decl,below=of b] {``\texttt{\strut A}''};
\draw [arrow] (tab) -- (ta) node[midway, left] {\scriptsize{base type}};
\draw [arrow] (ta) -- (t) node[midway, left] {\scriptsize{base type}};
\draw [arrow] (tab) -- (b);
\draw [arrow] (ta) -- (a);
\begin{scope}[on background layer]
\node (Foo) [draw=gray, dashed, rounded corners, fit=(a) (b), inner sep=5pt] {};
\end{scope}
\node (Label) [below=of Foo, yshift=-20] {\strut identifiers};
\draw [arrow, thick] (Label) -- (Foo);
\end{tikzpicture}
\end{tabular}
\end{center}
\end{figure}
\paragraph{Generic parameter types.} Conceptually, a \IndexDefinition{generic parameter type}generic parameter type abstracts over a generic argument provided by the caller. Generic parameter types are declared by \index{generic parameter declaration}generic parameter declarations. The sugared form references the declaration, and prints as the declaration's name; the canonical form only stores a depth and an index. Care must be taken not to print canonical generic parameter types in diagnostics, to avoid surfacing the ``\ttgp{1}{2}'' notation to the user. (Section~\ref{genericsigsourceref} shows a trick to transform a canonical generic parameter type back into its sugared form using a generic signature.)
\paragraph{Dependent member types.}
A \IndexDefinition{dependent member type}dependent member type abstracts over a concrete type that fulfills an associated type requirement. There are two structural components:
\begin{itemize}
\item A base type, which is a generic parameter type or another dependent member type.
\item An \index{identifier}identifier (in which case this is an \IndexDefinition{unbound dependent member type}\emph{unbound} dependent member type), or an \index{associated type declaration}associated type declaration (in which case it is \IndexDefinition{bound dependent member type}\emph{bound}).
\end{itemize}
Unbound dependent member types fit in somewhere in between type representations and ``true'' types, in that they are a syntactic construct. They appear in the \index{structural resolution stage}structural resolution stage when building a generic signature. Most type resolution happens in the \index{interface resolution stage}interface resolution stage, after a generic signature is available, and thus dependent member types appearing in the interface types of declarations are always bound.
If \ttbf{T} is the base type, \texttt{P} is a protocol and \texttt{A} is an associated type declared inside this protocol, we denote the bound dependent member type by \texttt{\textbf{T}.[P]A}, and the unbound dependent member type by \texttt{\textbf{T}.A}. The base type \ttbf{T} may be another dependent member type, so we can have a series of member type accesses, like \texttt{\ttgp{0}{0}.[P]A.[Q]B}. Figure~\ref{type params fig} shows the recursive structure of two dependent member types, bound and unbound.
A dependent member type is ``dependent'' in the C++ sense, \emph{not} a \index{dependent type}type dependent on a value in the \index{lambda cube}``lambda cube'' sense. Generic parameter types and dependent member types are together known as \emph{type parameters}. A type that might contain type parameters but is not necessarily a type parameter itself is called an \IndexDefinition{interface type}\emph{interface type}. The above summary necessarily leaves many questions unanswered, and understanding the behaviors of type parameters is a recurring theme throughout the book:
\begin{itemize}
\item What it means for a type parameter to be semantically valid (Section~\ref{derived req}).
\item Generic signature queries (Section~\ref{genericsigqueries}).
\item Dependent member type substitution (Section~\ref{abstract conformances} and Chapter~\ref{conformance paths}).
\item Type resolution with bound and unbound type parameters (Section~\ref{typeresolution}).
\end{itemize}
\paragraph{Archetype types.}
Type parameters derive their meaning from the requirements of a generic signature; they are only ``names'' of external entities, in a sense. \IndexDefinition{archetype type}Archetypes are an alternate ``self-describing'' representation. Archetypes are instantiated from a \emph{generic environment}, which stores a generic signature together with other information (Chapter~\ref{genericenv}).
Archetypes occur inside \index{expression}expressions and \index{SIL}SIL instructions. Archetypes also represent references to opaque return types (Section~\ref{opaquearchetype}) and the type of the payload inside of an existential (Section~\ref{open existential archetypes}). In diagnostics, an archetype is printed as the type parameter it represents. We will denote by $\archetype{T}$ the archetype for the type parameter \texttt{T} in some generic environment understood from context. A type that might contain archetypes but is not necessarily an archetype itself is called a \index{contextual type}\emph{contextual type}.
\medskip
The fundamental type kinds we surveyed above---nominal types, type parameters, and archetypes---are \textsl{the Swift types that can conform to protocols}. In other words, they can satisfy the left-hand side of a \index{conformance requirement}conformance requirement, with the details for each type given later in Section~\ref{conformance lookup}. Also important are \index{constraint type}\emph{constraint types}, appearing on the \emph{right hand side} of a conformance requirement. Constraint types themselves are never the types of value-producing expressions. (We will see shortly that type-erased values are represented by an existential type, wrapping a constraint type in a level of indirection.)
\paragraph{Protocol types.}
A protocol type is the most fundamental kind of constraint type; a conformance requirement involving any other kind of constraint type can always be split up into simpler conformance requirements. A \IndexDefinition{protocol type}protocol type is a kind of \index{nominal type}nominal type, so it will have a \index{parent type}parent type if the protocol declaration is nested inside of another nominal type declaration. Unlike other nominal types, protocols cannot be nested in generic contexts (Section~\ref{nested nominal types}), so neither the protocol type itself nor any of its parents can have generic arguments. Thus, there is exactly one protocol type corresponding to each protocol declaration.
\paragraph{Protocol composition types.}
A \IndexDefinition{protocol composition type}protocol composition type is a constraint type with a list of members. On the right hand side of a conformance requirement, protocol compositions \emph{expand} into a series of requirements for each member of the composition (Section~\ref{requirement desugaring}). The members can include protocol types, a class type (at most one), and the \Index{AnyObject@\texttt{AnyObject}}\texttt{AnyObject} layout constraint:
\begin{quote}
\begin{verbatim}
P & Q
P & AnyObject
SomeClass<Int> & P
\end{verbatim}
\end{quote}
\paragraph{Parameterized protocol types.}
A \index{constrained protocol type|see{parameterized protocol type}}\IndexDefinition{parameterized protocol type}parameterized protocol type stores a protocol type together with a list of generic arguments. As a constraint type, it expands into a conformance requirement together with one or more same-type requirements, for each of the protocol's \emph{primary associated types} (Section~\ref{protocols}). The written representation looks just like a generic nominal type, except the named declaration is a protocol, for example, \texttt{Sequence<Int>}. Parameterized protocol types were introduced in Swift 5.7 \cite{se0346} (the evolution proposal calls them ``constrained protocol types'').
\section{More Types}\label{more types}
Now we will look at the various \IndexDefinition{structural type}\emph{structural types} which are part of the language. (Not to be confused with the types produced by the \emph{structural resolution stage}, which is discussed in Chapter~\ref{typeresolution}.)
\begin{wrapfigure}[15]{r}{6.5cm}
\begin{center}
\begin{tikzpicture}
\node (anyPQ) [type, rectangle split, rectangle split parts=2] {\verb|any (P & Q)|\nodepart{two}existential type};
\node (PQ) [type, rectangle split, rectangle split parts=2, below=of anyPQ] {\verb|P & Q|\nodepart{two}protocol composition type};
\node (P) [type, rectangle split, rectangle split parts=2, below=of PQ, xshift=-50] {\texttt{P}\nodepart{two}protocol type};
\node (Q) [type, rectangle split, rectangle split parts=2, below=of PQ, xshift=50] {\texttt{Q}\nodepart{two}protocol type};
\draw [arrow] (anyPQ) -- (PQ) node[midway, left] {\scriptsize{constraint type}};
\draw [arrow] (PQ) -- (P) node[midway, left] {\scriptsize{member}};
\draw [arrow] (PQ) -- (Q) node[midway, right] {\scriptsize{member}};
\end{tikzpicture}
\end{center}
\end{wrapfigure}
\paragraph{Existential types.}
An \index{existential type}existential type has one structural component, the \emph{constraint type}. An existential value is a container for a value with some unknown dynamic type that is known to satisfy the constraint; to the right we show the existential type \verb|any (P & Q)|, which stores a value conforming to both \texttt{P} and \texttt{Q}.
The \texttt{any} keyword was added in Swift~5.6~\cite{se0355}; in \index{history}Swift releases prior, existential types and constraint types were the same concept in the language and implementation. (For the sake of source compatibility, a constraint type without the \texttt{any} keyword still resolves to an existential type except when it appears on the right-hand side of a conformance requirement.)
Existential types are covered in Chapter~\ref{existentialtypes}.
\begin{wrapfigure}[9]{r}{3cm}
\begin{tikzpicture}
\node (IntType) [type, rectangle split, rectangle split parts=2] {\verb|Int.Type|\nodepart{two}metatype type};
\node (Int) [type, rectangle split, rectangle split parts=2, below=of IntType] {\texttt{Int}\nodepart{two}nominal type};
\draw [arrow] (IntType) -- (Int);
\end{tikzpicture}
\end{wrapfigure}
\paragraph{Metatype types.} Types can be used as callees in \index{call expression}call expressions, \texttt{\textbf{T}(...)}; this is shorthand for a constructor invocation \texttt{\textbf{T}.init(...)}. They can serve as the base of a static method call, \texttt{\textbf{T}.foo(...)}, where the type is passed as the \texttt{self} parameter. Finally, types can be directly referenced by the expression \texttt{\textbf{T}.self}. In all cases, the type becomes a \emph{value}, and this value must itself be assigned a type; this type is called a \emph{metatype}. The metatype of a type \ttbf{T} is written as \texttt{\ttbf{T}.Type}. The type \ttbf{T} is the \IndexDefinition{instance type}\emph{instance type} of the metatype. For example, the type of the expression ``\verb|Int.self|'' is the metatype \texttt{Int.Type}, whose instance type is \verb|Int|.
Metatypes are sometimes referred to as \IndexDefinition{concrete metatype type}\emph{concrete metatypes}, to distinguish them from existential metatypes, which we introduce below. Most concrete metatypes are singleton types with one value, the instance type itself. One exception is that the class metatype for a non-final class also has all subclasses of the class as values.
\begin{figure}[b!]\captionabove{Existential metatype and metatype of existential}\label{existential metatype fig}
\begin{center}
\begin{tabular}{m{15em}m{10em}}
\begin{tikzpicture}
\node (PType) [type, rectangle split, rectangle split parts=2] {\verb|any P.Type|\nodepart{two}existential metatype type};
\node (P) [type, rectangle split, rectangle split parts=2, below=of PType] {\texttt{P}\nodepart{two}protocol type};
\draw [arrow] (IntType) -- (Int) node[midway, left] {\scriptsize{constraint type}};
\end{tikzpicture}&
\begin{tikzpicture}
\node (anyPType) [type, rectangle split, rectangle split parts=2] {\verb|(any P).Type|\nodepart{two}metatype type};
\node (anyP) [type, rectangle split, rectangle split parts=2, below=of anyPType] {\texttt{any P}\nodepart{two}existential type};
\node (P) [type, rectangle split, rectangle split parts=2, below=of anyP] {\texttt{P}\nodepart{two}protocol type};
\draw [arrow] (anyPType) -- (anyP) node[midway, left] {\scriptsize{instance type}};
\draw [arrow] (anyP) -- (P) node[midway, left] {\scriptsize{constraint type}};
\end{tikzpicture}
\end{tabular}
\end{center}
\end{figure}
\paragraph{Existential metatype types.}
An \index{existential metatype type}existential metatype is a container for an unknown concrete metatype, whose instance type is known to satisfy the constraint type.
Existential metatypes are not the same as metatypes whose instance type is existential, as we can demonstrate by considering language semantics. If \texttt{P} is a protocol and \texttt{S} is a type conforming to \texttt{P}, then the existential metatype \texttt{any P.Type} can store the value \texttt{S.self}. As the existential type \texttt{any P} does not conform to \texttt{P}, the value \texttt{(any P).self} cannot be stored inside of the existential metatype \texttt{any P.Type}. In fact, the type of this value is the \emph{concrete} metatype \texttt{(any P).Type}. Figure~\ref{existential metatype fig} compares the recursive structure of \texttt{any P.Type} against \texttt{(any P).Type}.
Prior to the introduction of the \texttt{any} keyword, existential metatypes were written as \texttt{P.Type}, and the concrete metatype of an existential as \texttt{P.Protocol}. This was a source of confusion, because for all non-protocol types \ttbf{T}, \texttt{\textbf{T}.Type} is always a concrete metatype. The below table compares the old and new syntax:
\begin{quote}
\begin{tabular}{lll}
\toprule
\textbf{Old syntax}&\textbf{New syntax}&\textbf{Type kind}\\
\midrule
\texttt{(\textbf{T}).Type}&\texttt{(\textbf{T}).Type}&Concrete metatype\\
\texttt{P.Protocol}&\texttt{(any P).Type}&Concrete metatype of existential\\
\texttt{P.Type}&\texttt{any P.Type}&Existential metatype\\
\bottomrule
\end{tabular}
\end{quote}
\begin{wrapfigure}[12]{r}{6cm}
\begin{center}
\begin{tikzpicture}
\node (Tuple) [type, rectangle split, rectangle split parts=3] {\texttt{(x:\ Int, y:\ Float)}\nodepart{two}tuple type\nodepart{three}labels: \texttt{x:y:}};
\node (Int) [type, rectangle split, rectangle split parts=2, below=of Tuple, xshift=-40] {\texttt{Int}\nodepart{two}nominal type};
\node (Float) [type, rectangle split, rectangle split parts=2, below=of Tuple, xshift=40] {\texttt{Float}\nodepart{two}nominal type};
\draw [arrow] (Tuple) -- (Int);
\draw [arrow] (Tuple) -- (Float);
\end{tikzpicture}
\end{center}
\end{wrapfigure}
\paragraph{Tuple types.}
A \IndexDefinition{tuple type}tuple type is a list of element types together with optional labels. If the list of element types is empty, we get the unique empty tuple type \texttt{()}.
An unlabeled one-element tuple type cannot be formed at all; \texttt{(\textbf{T})} resolves to the same type as \ttbf{T}. Labeled one-element tuple types \texttt{(foo:\ \textbf{T})} are valid in the grammar, but are rejected by type resolution. \index{SILGen}SILGen creates them internally when it materializes the payload of an enum case (for instance, ``\texttt{case person(name:\ String)}''), but they do not appear as the types of expressions.
\paragraph{Function types.} A \IndexDefinition{function type}function type is the type of the callee in a \index{call expression}call expression. Consists of a parameter list, a return type, and non-type attributes. The latter includes the function's effect, lifetime, and calling convention. The effects are \texttt{throws} and \texttt{async} (part of the Swift~5.5 concurrency model \cite{se0296}). Function values with non-escaping lifetime are second-class; they can only be passed to another function, captured by a non-escaping closure, or called. Only escaping functions can be returned or stored inside other values. The four calling conventions are:
\begin{itemize}
\item The default ``thick'' convention, where the function is passed as a function pointer together with a reference-counted closure context.
\item \texttt{@convention(thin)}: the function is passed as a single function pointer, without a closure context. Thin functions cannot capture values from outer scopes.
\item \texttt{@convention(c)}: passed as a single function pointer, and also the parameter and return types must be representable in C.
\item \texttt{@convention(block)}: passed as an \index{Objective-C}Objective-C block, which allow captures but must have parameter and return types representable in Objective-C.
\end{itemize}
Each entry in the parameter list contains a parameter type and some non-type bits:
\begin{itemize}
\item The \textbf{value ownership kind}, which can be the default, \texttt{inout}, \texttt{borrowing} or \texttt{consuming}.
The \texttt{inout} kind is key to Swift's mutable value type model; the interested reader can consult \cite{valuesemantics} for details. The last two were introduced in Swift~5.9 \cite{se0377}.
\item The \textbf{variadic} flag, in which case the parameter type must be an array type.
When type checking a call to function value with a variadic parameter, the type checker collects multiple expressions from the call argument list into an implicit array expression. Otherwise, variadic parameters behave exactly like arrays once we get to \index{SILGen}SILGen and below.
\item The \IndexDefinition{autoclosure function type}\texttt{@autoclosure} attribute, in which case the parameter type must be another function type of the form \texttt{() -> \textbf{T}} for some type \ttbf{T}.
This instructs the type checker to treat the corresponding argument in the caller as if it was a value of type \ttbf{T}, rather than a function type \texttt{()~->~\textbf{T}}. The argument is then wrapped inside an implicit \index{closure expression}closure \index{expression}expression. In the body of the callee, an \texttt{@autoclosure} parameter behaves exactly like an ordinary function value, and can be called to evaluate the expression provided by the caller.
\end{itemize}
\begin{figure}[b!]\captionabove{Function type with two parameters, or a single tuple parameter}\label{function param tuple fig}
\begin{center}
\begin{tabular}{m{15em}m{15em}}
\begin{tikzpicture}
\node (Func) [type, rectangle split, rectangle split parts=3] {\verb|(Int, Float) -> Bool|\nodepart{two}function type\nodepart{three}parameters: 2};
\node (Int) [type, below=of Func, xshift=-50] {\texttt{Int}};
\node (Float) [type, below=of Func] {\texttt{Float}};
\node (Bool) [type, below=of Func, xshift=50] {\texttt{Bool}};
\draw [arrow] (Func) -- (Int.north);
\draw [arrow] (Func) -- (Float.north);
\draw [arrow] (Func) -- (Bool.north) node[midway, right] {\,\scriptsize{result}};
\end{tikzpicture}&
\begin{tikzpicture}
\node (Func) [type, rectangle split, rectangle split parts=3] {\verb|((Int, Float)) -> Bool|\nodepart{two}function type\nodepart{three}parameters: 1};
\node (IntFloat) [type, rectangle split, rectangle split parts=2, below=of Func, xshift=-50] {\texttt{(Int, Float)}\nodepart{two}tuple type};
\node (Int) [type, below=of IntFloat, xshift=-25] {\texttt{Int}};
\node (Float) [type, below=of IntFloat, xshift=25] {\texttt{Float}};
\node (Bool) [type, below=of Func, xshift=50] {\texttt{Bool}};
\draw [arrow] (Func) -- (IntFloat.north);
\draw [arrow] (Func) -- (Bool.north) node[midway, right] {\,\scriptsize{result}};
\draw [arrow] (IntFloat) -- (Float.north);
\draw [arrow] (IntFloat) -- (Int.north);
\end{tikzpicture}
\end{tabular}
\end{center}
\end{figure}
In functional languages such as \index{ML}ML and \index{Haskell}Haskell, all function types conceptually take a single parameter type. This is not the case in Swift, however. Figure~\ref{function param tuple fig} illustrates the distinction between \verb|(Int, Float) -> Bool| and \verb|((Int, Float)) -> Bool|; the first has two parameters, and the second has a single parameter that is of tuple type.
For convenience, the type checker defines an implicit conversion, called a \index{tuple splat}``tuple splat,'' between function types taking a single tuple and function types of multiple arguments. This implicit conversion is only available when passing a function value as an argument to a call, and only when the function type's parameter list can be represented as a tuple (hence, it has no parameter attributes). An example:
\begin{Verbatim}
func apply<T, U>(fn: (T) -> U, arg: T) -> U {
return fn(arg)
}
// Tuple splat conversion:
// - the type of (+) is (Int, Int) -> (),
// - but apply() expects ((Int, Int)) -> ().
print(apply(fn: (+), arg: (1, 2)))
\end{Verbatim}
Another subtle point with function types is that \index{argument label}argument labels are part of a function declaration's \emph{name}, not a function declaration's \emph{type}. A closure, being an anonymous function, is always called without argument labels. This includes a \index{expression}\index{closure expression}closure formed from an unapplied reference to a function declaration---even if the function declaration \emph{does} have argument labels:
\begin{Verbatim}
func subtract(minuend x: Int, subtrahend y: Int) -> Int {
return x - y
}
print(subtract(minuend: 3, subtrahend: 1)) // prints 2
let fn1 = subtract // declaration name can omit argument labels
print(fn1(3, 1)) // prints 2
let fn2 = subtract(minuend:subtrahend:) // full declaration name
print(fn2(3, 1)) // prints 2
\end{Verbatim}
The history of Swift function types is an interesting case study in language evolution. Originally, Swift followed the classical functional language model, where a function type always had a \emph{single} parameter type, which could be a tuple type to simulate a function of multiple parameters. Tuple types used to be able to contain \texttt{inout} and variadic elements, and furthermore, the argument labels of a function declaration were part of the function declaration's type. The existence of such ``non-materializable'' tuple types introduced complications throughout the type system, and argument labels had inconsistent behavior in different contexts.
The syntax for referencing a declaration name with argument labels was adopted in \index{history}Swift~2.2~\cite{se0021}. Subsequently, argument labels were dropped from function types in Swift~3~\cite{se0111}. The distinction between a function taking multiple arguments and a function taking a single tuple argument was first hinted at in Swift~3 with \cite{se0029} and \cite{se0066}, and became explicit in Swift~4 \cite{se0110}. At the same time, Swift~4 also introduced the ``tuple splat'' function conversion which simulated the Swift~3 model in a limited way for the cases where the old behavior was convenient. For example, the element type of \texttt{Dictionary} is a key/value tuple, but often it is more convenient to call the \texttt{Collection.map()} method with a closure taking two arguments, and not a closure with a single tuple argument. Even after the above proposals were implemented, the compiler continued to model a function type as having a single input type for quite some time, despite this being completely hidden from the user. After Swift~5, the function type representation fully converged with the semantic model of the language.
\medskip
It is worth noting that metatypes, tuple types and function types play an important role in the core language model, but they are not essential to the formal analysis of generics; one can construct a toy implementation of Swift generics from nominal types and type parameters alone. Indeed, all structural types can be seen as special kinds of type constructors, which have no special behavior other than possibly containing type parameters which can be substituted.
\medskip
We finish this section by turning to sugared types. Sugared generic parameter types were already described in Section~\ref{fundamental types}. Of the remaining kinds of \index{sugared type}sugared types, type alias types are defined by the user, and the other three are built-in to the language.
\paragraph{Type alias types.} A \IndexDefinition{type alias type}type alias type represents a reference to a type alias declaration. It contains an optional parent type, a substitution map, and the substituted \IndexDefinition{underlying type}underlying type. The canonical type of a type alias type is the substituted underlying type. The substitution map is formed in type resolution, from any generic arguments applied to the type alias type declaration itself, together with the generic arguments of the parent type (Section~\ref{identtyperepr}). Type resolution applies this substitution map to the original underlying type of the type alias declaration to compute the substituted underlying type. The substitution map is preserved for printing, and for requirement inference (Section~\ref{requirementinference}).
\paragraph{Optional types.} The \IndexDefinition{optional sugared type}optional type is written as \texttt{\textbf{T}?} for some object type \T; its canonical type is \texttt{Optional<\textbf{T}>}.
\paragraph{Array types.} The \IndexDefinition{array sugared type}array type is written as \texttt{[\textbf{E}]} for some element type \ttbf{E}; its canonical type is \texttt{Array<\textbf{E}>}.
\paragraph{Dictionary types.} The \IndexDefinition{dictionary sugared type}dictionary type is written as \texttt{[\textbf{K}: \textbf{V}]} for some key type \ttbf{K} and value type \ttbf{V}; its canonical type is \texttt{Dictionary<\textbf{K}, \textbf{V}>}.
\section{Sporadic Types}\label{misc types}
Each of the sporadic types (this is not a technical term) is weird in its own unique way. They tend to only be valid in specific contexts, and some do not represent actual types of values at all. Their unexpected appearance can be a source of counter-examples and failed assertions. They all play important roles in the expression type checker, but again, do not really give us anything new if we consider the generics model from a purely formal viewpoint.
\paragraph{Generic function types.}
A \IndexDefinition{generic function type}generic function type has the same structural components as a function type, except it also stores a generic signature:
\begin{quote}
\begin{verbatim}
<S where S: Sequence> (S) -> S.Element
\end{verbatim}
\end{quote}
Generic function types are the \index{interface type}interface types of generic \index{function declaration}function and \index{subscript declaration}subscript declarations. A reference to a generic function declaration from an expression always applies substitutions first, so generic function types do not appear as the types of expressions. In particular, an unsubstituted generic function value cannot be a parameter to another function, thus the Swift type system does not support \index{higher-rank polymorphism}higher-rank polymorphism. Type inference with higher-rank types is known to be \index{halting problem}\index{undecidable problem}undecidable; see \cite{wells} and \cite{practicalhigherrank}.
Generic function types have a special behavior when their canonical type is computed. Since generic function types carry a generic signature, the parameter types and return type of a \emph{canonical} generic function type are actually \emph{reduced} types with respect to this generic signature (Section~\ref{reducedtypes}).
\paragraph{Reference storage types.}
A \IndexDefinition{reference storage type}reference storage type is the type of a variable declaration adorned with the \IndexDefinition{weak reference type}\texttt{weak}, \IndexDefinition{unowned reference type}\texttt{unowned} or \texttt{unowned(unsafe)} attribute. The wrapped type must be a class type, a class-constrained archetype, or class-constrained existential type. Reference storage types arise as the interface types of variable declarations, and as the types of SIL instructions. The types of \index{expression}expressions never contain reference storage types.
\paragraph{Placeholder types.}
A \IndexDefinition{placeholder type}placeholder type represents a generic argument to be inferred by the type checker. The written representation is the underscore ``\texttt{\_}''. They can only appear in a handful of restricted contexts and do not remain after type checking. The expression type checker replaces placeholder types with type variables, solves the constraint system, and finally replaces the type variables with their fixed concrete types. For example, here the interface type of the \texttt{myPets} local variable is inferred as \texttt{Array<String>}:
\begin{Verbatim}
let myPets: Array<_> = ["Zelda", "Giblet"]
\end{Verbatim}
Placeholder types were introduced in Swift 5.6~\cite{se0315}.
\paragraph{Unbound generic types.}
\IndexDefinition{unbound generic type}Unbound generic types predate placeholder types, and can be seen as a special case. An unbound generic type is written as a named reference to a generic type declaration, without generic arguments applied. An unbound generic type behaves like a generic nominal type where all generic arguments are placeholder types. In the example above, the generic nominal type \texttt{Array<\_>} contains a placeholder type. The unbound generic type \texttt{Array} could have been used instead:
\begin{Verbatim}
let myPets: Array = ["Zelda", "Giblet"]
\end{Verbatim}
Unbound generic types are also occasionally useful in diagnostics, to print the name of a type declaration only (like \texttt{Outer.Inner}) without the generic parameters of its declared interface type (\texttt{Outer<T>.Inner<U>}, for example). Unbound generic types are discussed in the context of type resolution in Section~\ref{unbound generic types}.
\begin{listing}\captionabove{Dynamic Self type example}\label{dynamic self example}
\begin{Verbatim}
class Base {
required init() {}
func dynamicSelf() -> Self {
// the type of `self' in a method returning `Self' is
// the dynamic Self type.
return self
}
func clone() -> Self {
return Self()
}
func invalid1() -> Self {
return Base()
}
func invalid2(_: Self) {}
}
class Derived: Base {}
let y = Derived().dynamicSelf() // y has type `Derived'
let z = Derived().clone() // z has type `Derived'
\end{Verbatim}
\end{listing}
\paragraph{Dynamic Self types.}
The \IndexDefinition{dynamic Self type@dynamic \texttt{Self} type}dynamic Self type appears when a class method declares a return type of \texttt{Self}. In this case, the object is known to have the same dynamic type as the base of the method call, which might be a subclass of the method's class. The dynamic Self type has one structural component, a class type, which is the static upper bound for the type. This concept comes from \index{Objective-C}Objective-C, where it is called \texttt{instancetype}. The dynamic Self type in many ways behaves like a generic parameter, but it is not represented as one; the type checker and \index{SILGen}SILGen implement support for it directly. Note that \texttt{Self} only has this interpretation inside a class declaration. In a protocol declaration, \texttt{Self} is the implicit generic parameter (Section~\ref{protocols}). In a struct or enum declaration, \texttt{Self} is the declared interface type (Section~\ref{identtyperepr}).
Listing~\ref{dynamic self example} demonstrates some of the behaviors of the dynamic Self type. Two invalid cases are shown; \texttt{invalid1()} is rejected because the type checker cannot prove that the return type is always an instance of the dynamic type of \texttt{self}, and \texttt{invalid2()} is rejected because \texttt{Self} appears in contravariant position.
\paragraph{Type variable types.}
A \IndexDefinition{type variable type}type variable represents the future inferred type of an \index{expression}expression in the expression type checker's constraint system. The expression type checker builds the constraint system by walking an expression recursively, assigning new type variables to the types of sub-expressions and recording constraints between these type variables. Solving the constraint system can have three possible outcomes:
\begin{itemize}
\item \textbf{One solution}---every type variable has exactly one fixed type assignment; the expression is well-typed.
\item \textbf{No solutions}---some constraints could not be solved, indicating erroneous input.
\item \textbf{Multiple solutions}---the constraint system is underspecified and some type variables can have multiple valid fixed type assignments.
\end{itemize}
In the case of multiple solutions, the type checker uses heuristics to pick the ``best'' solution for the entire expression; if none of the solutions are clearly better than the others, an ambiguity error is diagnosed. Otherwise, we proceed as if the solver only found the best solution. The final step applies the solution to the expression by replacing type variables appearing in the types of sub-expressions with their fixed types.
The utmost care must be taken when working with type variables because unlike all other types, they are not allocated with indefinite lifetime. Type variables live in the \IndexDefinition{constraint solver arena}constraint solver arena, which grows and shrinks as the solver explores branches of the solution space. Types that \emph{contain} type variables also need to be allocated in the constraint solver arena. This is also true of structures that contain types, such as substitution maps. Type variables ``escaping'' from the constraint solver can crash the compiler in odd ways. Assertions should be used to rule out type variables from appearing in the wrong places.
\IndexFlag{debug-constraints}
The printed representation of a type variable is \texttt{\$Tn}, where \texttt{n} is an incrementing integer local to the constraint system. One way to see type variables in action is to pass the \texttt{-Xfrontend~-debug-constraints} compiler flag.
\paragraph{L-value types.}
An \IndexDefinition{l-value type}l-value type represents the type of an \index{expression}expression appearing on the left hand side of an assignment operator (hence the ``l'' in l-value), or as an argument to an \texttt{inout} parameter in a function call. L-value types wrap an \IndexDefinition{object type}\emph{object type} which is the type of the stored value; they print out as \texttt{@lvalue~\textbf{T}} where \ttbf{T} is the object type, but this is not valid syntax in the language.
L-value types appear in type-checked expressions. The reader familiar with C++ might think of an l-value type as somewhat analogous to a C++ mutable reference type ``\texttt{\textbf{T}~\&}''---unlike C++ though, they are not directly visible in the source language. L-value types do not appear in the types of SIL instructions; \index{SILGen}SILGen lowers l-value accesses into accessor calls or direct manipulation of memory.
\paragraph{Error types.}
\IndexDefinition{error type}
\index{expression}
Error types are returned when type substitution encounters an invalid or missing conformance (Chapter~\ref{substmaps}). In this case, the error type wraps the original type, and prints as the original type to make types coming from malformed conformances more readable in diagnostics.
The expression type checker also assigns error types to invalid declaration references. This uses the singleton form of the error type, which prints as \texttt{<<error~type>>}. To avoid user confusion, diagnostics containing the singleton error type should not be emitted. Generally, any expression whose type contains an error type does not need to be diagnosed, because a diagnostic should have been emitted elsewhere.
\paragraph{Built-in types.}
\IndexDefinition{compiler intrinsic}
\IndexDefinition{built-in type}
What users think of as fundamental types, such as \texttt{Int} and \texttt{Bool}, are defined as structs in the standard library. These structs wrap the various \emph{built-in types} which are understood directly by the compiler. Built-in types are not nominal types, so they cannot contain members, cannot have new members added via extensions, and cannot conform to protocols. Values of built-in types are manipulated using special \emph{compiler intrinsics}. The standard library wraps built-in types in nominal types, and defines methods and operators on those nominal types which call the intrinsic functions, thereby presenting the actual interface expected by users.
For example, the \texttt{Int} struct defines a single stored property named \texttt{\_value} with type \texttt{Builtin.Int}. The \texttt{+} operator on \texttt{Int} is implemented by extracting the \texttt{\_value} stored property from a pair of \texttt{Int} values, calling the \texttt{Builtin.sadd\_with\_overflow\_Int64} compiler intrinsic to add them together, and finally, wrapping the resulting \texttt{Builtin.Int} in a new instance of \texttt{Int}.
\IndexDefinition{built-in module}
\IndexFlag{parse-stdlib}
Built-in types and their intrinsics are defined in the special \texttt{Builtin} module, which is a special module constructed by the compiler itself and not built from source code. The \texttt{Builtin} module is only visible when the compiler is invoked with the \texttt{-parse-stdlib} frontend flag; the standard library is built with this flag, but user code never interacts with the \texttt{Builtin} module directly.
\section{Source Code Reference}\label{typesourceref}
Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/Type.h}
\item \SourceFile{include/swift/AST/Types.h}
\item \SourceFile{lib/AST/Type.cpp}
\end{itemize}
Other source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/TypeNodes.def}
\item \SourceFile{include/swift/AST/TypeVisitor.h}
\item \SourceFile{include/swift/AST/CanTypeVisitor.h}
\end{itemize}
\IndexSource{type}
\apiref{Type}{class}
Represents an immutable, uniqued type. Meant to be passed as a value, it stores a single instance variable, a \texttt{TypeBase *} pointer.
The \texttt{getPointer()} method returns this pointer. The pointer is not \texttt{const}, however neither \texttt{TypeBase} nor any of its subclasses define any mutating methods. The pointer may be \texttt{nullptr}; the default constructor \texttt{Type()} constructs an instance of a null type. Most methods will crash if called on a null type; only the implicit \texttt{bool} conversion and \texttt{getPointer()} are safe.
The \texttt{getPointer()} method is only used occasionally, because types are usually passed as \texttt{Type} and not \texttt{TypeBase *}, and \texttt{Type} overloads \texttt{operator->} to forward method calls to the \texttt{TypeBase *} pointer. While most operations on types are actually methods on \texttt{TypeBase}, a few methods are also defined on \texttt{Type} itself (these are called with ``\texttt{.}'' instead of ``\texttt{->}'').
\begin{itemize}
\item \textbf{Various traversals:} \texttt{walk()} is a general pre-order traversal where the callback returns a tri-state value---continue, stop, or skip a sub-tree. Built on top of this are two simpler variants; \texttt{findIf()} takes a boolean predicate, and \texttt{visit()} takes a void-returning callback which offers no way to terminate the traversal.
\item \textbf{Transformations:} \texttt{transformWithPosition()}, \texttt{transformRec()}, \texttt{transform()}. As with the traversals, the first of the three is the most general, and the other two are built on top. In all three cases, the callback is invoked on all types contained within a type, recursively. It can either elect to replace a type with a new type, or leave a type unchanged and instead try to transform any of its child types.
\item \textbf{Substitution:} \texttt{subst()} implements type substitution, which is a particularly common kind of transform which replaces generic parameters or archetypes with concrete types (Section~\ref{substmapsourcecoderef}).
\item \textbf{Printing:} \texttt{print()} outputs the string form of a type, with many customization options; \texttt{dump()} prints the \index{tree}tree structure of a type in an \index{s-expression}s-expression form. The latter is extremely useful for invoking from inside a debugger, or ad-hoc print debug statements.
\end{itemize}
\IndexSource{type pointer equality}
The \texttt{Type} class explicitly deletes the overloads of \texttt{operator==} and \texttt{operator!=} to make the choice between pointer and canonical equality explicit. To check type pointer equality of possibly-sugared types, first unwrap both sides with a \texttt{getPointer()} call:
\begin{Verbatim}
if (lhsType.getPointer() == rhsType.getPointer())
...;
\end{Verbatim}
\IndexSource{canonical type equality}
The more common canonical type equality check is implemented by the \texttt{isEqual()} method on \texttt{TypeBase}:
\begin{Verbatim}
if (lhsType->isEqual(rhsType))
...;
\end{Verbatim}
\apiref{TypeBase}{class}
The root of the type kind hierarchy. Its instances are always uniqued and allocated by the AST context, either the permanent arena or constraint solver arena. Instances are usually wrapped in \texttt{Type}. The various subclasses correspond to the different kinds of types:
\begin{itemize}
\item \texttt{NominalType} and its four subclasses:
\begin{itemize}
\item \texttt{StructType},
\item \texttt{EnumType},
\item \texttt{ClassType},
\item \texttt{ProtocolType}.
\end{itemize}
\item \texttt{BoundGenericNominalType} and its three subclasses:
\begin{itemize}
\item \texttt{BoundGenericStructType},
\item \texttt{BoundGenericEnumType},
\item \texttt{BoundGenericClassType}.
\end{itemize}
\item The structural types \texttt{TupleType}, \texttt{MetatypeType}.
\item \texttt{AnyFunctionType} and its two subclasses:
\begin{itemize}
\item \texttt{FunctionType},
\item \texttt{GenericFunctionType}.
\end{itemize}
\item \texttt{GenericTypeParamType}, \texttt{DependentMemberType}, the two type parameter types.
\item \texttt{ArchetypeType}, and its three subclasses:
\begin{itemize}
\item \texttt{PrimaryArchetypeType},
\item \texttt{OpenedArchetypeType},
\item \texttt{OpaqueArchetypeType}.
\end{itemize}
\item The abstract types:
\begin{itemize}
\item \texttt{ProtocolCompositionType},
\item \texttt{ParameterizedProtocolType},
\item \texttt{ExistentialType},
\item \texttt{ExistentialMetatypeType},
\item \texttt{DynamicSelfType}.
\end{itemize}
\item \texttt{SugarType} and its four subclasses:
\begin{itemize}
\item \texttt{TypeAliasType},
\item \texttt{OptionalType},
\item \texttt{ArrayType},
\item \texttt{DictionaryType}.
\end{itemize}
\item \texttt{BuiltinType} and its subclasses (there are a bunch of esoteric ones; only a few are shown below):
\begin{itemize}
\item \texttt{BuiltinRawPointerType},
\item \texttt{BuiltinVectorType},
\item \texttt{BuiltinIntegerType},
\item \texttt{BuiltinIntegerLiteralType},
\item \texttt{BuiltinNativeObjectType},
\item \texttt{BuiltinBridgeObjectType}.
\end{itemize}
\item \texttt{ReferenceStorageType} and its two subclasses:
\begin{itemize}
\item \texttt{WeakStorageType},
\item \texttt{UnownedStorageType}.
\end{itemize}
\item Miscellaneous types:
\begin{itemize}
\item \texttt{UnboundGenericType},
\item \texttt{PlaceholderType},
\item \texttt{TypeVariableType},
\item \texttt{LValueType},
\item \texttt{ErrorType}.
\end{itemize}
\end{itemize}
Each concrete subclass defines some set of static factory methods, usually named \texttt{get()} or similar, which take the structural components and construct a new, uniqued type of this kind. There are also getter methods, prefixed with \texttt{get}, which project the structural components of each kind of type. It would be needlessly duplicative to list all of the getter methods for each subclass of \texttt{TypeBase}; they can all be found in \SourceFile{include/swift/AST/Types.h}.
\paragraph{Dynamic casts.}
Subclasses of \texttt{TypeBase *} are identifiable at runtime via the \verb|is<>|, \verb|castTo<>| and \verb|getAs<>| template methods. To check if a type has a specific kind, use \verb|is<>|:
\begin{Verbatim}
Type type = ...;
if (type->is<FunctionType>())
...;
\end{Verbatim}
To conditionally cast a type to a specific kind, use \verb|getAs<>|, which returns \verb|nullptr| if the cast fails:
\begin{Verbatim}
if (FunctionType *funcTy = type->getAs<FunctionType>())
...;
\end{Verbatim}
Finally, \verb|castTo<>| is an unconditional cast which asserts that the type has the required kind:
\begin{Verbatim}
FunctionType *funcTy = type->castTo<FunctionType>();
\end{Verbatim}
These template methods desugar the type if it is a sugared type, and the casted type can never itself be a sugared type. This is usually correct; for example, if \texttt{type} is the \texttt{Swift.Void} type alias type, then \texttt{type->is<TupleType>()} returns true, because it is for all intents and purposes a tuple (an empty tuple), except when printed in diagnostics.
There are also top-level template functions \verb|isa<>|, \verb|dyn_cast<>| and \verb|cast<>| that operate on \texttt{TypeBase *}. Using these with \texttt{Type} is an error; the pointer must be explicitly unwrapped with \texttt{getPointer()} first. These casts do not desugar, and permit casting to sugared types. This is the mechanism used when sugared types must be distinguished from canonical types for some reason:
\begin{Verbatim}
Type type = ...;
if (isa<OptionalType>(type.getPointer()))
...;
\end{Verbatim}
\paragraph{Visitors.}
The simplest way to \index{exhaustive switch}exhaustively handle each kind of type is to switch over the \IndexSource{type kind}kind, which is an instance of the \texttt{TypeKind} enum, like this:
\begin{Verbatim}
Type ty = ...;
switch (ty->getKind()) {
case TypeKind::Struct: {
auto *structTy = ty->castTo<StructType>();
...
}
case TypeKind::Enum:
...
case TypeKind::Class:
...
}
\end{Verbatim}
However, in most cases it is more convenient to use the \index{visitor pattern}\emph{visitor pattern} instead, by subclassing \texttt{TypeVisitor} and overriding various \texttt{visit\emph{Kind}Type()} methods. Then, invoking the visitor's \texttt{visit()} method with a type performs the same switch and dynamic cast dance above:
\begin{Verbatim}
class MyVisitor: public TypeVisitor<MyVisitor> {
public:
void visitStructType(StructType *ty) {
...
}
};
MyVisitor visitor;
Type ty = ...;
visitor.visit(ty);
\end{Verbatim}
The \texttt{TypeVisitor} also defines various methods corresponding to abstract base classes in the \texttt{TypeBase} hierarchy, so, for example, you can override \texttt{visitNominalType()} to handle all nominal types at once.
The \texttt{TypeVisitor} preserves information if it receives a sugared type; for example, visiting \texttt{Int?}\ will call \texttt{visitOptionalType()}, while visiting \texttt{Optional<Int>} will call \texttt{visitBoundGenericEnumType()}. In the common situation where the semantics of your operation do not depend on type sugar, you can use the \texttt{CanTypeVisitor} template class instead. Here, the \texttt{visit()} method takes a \texttt{CanType}, so \texttt{Int?}\ will need to be canonicalized to \texttt{Optional<Int>} before being passed in.
\paragraph{Canonical types.}
The \texttt{getCanonicalType()} method outputs a \texttt{CanType} wrapping the \IndexSource{canonical type}canonical form of this \texttt{TypeBase *}. The \texttt{isCanonical()} method checks if a type is canonical.
\paragraph{Nominal types.} A handful of methods on \texttt{TypeBase} exist which perform a desugaring cast to a nominal type (so they will also accept a type alias type or other sugared type), and return the nominal type declaration, or \texttt{nullptr} if the type isn't of a nominal kind:
\begin{itemize}
\item \texttt{getAnyNominal()} returns the nominal type declaration of \texttt{UnboundGenericType}, \texttt{NominalType} or \texttt{BoundGenericNominalType}.
\item \texttt{getNominalOrBoundGenericNominal()} returns the nominal type declaration of a \texttt{NominalType} or \texttt{BoundGenericNominalType}.
\item \texttt{getStructOrBoundGenericStruct()} returns the type declaration of a \texttt{StructType} or \texttt{BoundGenericStructType}.
\item \texttt{getEnumOrBoundGenericEnum()} returns the type declaration of an \texttt{EnumType} or \texttt{BoundGenericEnumType}.
\item \texttt{getClassOrBoundGenericClass()} returns the class declaration of a \texttt{ClassType} or \texttt{BoundGenericClassType}.
\item \texttt{getNominalParent()} returns the parent type stored by an \texttt{UnboundGenericType}, \texttt{NominalType} or \texttt{BoundGenericNominalType}.
\end{itemize}
\paragraph{Recursive properties.} Various predicates are computed when a type is constructed and are therefore cheap to check:
\begin{itemize}
\item \texttt{hasTypeVariable()} determines whether the type was allocated in the permanent arena or the \IndexSource{constraint solver arena}constraint solver arena.
\item \texttt{hasArchetype()}, \texttt{hasOpaqueArchetype()}, \texttt{hasOpenedExistential()}.
\item \texttt{hasTypeParameter()}.
\item \texttt{hasUnboundGenericType()}, \texttt{hasDynamicSelf()}, \texttt{hasPlaceholder()}.
\item \texttt{isLValue()}---despite the ``\texttt{is}'' in the name, this is a recursive property and not the same as \verb|ty->is<LValueType>()|.
\end{itemize}
\paragraph{Utility operations.} These encapsulate frequently-useful patterns.
\begin{itemize}
\item \texttt{getOptionalObjectType()} returns the type \texttt{T} if the type is some \texttt{Optional<T>}, otherwise it returns the null type.
\item \texttt{getMetatypeInstanceType()} returns the type \texttt{T} if the type is some \texttt{T.Type}, otherwise it returns \texttt{T}.
\item \texttt{mayHaveMembers()} answers if this is a nominal type, archetype, existential type or dynamic Self type.
\end{itemize}
\paragraph{Recovering the AST context.} All non-canonical types point at their canonical type, and canonical types point at the AST context.
\begin{itemize}
\item \texttt{getASTContext()} returns the singleton AST context from a type.
\end{itemize}
\apiref{CanType}{class}
The \texttt{CanType} class wraps a \texttt{TypeBase *} pointer which is known to be canonical. The pointer can be recovered with the \texttt{getPointer()} method. It forwards various methods to either \texttt{Type} or \texttt{TypeBase~*}. There is an implicit conversion from \texttt{CanType} to \texttt{Type}. In the other direction, the explicit one-argument constructor \texttt{CanType(Type)} asserts that the type is canonical; however, most of the time the \texttt{getCanonicalType()} method on \texttt{TypeBase} is used instead.
The \texttt{operator==} and \texttt{operator!=} operators are used to test \texttt{CanType} for \IndexSource{type pointer equality}type pointer equality. The \texttt{isEqual()} method described earlier implements canonical equality on sugared types by first canonicalizing both sides, and then checking the resulting canonical types for type pointer equality. Therefore, the following are equivalent:
\begin{Verbatim}
if (lhsType->isEqual(rhsType)) ...;
if (lhsType->getCanonicalType() == rhsType->getCanonicalType()) ...;
\end{Verbatim}
The \texttt{CanType} class can be used with the \verb|isa<>|, \verb|cast<>| and \verb|dyn_cast<>| templates. Instead of returning the actual \texttt{TypeBase} subclass, the latter two return a \emph{canonical type wrapper} for that subclass. Every subclass of \texttt{TypeBase} has a corresponding canonical type wrapper; if the subclass is named \texttt{FooType}, the canonical wrapper is named \texttt{CanFooType}. Canonical type wrappers forward \texttt{operator->} to the specific \texttt{TypeBase} subclass, and define methods of their own (called with ``\texttt{.}'') which project the known-canonical components of the type.
For example, \texttt{FunctionType} has a \texttt{getResult()} method returning \texttt{Type}, so the canonical type wrapper \texttt{CanFunctionType} has a \texttt{getResult()} method returning a \texttt{CanType}. The wrapper methods are not exhaustive, and their use is not required because you can instead make explicit calls to \texttt{CanType(Type)} or \texttt{getCanonicalType()} after projecting a type that is known to be canonical.
\begin{Verbatim}
CanType canTy = ...;
CanFunctionType canFuncTy = cast<FunctionType>(canTy);
// method on CanFunctionType: returns CanType(canFuncTy->getResult())
CanType canResultTy = canFuncTy.getResult();
// operator-> forwards to method on FunctionType: returns Type
CanType resultTy = CanType(canFuncTy->getResult());
\end{Verbatim}
\apiref{AnyFunctionType}{class}
This is the base class of \texttt{FunctionType} and \texttt{GenericFunctionType}.
\begin{itemize}
\item \texttt{getParams()} returns an array of \texttt{AnyFunctionType::Param}.
\item \texttt{getResult()} returns the result type.
\item \texttt{getExtInfo()} returns an instance of \texttt{AnyFunctionType::ExtInfo} storing the additional non-type attributes.
\end{itemize}
\apiref{AnyFunctionType::Param}{class}
This represents a parameter in a function type's parameter list.
\begin{itemize}
\item \texttt{getPlainType()} returns the type of the parameter. If the parameter is variadic (\texttt{T...}), this is the element type \texttt{T}.
\item \texttt{getParameterType()} same as above, but if the parameter is variadic, returns the type \texttt{Array<T>}.
\item \texttt{isVariadic()}, \texttt{isAutoClosure()} are the special behaviors.
\item \texttt{getValueOwnership()} returns an instance of the \texttt{ValueOwnership} enum.
\end{itemize}
\apiref{ValueOwnership}{enum class}
The possible ownership attributes on a function parameter.
\begin{itemize}
\item \texttt{ValueOwnership::Default}
\item \texttt{ValueOwnership::InOut}
\item \texttt{ValueOwnership::Shared}
\item \texttt{ValueOwnership::Owned}
\end{itemize}
\apiref{AnyFunctionType::ExtInfo}{class}
This represents the non-type attributes of a function type.
\end{document}