File: extensions.tex

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (838 lines) | stat: -rw-r--r-- 63,904 bytes parent folder | download
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
\documentclass[../generics]{subfiles}

\begin{document}

\chapter{Extensions}\label{extensions}

\IndexDefinition{extension declaration}
\index{value declaration}
\index{qualified lookup}
\IndexDefinition{extended type}
\lettrine{E}{xtensions add members} to existing nominal type declarations. We refer to this nominal type declaration as the \emph{extended type} of the extension. The extended type may have been declared in the same source file, another source file of the main module, or in some other module. Extensions themselves are declarations, but they are \emph{not} value declarations in the sense of Chapter~\ref{decls}, meaning the extension itself cannot be referenced by name. Instead, the members of an extension are referenced as members of the extended type, visible from qualified name lookup.

Consider a module containing a pair of struct declarations, \texttt{Outer} and \texttt{Outer.Middle}:
\begin{Verbatim}
public struct Outer<T> {
  public struct Middle<U> {}
}
\end{Verbatim}
A second module can declare an extension of \texttt{Outer.Middle} to add a method named \texttt{foo()} and a nested type named \texttt{Outer.Middle.Inner}:
\begin{Verbatim}
extension Outer.Middle {
  func foo() {}
  struct Inner<V> {}
}
\end{Verbatim}
If a third module subsequently imports both the first and second module, it will see the members \texttt{Outer.Middle.foo()} and \texttt{Outer.Middle.Inner} just as if they were defined inside \texttt{Outer.Middle} itself. 

\index{interface type}
\index{normal conformance}
\paragraph{Extensions and generics.}
Extensions have generic signatures, so the interface types of their members may involve the generic parameters of the extended type. The generic signature of an ``unconstrained'' extension is the same as that of the extended type. Extensions can impose additional requirements on their generic parameters via a \texttt{where} clause; this declares a \emph{constrained extension} with its own generic signature (Section~\ref{constrained extensions}). An extension can also state a conformance to a protocol, which is represented as normal conformance visible to global conformance lookup. If the extension is unconstrained, this is equivalent to a conformance on the extended type. If the extension is constrained, the conformance becomes a \emph{conditional conformance} (Section~\ref{conditional conformance}).

\index{generic parameter list}
Let's begin by taking a closer look at generic parameter lists of extensions, by way of our nested type \texttt{Outer.Middle} and its extension above. Recall how generic parameters of nominal types work from Chapter~\ref{generic declarations}: their names are lexically scoped to the body of the type declaration, and each generic parameter uniquely identified by its depth and index. We can represent the declaration context nesting and generic parameter lists of our nominal type declaration \texttt{Outer.Middle} with a diagram like the following:
\begin{quote}
\begin{tikzpicture}[node distance=5mm and 5mm,text height=1.5ex,text depth=.25ex]

\node (SourceFile) [SourceFile] {source file};

\node (Outer) [below=of SourceFile,xshift=4em,decl] {struct \texttt{Outer}};
\node (OuterGP) [right=of Outer,xshift=2em,OtherEntity] {generic parameter list \texttt{<T>}};

\node (Middle) [below=of Outer,xshift=4em,decl] {struct \texttt{Middle}};
\node (MiddleGP) [right=of Middle,xshift=2em,OtherEntity] {generic parameter list \texttt{<U>}};

\draw [arrow] (Middle.west) -| (Outer.south);
\draw [arrow] (Outer.west) -| (SourceFile.south);

\path (Middle.east) edge[arrow] (MiddleGP.west);
\path (Outer.east) edge[arrow] (OuterGP.west);

\end{tikzpicture}
\end{quote}

Semantically, each generic parameter visible inside the extended type should also be visible inside the extension, under the same name, depth and index. This is implemented by cloning the generic parameter declarations. Since every generic parameter in a single generic parameter list must have the same depth, an extension conceptually has multiple generic parameter lists, one for each level of depth (that is, the generic context nesting) of the extended type.

This is represented by linking the generic parameter lists together via an optional ``outer list'' pointer. The innermost generic parameter list is ``the'' generic parameter list of the extension, and the head of the list; it is cloned from the extended type. Its outer list pointer is cloned from the extended type's parent generic context, if any, and so on. The outermost generic parameter list has a null outer list pointer. In our extension of \texttt{Outer.Middle}, this looks like so:
\begin{quote}
\begin{tikzpicture}[every node/.style={draw,rectangle},node distance=5mm and 5mm,text height=1.5ex,text depth=.25ex]

\node (SourceFile) [SourceFile] {source file};

\node (Middle) at (0, -2) [xshift=6.5em,decl] {extension \texttt{Outer.Middle}};

\node (MiddleGP) [right=of Middle,xshift=2em,OtherEntity] {generic parameter list \texttt{<U>}};
\node (OuterGP) [above=of MiddleGP,OtherEntity] {generic parameter list \texttt{<T>}};

\draw [arrow] (Middle.west) -| (SourceFile.south);

\path (Middle.east) edge[arrow] (MiddleGP.west);
\path (MiddleGP.north) edge[arrow] (OuterGP.south);

\end{tikzpicture}
\end{quote}

Unqualified name lookup traverses the outer list pointer when searching for generic parameter declarations by name. A generic parameter found inside an extension always has the same depth and index as the original generic parameter it was cloned from in the extended type. Now, consider the nested type \texttt{Inner} from our example, which declares a generic parameter list of its own:
\begin{Verbatim}
extension Outer.Middle {
  struct Inner<V> {}
}
\end{Verbatim}
When an extension declares a nested generic type, the depth of the nested type's generic parameters becomes one greater than the depth of the extension's innermost generic parameter list. Thus, the generic parameter \texttt{V} of \texttt{Inner} has depth 2 and index 0. All three generic parameter lists are visible inside the body of \texttt{Outer.Middle.Inner}:
\begin{quote}
\begin{tikzpicture}[every node/.style={draw,rectangle},node distance=5mm and 5mm,text height=1.5ex,text depth=.25ex]

\node (SourceFile) [SourceFile] {source file};

\node (Middle) at (0, -2) [xshift=6.5em,decl] {extension \texttt{Outer.Middle}};
\node (Inner) [below=of Middle,xshift=4em,decl] {struct \texttt{Inner}};
\node (InnerGP) [right=of Inner,xshift=2em,OtherEntity] {generic parameter list \texttt{<V>}};

\node (MiddleGP) [right=of Middle,xshift=2em,OtherEntity] {generic parameter list \texttt{<U>}};
\node (OuterGP) [above=of MiddleGP,OtherEntity] {generic parameter list \texttt{<T>}};

\draw [arrow] (Middle.west) -| (SourceFile.south);
\draw [arrow] (Inner.west) -| (Middle.south);

\path (Middle.east) edge[arrow] (MiddleGP.west);
\path (MiddleGP.north) edge[arrow] (OuterGP.south);
\path (Inner.east) edge[arrow] (InnerGP.west);

\end{tikzpicture}
\end{quote}

\paragraph{Other behaviors.} Syntactically, the extended type is written in a type representation following the \texttt{extension} keyword. As the extended type must ultimately resolve to a nominal type, this is typically an identifier type representation. Extension binding uses a more primitive form of type resolution, for reasons explained in Section~\ref{extension binding}.  Extension members generally behave as members of the extended type, with a few caveats:
\begin{itemize}
\item Members of \index{protocol extension}\emph{protocol extensions} are not requirements imposed on the concrete type in the way that members of a protocol declaration are; they actually have implementations.

A protocol extension member with the same name and \index{interface type}interface type as a protocol requirement acts as a \IndexDefinition{default witness}\emph{default witness}, to be used if the conforming type does not provide its own witness for this requirement. The protocol extension below declares a default implementation of the protocol requirement \texttt{f()}, together with a utility function \texttt{g()}:
\begin{Verbatim}
protocol P {
  func f()
}

extension P {
  func f() {}
  func g() {
    f()
  }
}

struct S: P {}  // conformance uses the default witness for P.f()
\end{Verbatim}
\index{stored property declaration}
\index{struct declaration}
\index{limitation}
\item Extensions of struct and class declarations cannot add stored properties, only computed properties:
\begin{Verbatim}
struct S {
  var x: Int
}

extension S {
  var y: Int  // stored property: error
  var flippedX: Int { return -x }  // computed property: okay
}
\end{Verbatim}
This is for several reasons. Semantically, all stored properties must be initialized by all declared constructors; if extensions could add stored properties unknown to a previously-declared constructor, this invariant would be broken. Another reason is that the stored property layout of a struct or class is computed when the struct or class declaration is emitted, and there is no mechanism for extensions to alter this layout after the fact.
\index{enum declaration}
\item Extensions cannot add new cases to enum declarations, for similar reasons as stored properties; doing so would complicate both the static exhaustiveness checking for \texttt{switch} statements and the in-memory layout computation of the enum.

\index{class declaration}
\index{vtable}
\item When the extended type is a class, the methods of the extension are implicitly \texttt{final}, and the extension's methods are not permitted to override methods from the superclass. Non-\texttt{final} methods declared inside a class are dispatched through a vtable of function pointers attached to the runtime metadata of the class, and there is no mechanism for extensions to add new entries or replace existing entries inherited from the superclass.

\index{nested type declaration}
\item The rules for nested types in extensions are the same as nested types inside nominal types (Section~\ref{nested nominal types}). That is, extensions of structs, enums and classes can declare nested structs, enums and classes; while protocol extensions cannot declare nested nominal types for the same reason that protocols cannot. Extensions themselves always appear at the top level of a source file, but the extended type can be a nominal type nested inside of another nominal type (or extension).

\index{self interface type}
\index{declared interface type}
\Index{protocol Self type@protocol \texttt{Self} type}
\item The declared interface type of an extension is the declared interface type of the extended type; the self interface type of an extension is the self interface type of the extended type. The two concepts coincide except when the extended type is a protocol, in which case the declared interface type is the protocol type, whereas the self interface type is the protocol \texttt{Self} type.
\end{itemize}

\section{Extension Binding}\label{extension binding}

\IndexDefinition{extension binding}%
\index{qualified lookup}%
\index{name lookup}%
Extension members are visible to qualified lookup because \emph{extension binding} establishes a two-way association between an extension declaration and its extended type. Extension binding resolves the extended type representation to obtain the extended type, and then adds the extension's members to the extended type's name lookup table. Extension binding runs very early in the type checking process, immediately after parsing and import resolution. A complication is that the extended type of an extension can itself be declared inside of another extension. Extension binding cannot simply visit all extension declarations in a single pass in source order, because the order of declarations in a source file, and the order of source files within a module, should have no semantic effect. Instead, multiple passes are performed; a failure to bind an extension is not a fatal condition, and instead failed extensions are revisited later after subsequent extensions are successfully bound. This process iterates until fixed point.
\begin{algorithm}[Extension binding]\label{extension binding algorithm}
Takes a list of all extensions in the main module as input, in any order.
\begin{enumerate}
\item Initialize the pending list to contain all extensions.
\item Initialize the delayed list to the empty list.
\item Initialize the flag, initially clear.
\item (Check) If the pending list is empty, go to Step~6.
\item (Resolve) Remove an extension from the pending list and attempt to resolve its extended type. If resolution succeeds, associate the extension with the resolved nominal type declaration and set the flag. If resolution fails, add the extension to the delayed list but do not emit any diagnostics and leave the flag unchanged. Go back to Step~4.
\item (Retry) If the flag is set, move the entire contents of the delayed list to the pending list, clear the flag, and go back to Step~4. Otherwise, return.
\end{enumerate}
\end{algorithm}
\index{type-check source file request}
\index{primary file}
Any extensions with an unresolvable extended type will simply remain on the delayed list when this algorithm returns; the algorithm does not actually emit diagnostics. Unresolvable extended types are diagnosed later, when the \textbf{type-check source file request} visits the declarations in each primary file. Upon encountering an extension which failed extension binding, the type-check source file request resolves the extended type using ordinary type resolution. If this fails, we simply diagnose the unknown type. Otherwise, we're in a more subtle situation where the extended type is resolvable by ordinary type resolution, but not the limited form of type resolution used by extension binding, which is described below.

The worklist-driven extension binding algorithm was introduced in \index{history}Swift~5.0. Older compiler releases attempted to bind extensions in a single pass, something that could either succeed or fail depending on declaration order. This incorrect behavior was one of the most frequently reported bugs of all time \cite{sr631}.

\index{limitation}%
\paragraph{Unsupported extensions.}
\index{synthesized declaration}%
\index{identifier type representation}%
\index{generic type alias}%
\index{type resolution}%
\index{associated type inference}%
Ordinary type resolution depends on generic signature construction and protocol conformance checking; however, we cannot do these things until after extension binding is complete, lest they depend on name lookup finding members of extensions. For this reason, extension binding must use a minimal form of type resolution that does not call on other parts of the type checker. In particular, extension binding cannot find declarations synthesized by the compiler, including type aliases created by associated type inference. Also, it cannot perform type substitution; this rules out extensions of generic type aliases whose underlying type is itself a type parameter.

This is the situation alluded to previously, where extension binding fails but the \textbf{type-check source file request} successfully resolves the extended type later. In this case, a couple of additional checks help tailor the diagnostic. If ordinary type resolution returned a type alias type \texttt{Foo} desugaring to a nominal type \texttt{Bar}, the type checker emits the ``extension of type \texttt{Foo} must be declared as an extension of \texttt{Bar}'' diagnostic. Even though we know what the extended type should be at this point, we must still diagnose an error; it is too late to bind the extension, because other name lookups may have already been performed, potentially missing out on finding members of this extension.

\begin{example}\label{bad extension 1} An invalid extension of an inferred type alias:\index{horse}
\begin{Verbatim}
protocol Animal {
  associatedtype FeedType
  func eat(_: FeedType)
}

struct Horse: Animal {
  func eat(_: Hay) {}
}

// error: extension of type `Horse.FeedType' must be declared as an
// extension of `Hay'
extension Horse.FeedType {...}
\end{Verbatim}
Extension binding fails to resolve \texttt{Horse.FeedType}, because this type alias was not stated explicitly and is inferred by the conformance checker from the witness \verb|Horse.eat(_:)|. Therefore, the type alias does not exist at extension binding time, and we specifically do not trigger its synthesis.
\end{example}
\begin{example}\label{bad extension 2}
An invalid extension of a type alias with an underlying type that is a type parameter:
\begin{Verbatim}
typealias G<T: Sequence> = T.Element

// error: extension of type `G<Array<Int>>' must be declared as an
// extension of `Int'
extension G<Array<Int>> {...}
\end{Verbatim}
Extension binding fails to resolve \texttt{G<Array<Int>>}, because this requires performing a type substitution that depends on the conformance \verb|Array: Sequence|:
\begin{gather*}
\texttt{T.Element}\otimes\SubstMapC{\SubstType{T}{Array<Int>}}{\SubstConf{T}{Array<Int>}{Sequence}}\\
\qquad {} =\texttt{Int}
\end{gather*}
\end{example}

The other case where extension binding fails but \textbf{type-check source file request} is able to resolve the extended type is when this type is not actually a nominal type. In this situation, the type checker emits the fallback ``non-nominal type cannot be extended'' diagnostic.

The extension binding algorithm is quadratic in the worst case, where each pass over the pending list is only able to bind exactly one extension. However, only unrealistic code examples trigger this pathological behavior. Indeed, the first pass binds all extensions of types not nested inside of other extensions, and the second pass binds extensions of types nested inside extensions that were bound by the first pass, which covers the vast majority of cases in reasonable user programs.

\begin{example}
The following order of extensions requires four passes to bind; by adding more nested types, the number of iterations can be increased arbitrarily:
\begin{Verbatim}
struct Outer {}

extension Outer.Middle.Inner {}  // bound in 3rd pass

extension Outer.Middle {  // bound in 2nd pass
  struct Inner {}
}

extension Outer {  // bound in 1st pass
  struct Middle {}
}

extension DoesNotExist {}  // remains on delayed list
\end{Verbatim}

In the first pass, the extensions of \texttt{Outer.Middle.Inner} and \texttt{Outer.Middle} both fail, but we do successfully bind the extension of \texttt{Outer}. The second pass once again fails to bind the extension of \texttt{Outer.Middle.Inner}, but it does bind the extension of \texttt{Outer.Middle}. Finally, the third pass binds the extension of \texttt{Outer.Middle.Inner}. Notice how in each of the first three passes, we are able to bind at least one extension. The invalid extension of \texttt{DoesNotExist} remains on the delayed list after each of the first three passes. Since the fourth pass does not make any forward progress, the algorithm stops. Later we end up in the diagnostic path, which resolves \texttt{DoesNotExist} via ordinary type resolution, surfacing the ``unknown type'' error.
\end{example}

\paragraph{Local types.}
\index{local type declaration}
\index{limitation}
Because extensions can only appear at the top level of a source file, the extended type must ultimately be visible from the top level. This allows extensions of types nested inside other top-level types, but precludes extensions of local types nested inside of functions or other local contexts, because there is ultimately no way to name a local type from the top level of a source file. (As a curious consequence, local types cannot conditionally conform to protocols, since the only way to declare a conditional conformance is with an extension!)

\section{Direct Lookup}

Now we're going to take closer look at \IndexDefinition{direct lookup}\emph{direct lookup}, the primitive operation that looks for a \index{value declaration}value declaration with the given name inside of a nominal type and its extensions. This was first introduced in Section~\ref{name lookup} as the layer below qualified \index{name lookup}name lookup, which performs direct lookups into the base type, its conformed protocols, and superclasses.

Nominal type declarations and extensions are \IndexDefinition{iterable declaration context}\emph{iterable declaration contexts}, meaning they contain member declarations. Before discussing direct lookup, let's consider what happens if we ask an iterable declaration context to list its members. This is a lazy operation which triggers work the first time it is called:
\begin{itemize}
\item Iterable declaration contexts parsed from source are populated by \index{delayed parsing}delayed parsing; when the \index{parser}parser first reads a source file, the bodies of iterable declaration contexts are skipped, and only the source range is recorded. Asking for the list of members goes and parses the source range again, constructing declarations from their parsed representation (Section~\ref{delayed parsing}).
\index{serialized module}
\index{imported module}
\index{Objective-C}
\item Iterable declaration contexts from binary and imported modules are equipped with a \IndexDefinition{lazy member loader}\emph{lazy member loader} which serves a similar purpose. Asking the lazy member loader to provide a list of members will build Swift declarations from deserialized records or imported Clang declarations. The lazy member loader can also find declarations with a specific name, as explained below.
\end{itemize}

\paragraph{Member lookup table.}
Every nominal type declaration has an associated \IndexDefinition{member lookup table}\emph{member lookup table}, which is used for direct lookup. This table maps each identifier to a list of value declarations with that name (multiple value declarations can share a name because Swift allows type-based overloading). The declarations in a member lookup table are understood to be members of one or more iterable declaration contexts, which are exactly the type declaration itself and all of its extensions. These iterable declaration contexts might originate from a mix of different module kinds. For example, the nominal type itself might be an Objective-C class from an imported Objective-C module, with one extension declared in a binary Swift module, and another extension defined in the main module, parsed from source. 

The lookup table is populated lazily, in a manner resembling a state machine. The first direct lookup into a nominal type does populate the member lookup table with all members from any \emph{parsed} iterable declaration contexts, which might trigger delayed parsing. Each entry in the member lookup table stores a ``complete'' bit. Initially the ``complete'' bit of these entries is \emph{not} set, meaning that the entry only contains those members that were parsed from source. If any iterable declaration contexts originate from binary and imported modules, direct lookup then asks each lazy member loader to selectively load only those members with the given name. After the lazy member loaders do their work, the lookup table entry for this name is now complete, and the ``complete'' bit is set. Later when direct lookup finds a member lookup table entry with the ``complete'' bit set, it knows this entry is fully populated, and the stored list of declarations is returned immediately without querying the lazy member loaders.

This \IndexDefinition{lazy member loading}\emph{lazy member loading} mechanism ensures that only those members which are actually referenced in a compilation session are loaded from serialized and imported iterable declaration contexts. Iterable declaration contexts parsed from source do not offer this level of fine-grained lazyness, because there is no way to parse only those members having a given name.

\begin{listing}\captionabove{A class implemented in Objective-C, with an extension written in Swift}\label{lazy member listing}
\begin{Verbatim}
// a.h
@interface NSHorse: NSObject
- (void) trot: (int) x;
- (void) canter: (float) x;
@end
\end{Verbatim}
\begin{Verbatim}
// b.swift
import HorseKit

extension NSHorse {
  func walk(_: Float) {}
  func trot(_: Float) {}
}
\end{Verbatim}
\begin{Verbatim}
// c.swift
import HorseKit

func ride(_ horse: NSHorse) {
  horse.walk(1.0)
  horse.trot(2.0)
  horse.walk(1.0)
}
\end{Verbatim}
\end{listing}

\begin{example}
Listing~\ref{lazy member listing} shows an example of lazy member loading. Observe the following:
\begin{itemize}
\item The \texttt{NSHorse} class itself is declared in Objective-C in a header file. Suppose this header file is part of the \texttt{HorseKit} module, imported by the two Swift source files.
\item The Swift source file \texttt{b.swift} declares an extension of \texttt{NSHorse}. Let's say that this is a secondary file in the current frontend job.
\item The Swift source file \texttt{c.swift} declares a function which calls some methods on \texttt{NSHorse}. For our example this needs to be a primary file of this frontend job.
\item The \texttt{trot()} method in the class has a different interface type than the \texttt{trot()} method in the extension, so they are two distinct overloaded methods with the same name.
\end{itemize}
The compiler begins by parsing both Swift source files, skipping over the extension body with delayed parsing because it appears in a secondary file. Next, extension binding is performed, which associates the extension of \texttt{NSHorse} with the imported class declaration of \texttt{NSHorse}. Finally, we type check the body of the \texttt{ride()} function, since it appears in a primary file. Type checking the expressions in the body performs three direct lookups into \texttt{NSHorse}, first with the name \texttt{walk}, then \texttt{trot}, and finally \texttt{walk} again.

\newcommand{\LookupTableEntry}[1]{{\setlength{\fboxrule}{0pt}\fbox{\begin{tabular}{@{}l@{}}#1\end{tabular}}}}

\newcommand{\LookupTableElt}[1]{
\begin{tikzpicture}
\node [rounded corners, fill=light-gray] {#1};
\end{tikzpicture}
}

\smallskip

(\texttt{walk}) The table is initially empty, so it must be populated with the members of all parsed iterable declaration contexts first. This triggers delayed parsing of the extension, which adds two entries to our member lookup table:
\begin{quote}
\begin{tabular}{llc}
\toprule
\textbf{Name}&\textbf{Declarations}&\textbf{Complete?}\\
\midrule
\texttt{walk}&
\LookupTableEntry{
\LookupTableElt{
\texttt{NSHorse.walk} in extension of \texttt{NSHorse}
}
}
&$\times$\\
\midrule
\texttt{trot}&
\LookupTableEntry{
\LookupTableElt{
\texttt{NSHorse.trot} in extension of \texttt{NSHorse}
}
}&$\times$\\
\bottomrule
\end{tabular}
\end{quote}
At this point, neither entry is complete, because we haven't looked for members inside the class itself, which was imported and not parsed. Direct lookup does that next, by asking the lazy member loader associated with the class declaration to load any members named \texttt{walk}. The class does not define such a member, so we simply mark the member lookup table entry as complete:
\begin{quote}
\begin{tabular}{llc}
\toprule
\textbf{Name}&\textbf{Declarations}&\textbf{Complete?}\\
\midrule
\texttt{walk}&
\LookupTableEntry{
\LookupTableElt{
\texttt{NSHorse.walk} in extension of \texttt{NSHorse}
}
}
&$\checkmark$\\
\midrule
\texttt{trot}&
\LookupTableEntry{
\LookupTableElt{
\texttt{NSHorse.trot} in extension of \texttt{NSHorse}
}
}&$\times$\\
\bottomrule
\end{tabular}
\end{quote}
Direct lookup returns \texttt{NSHorse.walk()} to the type checker.

\smallskip

(\texttt{trot}) While the member lookup table already has an entry named \texttt{trot}, it is not complete, so the lazy member loader for the class declaration is consulted again. This time, the class contains a member with this name also. The \texttt{trot} method is imported from Objective-C and added to the member lookup table:
\begin{quote}
\begin{tabular}{llc}
\toprule
\textbf{Name}&\textbf{Declarations}&\textbf{Complete?}\\
\midrule
\texttt{walk}&
\LookupTableEntry{
\LookupTableElt{
\texttt{NSHorse.walk} in extension of \texttt{NSHorse}
}
}
&$\checkmark$\\
\midrule
\texttt{trot}&
\LookupTableEntry{
\LookupTableElt{
\texttt{NSHorse.trot} in extension of \texttt{NSHorse}
}\\
\LookupTableElt{
\texttt{NSHorse.trot} in class \texttt{NSHorse}
}
}
&$\checkmark$\\
\bottomrule
\end{tabular}
\end{quote}
Direct lookup now returns both overloads of \texttt{NSHorse.trot()} to the type checker.

\smallskip

(\texttt{walk}) The third lookup finds that the corresponding member lookup table entry is already complete, so we immediately return the existing declaration stored there without consulting the lazy member loader. Notice that the \texttt{canter} method of \texttt{NSHorse} was never referenced, so it did not need to be imported at all.
\end{example}

\paragraph{History.}
Lazy member loading was introduced in Swift~4.1 to avoid wasted work in deserializing or importing members that are never referenced. The speedup is most pronounced when multiple frontend jobs perform direct lookup into a common set of deserialized or imported nominal types. The overhead of loading all members of this common set of types was multiplied across frontend jobs prior to the introduction of lazy member loading.

\section{Constrained Extensions}\label{constrained extensions}

\IndexDefinition{constrained extension}
\IndexDefinition{unconstrained extension}
An extension can impose its own requirements on the generic parameters of the extended type; we refer to this as a \emph{constrained extension}. These requirements are always additive; the generic signature of a constrained extension is built from the generic signature of the extended type, together with the new requirements. The members of a constrained extension are then only available on specializations of the extended type that satisfy these requirements. There are three ways to declare a constrained extension:
\begin{enumerate}
\item using a \Index{where clause@\texttt{where} clause}\texttt{where} clause,
\item by writing a bound generic type as the extended type,
\item by writing a generic type alias type as the extended type, with some restrictions.
\end{enumerate}
Case~1 is the most general form; Case~2 and Case~3 can be expressed by writing the appropriate requirements in a \texttt{where} clause. An extension that does not fall under one of these three cases is sometimes called an \emph{unconstrained extension} when it is important to distinguish it from a constrained extension. The generic signature of an unconstrained extension is the same as the generic signature of the extended type. 

Here is a constrained extension of \texttt{Set} which constrains the \texttt{Element} type to \texttt{Int}:
\begin{Verbatim}
extension Set where Element == Int {...}
\end{Verbatim}
The generic signature of \texttt{Set} is \verb|<Element where Element: Hashable>|. Adding the same-type requirement $\FormalReq{Element == Int}$ makes the requirement $\ConfReq{Element}{Hashable}$ redundant since \texttt{Int} conforms \texttt{Hashable}, so the extension's generic signature becomes \verb|<Element where Element == Int>|.

This example demonstrates that while the requirements of the constrained extension abstractly imply those of the extended type, they are not a ``syntactic'' subset---the $\ConfReq{Element}{Hashable}$ requirement does not appear in the constrained extension's generic signature, because it became redundant when $\FormalReq{Element == Int}$ was added.

In the early days of Swift, this extension was not supported at all, because the compiler did not permit same-type requirements between generic parameters and concrete types; only dependent member types could be made concrete. This restriction was lifted in Swift~3, and many concepts described in this book, most importantly substitution maps and generic environments, were introduced as part of this effort.

\paragraph{Extending a generic nominal type.} An extension of a generic nominal type with generic arguments is shorthand for a \texttt{where} clause that constrains each generic parameter to a concrete type. The generic argument types must be fully concrete; they cannot reference the generic parameters of the extended type declaration. The previous example can be more concisely expressed using this syntax:
\begin{Verbatim}
extension Set<Int> {...}
\end{Verbatim}
A non-generic type alias type whose underlying type is a bound generic type can also be used in the same manner:
\begin{Verbatim}
typealias StringMap = Dictionary<String, String>
extension StringMap {...}
\end{Verbatim}
This shorthand was introduced in Swift 5.7 \cite{se0361}.

\paragraph{Extending a generic type alias.}
A \index{generic type alias}generic type alias is called a \IndexDefinition{pass-through type alias}``pass-through type alias'' if it satisfies the following three conditions:
\begin{enumerate}
\item the underlying type of the generic type alias must be a generic nominal type,
\item the type alias must have the same number of generic parameters as the underlying type declaration,
\item the type alias must substitute each generic parameter of the underlying type declaration with the corresponding generic parameter of the type alias (where the correspondence means they have the same depth and index).
\end{enumerate}
A pass-through type alias essentially equivalent to the underlying generic nominal type, except that it may introduce additional requirements via a \texttt{where} clause. An extension of a pass-through type alias is equivalent to a constrained extension of the underlying nominal type which states these additional requirements. Note that the pass-through type alias is not required to give its generic parameters the same names as its underlying type, which is slightly confusing, because the names used by the type alias declaration do not matter to the extension at all; the generic parameter list of the extension is always cloned from the extended nominal type, and not the type alias.

\begin{example}
While it is a generally useful feature, the ability to extend a pass-through type alias was motivated by the desire to maintain source compatibility after a specific standard library change.

The standard library defines a generic struct named \texttt{Range} with a single \texttt{Bound} generic parameter conforming to \texttt{Comparable}:
\begin{Verbatim}
struct Range<Bound: Comparable> {...}
\end{Verbatim}
Prior to Swift 4.2, the standard library also had a separate \texttt{CountableRange} type with a different set of requirements:
\begin{Verbatim}
struct CountableRange<Bound: Stridable>
    where Bound.Stride: SingedInteger {}
\end{Verbatim}
The \texttt{Stridable} protocol inherits from \texttt{Comparable}, so every valid generic argument of \texttt{CountableRange} was also also suitable for \texttt{Range}. Also, \texttt{CountableRange} offered a superset of the API of \texttt{Range}. The only difference between the two was that \texttt{CountableRange} conformed to more protocols than \texttt{Range}. After conditional conformances were added to the language, \texttt{CountableRange} no longer made sense as a separate type. Swift~4.2 replaced \texttt{CountableRange} with a generic type alias:
\begin{Verbatim}
typealias CountableRange<Bound: Stridable> = Range<Bound>
    where Bound.Stride: SignedInteger
\end{Verbatim}
In Swift 4.1, the following were extensions of two different nominal types:
\begin{Verbatim}
extension Range {...}

extension CountableRange {...}
\end{Verbatim}
In Swift 4.2, the second extension became equivalent to a constrained extension of \texttt{Range}, once the compiler understood pass-through type aliases:
\begin{Verbatim}
extension Range
    where Bound: Stridable,
          Bound.Stride: SignedInteger {...}
\end{Verbatim}
\end{example}
\begin{example}
The following type aliases are not pass-through type aliases.
\begin{enumerate}
\item The underlying type of this type alias is not a nominal type:
\begin{verbatim}
typealias A<T> = () -> T
\end{verbatim}
\item This type alias has the wrong number of generic parameters:
\begin{verbatim}
typealias B<Value> = Dictionary<AnyHashable, Value>
\end{verbatim}
\item This type alias does not substitute the second generic parameter of the underlying type with the second generic parameter of the type alias:
\begin{verbatim}
typealias D<Key, Value> = Dictionary<Key, (Value) -> Int>
\end{verbatim}
\end{enumerate}
\end{example}

\section{Conditional Conformances}\label{conditional conformance}

A conformance declared on a nominal type declaration or an unconstrained extension implements the protocol's requirements for all specializations of the nominal type; we can call this an \emph{unconditional} conformance. In constrast, a conformance declared on a \emph{constrained} extension is what's known as a \IndexDefinition{conditional conformance}\emph{conditional conformance}, which implements the protocol requirements only for those specializations of the extended type which satisfy the requirements of the extension. For example, arrays have a natural notion of equality, defined in terms of the equality operation on the element type. However, there is no reason to require all arrays to store \texttt{Equatable} types. Instead, the standard library defines a conditional conformance of \texttt{Array} to \texttt{Equatable} where the element type is \texttt{Equatable}:
\begin{Verbatim}
struct Array<Element> {...}

extension Array: Equatable where Element: Equatable {
  func ==(lhs: Self, rhs: Self) -> Bool {
    guard lhs.count == rhs.count else { return false }

    for i in 0..<lhs.count {
      // `Element: Equatable' conditional requirement is used here
      guard lhs[i] == rhs[i] else { return false }
    }

    return true
  }
}
\end{Verbatim}
%Conditional conformances of \texttt{Array} to \texttt{Hashable} and \texttt{Comparable} are defined similarly.

\paragraph{Computing conditional requirements.}
A \index{normal conformance}normal conformance stores a list of zero or more \IndexDefinition{conditional requirement}\emph{conditional requirements}; this is the ``difference'' between the requirements of the conforming context, and the requirements of the conforming type. A conditional conformance is a conformance with at least one conditional requirement; equivalently, it is a conformance declared on a constrained extension. Formally, this ``requirement difference'' operation takes two generic signatures, that of the conforming type, and the conforming context. We collect those requirements of the conforming context which are not already satisfied by the conforming type. 
A simple example is the conditional conformance of \texttt{Dictionary} to \texttt{Equatable}:
\begin{Verbatim}
extension Dictionary: Equatable where Value: Equatable {...}
\end{Verbatim}
The generic signature of \texttt{Dictionary} is \verb|<Key, Value where Key: Hashable>|. The generic signature of our constrained extension has two requirements:
\begin{quote}
\begin{verbatim}
<Key, Value where Key: Hashable, Value: Equatable>
\end{verbatim}
\end{quote}
The first requirement is already satisfied by the generic signature of \texttt{Dictionary} itself; the second requirement is the conditional requirement of our conformance.

Algorithm~\ref{reqissatisfied}, for checking \index{generic arguments}generic arguments against the requirements of a nominal type's generic signature, is also used to compute conditional requirements. This algorithm takes a substituted requirement as input, which cannot contain type parameters. Here though, we need to find the requirements of a generic signature $G$ that are not satisfied by another generic signature $H$, rather than checking if a specific set of concrete types satisfy the requirements of $H$. To solve this problem, we reach for a generic environment and its archetypes. If $G$ is the generic signature of the extended type, and $H$ is the generic signature of the constrained extension, then the \index{archetype type}archetypes of the \index{generic environment}primary generic environment of $G$ abstractly represent ``the most general'' substitutions which satisfy the requirements of $G$.

\index{substituted requirement}
\begin{algorithm}[Computing conditional requirements]\label{conditional requirements algorithm}
As input, takes the generic signature of the conforming type, and the generic signature of the conforming context. We can assume the conforming context is a constrained extension, since otherwise the algorithm is trivial and always returns an empty list.
\begin{enumerate}
\item Let $G$ be the generic signature of the conforming type, and let $H$ be the generic signature of the constrained extension.
\item Initialize the output list of conditional requirements to be empty.
\item For each requirement of $H$, apply the \index{forwarding substitution map}forwarding substitution map $1_{\EquivClass{G}}$ to the requirement, to get a substituted requirement.
\item If the substituted requirement contains error types due to a substitution failure, add the original requirement to the output list. A substitution failure indicates that the requirement is unsatisfied, because it depends on some other unsatisfied conformance requirement.
\item Otherwise, we have a valid substituted requirement. Apply Algorithm~\ref{reqissatisfied} to check if the substituted requirement is satisfied.
\item If the substituted requirement is not satisfied, add it to the output list.
\item Otherwise the substituted requirement is satisfied, so it is not a conditional requirement.
\end{enumerate}
\end{algorithm}

\paragraph{Specialized conditional conformances.}
Applying a substitution map $\Sigma$ to a normal conformance $\ConfReq{$\texttt{T}_d$}{P}$ produces a \index{specialized conformance}specialized conformance $\ConfReq{$\texttt{T}_d$}{P}\otimes\Sigma$, which we denoted by $\ConfReq{T}{P}$, where $\texttt{T}=\texttt{T}_d\otimes\Sigma$, and $\texttt{T}_d$ is the declared interface type of the conforming nominal type declaration. If this underlying normal conformance is conditional, the conformance substitution map $\Sigma$ is the context substitution map of the conforming type \texttt{T} with respect to the constrained extension, and the input generic signature of $\Sigma$ is the generic signature of this extension. Thus, $\Sigma$ can be applied to the type parameters of the constrained extension, including the type parameters appearing in the constrained extension's requirements. The conditional requirements of a specialized conformance are then defined as the result of applying $\Sigma$ to the conditional requirements of the underlying normal conformance, making the following \index{commutative diagram}diagram commute:
\begin{quote}
\newcommand{\GetConditionalRequirements}{\def\arraystretch{0.65}\arraycolsep=0pt\begin{array}{c}\text{get conditional}\\\text{requirements}\end{array}}
\begin{tikzcd}[column sep=3cm,row sep=1cm]
\ConfReq{$\texttt{T}_d$}{P} \arrow[d, "\GetConditionalRequirements"{left}] \arrow[r, "\Sigma"] &\ConfReq{T}{P} \arrow[d, "\GetConditionalRequirements"] \\
\text{original requirement} \arrow[r, "\Sigma"]&\text{substituted requirement}
\end{tikzcd}
\end{quote}

Consider the $\ConfReq{Array<Element>}{Equatable}$ conformance from the standard library. While the generic signature of \texttt{Array} itself has no requirements, the generic signature of the constrained extension is \verb|<Element where Element: Equatable>|. The context substitution map of \texttt{Array<Int>} with respect to the constrained extension is:
\[\Sigma := \SubstMapLongC{\SubstType{Element}{Int}}{\SubstConf{Element}{Int}{Equatable}}\]
We can apply this substitution map to the normal conformance get the specialized conditional conformance, denoted \ConfReq{Array<Int>}{Equatable}:
\[
\ConfReq{Array<Element>}{Equatable} \otimes \Sigma = \ConfReq{Array<Int>}{Equatable}
\]
The normal conformance has a single conditional requirement, \ConfReq{Element}{Equatable}. The conditional requirement of the specialized conformance is obtained by applying $\Sigma$:
\[
\ConfReq{Element}{Equatable} \otimes \Sigma = \ConfReq{Int}{Equatable}
\]

\paragraph{Global conformance lookup.}
\index{global conformance lookup}
Global conformance lookup purposely does not check conditional requirements, allowing callers to answer two different questions:
\begin{enumerate}
\item Does this specialized type with its specific list of generic arguments conform to the protocol?
\item What requirements should these generic arguments satisfy to make the specialized type conform?
\end{enumerate}
It is up to the caller to apply Algorithm \ref{reqissatisfied} to each conditional requirement if the first interpretation is desired; if this holds, we say the type \emph{conditionally conforms}. For the second interpretation, the conditional requirements can be extracted for further processing.

Recall that with a specialized type, global conformance lookup first finds the normal conformance, and then applies the context substitution map to produce a specialized conformance. If the conformance is conditional, the context substitution map is computed with respect to the constrained extension. For example, \texttt{Array<AnyObject>} does not conditionally conform to \texttt{Equatable}, since \texttt{AnyObject} is not \texttt{Equatable}. Global conformance lookup will still construct a specialized conformance:
\begin{gather*}
\protosym{Equatable} \otimes \texttt{Array<AnyObject>}\\
= \ConfReq{Array<Element>}{Equatable} \otimes \SubstMapLongC{\SubstType{Element}{AnyObject}}{\ConfReq{Element}{Equatable}\mapsto\text{invalid}}\\
= \ConfReq{Array<AnyObject>}{Equatable}
\end{gather*}
While the above conformance substitution map contains an invalid conformance, looking for invalid conformances in the conformance substitution map is not the correct way of checking conditional requirements. If the conforming type conditionally conforms, the conformance substitution map will be valid, but not vice versa, because the conditional requirements might not be conformance requirements. The satisfiability of superclass, same-type, and layout requirement is not encoded in the conformance substitution map. In the below, $\ConfReq{Pair<Int, String>}{P}$ has a valid conformance substitution map, but the conditional requirement $\FormalReq{T == U}$ does not hold:
\begin{Verbatim}
protocol P {}
struct Pair<T, U> {}
extension Pair: P where T == U {}
\end{Verbatim}

\begin{listing}[b!]\captionabove{Infinite recursion while building a specialized conditional conformance}\label{conditional conformance recursion}
\begin{Verbatim}
protocol P {}

protocol Q {
  associatedtype A
}

struct G<T: Q> {}

extension G: P where T.A: P {}

struct S: Q {
  typealias A = G<S>
}

func takesP<T: P>(_: T.Type) {}
takesP(G<S>.self)
\end{Verbatim}
\end{listing}

\begin{example}
Conditional conformances can express \index{non-terminating computation}non-terminating computation at compile time. 
The code shown in Listing~\ref{conditional conformance recursion} shows an example from a bug report which remains unfixed for the time being \cite{sr6724}. The \texttt{takesP()} function has the below generic signature:
\begin{quote}
\begin{verbatim}
<τ_0_0 where τ_0_0: P>
\end{verbatim}
\end{quote}
In the snippet, this function is called with \texttt{G<S>} as the generic argument for \ttgp{0}{0}. This substitution map for this call also needs to store the conformance $\ConfReq{G<S>}{P}$, but this conformance cannot be constructed. The normal conformance $\ConfReq{G<\ttgp{0}{0}>}{P}$ is declared on a constrained extension with the following generic signature:
\begin{quote}
\begin{verbatim}
<τ_0_0 where τ_0_0: Q, τ_0_0.[Q]A: P>
\end{verbatim}
\end{quote}
To construct the specialized conformance $\ConfReq{G<S>}{P}$ from this normal conformance, we must first construct the conformance substitution map. The substitution map should map \ttgp{0}{0} to \texttt{S}, and store a pair of conformances, for the conformance requirements $\ConfReq{\ttgp{0}{0}}{Q}$ and $\ConfReq{\ttgp{0}{0}.[Q]A}{P}$:
\[\Sigma := \SubstMapLongC{\SubstType{\ttgp{0}{0}}{S}}{
\SubstConf{\ttgp{0}{0}}{S}{Q}\\
\ConfReq{\ttgp{0}{0}.[Q]A}{P}\mapsto\text{???}
}\]
The conforming type of the first conformance should be $\ttgp{0}{0}\otimes\Sigma=\texttt{S}$, so the first conformance is the normal conformance $\ConfReq{S}{Q}$. The conforming type of the second conformance should be 
$\AssocType{[Q]A}\otimes\ConfReq{S}{Q}=\texttt{G<S>}$; so the second conformance is exactly $\ConfReq{G<S>}{P}$, the conformance we're in the process of constructing. A substitution map cannot form a cycle with a specialized conformance it contains.

Now, suppose we could represent a circular substitution map of this kind:
\[\Sigma := \SubstMapLongC{\SubstType{\ttgp{0}{0}}{S}}{
\SubstConf{\ttgp{0}{0}}{S}{Q}\\
\ConfReq{\ttgp{0}{0}.[Q]A}{P}\mapsto\ConfReq{G<\ttgp{0}{0}>}{P}\otimes\Sigma
}\]
Unfortunately, this would still not allow our example to type check. The next problem we would encounter is checking the conditional requirement, $\ConfReq{\ttgp{0}{0}.[Q]A}{P}$. Applying $\Sigma$ gives us the substituted conditional requirement:
\[\ConfReq{\ttgp{0}{0}.[Q]A}{P}\otimes\Sigma=\ConfReq{G<S>}{P}\]
So \texttt{G<S>} conditionally conforms to \texttt{P} if the conditional requirement $\ConfReq{G<S>}{P}$ is satisfied; this conditional requirement is satisfied if \texttt{G<S>} conditionally conforms to \texttt{P}. At this point, we are stuck in a loop, again. For now, the compiler crashes on this example while constructing the conformance substitution map; hopefully a future update to this book will describe the eventual resolution of this bug by imposing an iteration limit.

Our example only encodes an infinite loop, but conditional conformances can actually express arbitrary computation. This is shown for the \index{Rust}Rust programming language, which also has conditional conformances, in \cite{rustturing}. We'll also see another example of non-terminating compile-time computation in Section~\ref{recursive conformances}.
\end{example}

\paragraph{Protocol inheritance.}
\index{inherited protocol}
Protocol inheritance is modeled by conformance requirements on \texttt{Self}, so for instance the requirement signature of \verb|P| has a conformance requirement $\ConfReq{Self}{Q}$:
\begin{Verbatim}
protocol P {...}
protocol Q: P {...}
\end{Verbatim}
When checking a conformance to \texttt{P}, the \index{conformance checker}conformance checker ensures that the conforming type satisfies the $\ConfReq{Self}{P}$ requirement. When the conformance to \texttt{Q} is unconditional, this always succeeds, because an unconditional conformance to a derived protocol also implies an unconditional conformance to the base protocol:
\begin{Verbatim}
struct G<T, U> {}
extension G: Q {...}
// implies `extension G: P {}'
\end{Verbatim}
The nominal type's \index{conformance lookup table}conformance lookup table synthesizes these implied conformances and makes them available to global conformance lookup. With conditional conformances, the situation is rather different. The conformance lookup table cannot synthesize a \emph{conditional} conformance to a base protocol because there is no way to guess what the conditional requirements on that conformance should be. The conformance checker still checks the conformance requirement on \texttt{Self} though, which has the effect of requiring explicit declaration of conditional conformances to base protocols.

Suppose we instead wish for \texttt{G<T, U>} to conditionally conform to \texttt{Q} when \texttt{T == Int}:
\begin{Verbatim}
extension G: Q where T == Int {...}
\end{Verbatim}
The compiler will only accept this declaration if there is also an explicit conformance of \texttt{G<T, U>} to \texttt{P}. There are several possible ways to declare a conformance of \texttt{G<T, U>} to \texttt{P}. The simplest way is to conform unconditionally:
\begin{Verbatim}
extension G: P {...}
\end{Verbatim}
Things get more interesting if the conformance to the base protocol is also conditional, because then the conformance $\ConfReq{G<T, U>}{Q}$ is only valid if its conditional requirements imply the conditional requirements of $\ConfReq{G<T, U>}{P}$ (if the latter is unconditional, this is of course vacuously true).

There are three generic contexts in play here:
\begin{enumerate}
\item The nominal type declaration of the conforming type.
\item The constrained extension for the base protocol conformance.
\item The constrained extension for the derived protocol conformance.
\end{enumerate}
Specifically, tensure the conformance $\ConfReq{G<T, U>}{Q}$ satisfies the requirement signature requirement $\ConfReq{Self}{P}$, the conformance checker must prove that any specialization of \verb|G| which satisfies the conditional requirements of (3) must \emph{also} satisfy the conditional requirements of (2). This is where the notion of a generic environment is useful. Mapping the declared interface type of (1) into the generic environment of (3) gives us a type whose generic arguments satisfy the conditional requirements of (3) in the ``most general'' way:
\[\texttt{G<T, U>} \otimes \SubstMap{\SubstType{T}{Int},\,\SubstType{U}{$\archetype{U}$}} = \texttt{G<Int, $\archetype{U}$>}\]
Next, we do a global conformance lookup of this type with the base protocol, which gives us a specialized conformance:
\[\protosym{P}\otimes \texttt{G<Int, $\archetype{U}$>} = \ConfReq{G<T, U>}{P} \otimes \SubstMap{\SubstType{T}{Int},\,
\SubstType{U}{$\archetype{U}$}}\]
Specialized conformances apply the conformance substitution map to their conditional requirements, so the above conformance gives us the conditional requirements of (2) but substituted with the archetypes of (3). Checking these requirements determines our final answer. Let's look at some possibilities for our base conformance $\ConfReq{G<T>}{P}$, and how they impact the validity of the conformance to the derived protocol $\ConfReq{G<T>}{Q}$:
\begin{enumerate}
\item
The conditional conformance of \texttt{G} to \texttt{P} might require that \texttt{T} is \texttt{Int}:
\begin{Verbatim}
extension G: P where T == Int {...}
\end{Verbatim}
The conditional requirement is $\FormalReq{T == Int}$, and after substitution we get:
\[\FormalReq{T == Int}\otimes \SubstMap{\SubstType{T}{Int},\,\SubstType{U}{$\archetype{U}$}}=\FormalReq{Int == Int}\]
This trivially holds, therefore the conditional requirements of $\ConfReq{G<T>}{Q}$ imply the conditional requirements of $\ConfReq{G<T>}{P}$, so the former is valid.

\item Instead, we could conform \texttt{G} to \texttt{P} when \texttt{T} conforms to \texttt{Equatable}:
\begin{Verbatim}
extension G: P where T: Equatable {...}
\end{Verbatim}
Now, the conditional requirement of $\ConfReq{G<T>}{P}$ is $\ConfReq{T}{Equatable}$, and after substitution we get:
\[\ConfReq{G<T>}{P}\otimes\SubstMap{\SubstType{T}{Int},\,\SubstType{U}{$\archetype{U}$}}=\ConfReq{Int}{Equatable}\]
This also holds, so once again our conditional conformance $\ConfReq{G<T>}{Q}$ is valid.

\item Finally consider the following, which is invalid:
\begin{Verbatim}
extension G: P where U: Equatable {...}
\end{Verbatim}
The conditional requirement is $\ConfReq{U}{Equatable}$, which becomes $\ConfReq{$\archetype{U}$}{Equatable}$ after substitution:
\[\ConfReq{U}{Equatable}\otimes \SubstMap{\SubstType{T}{Int},\,\SubstType{U}{$\archetype{U}$}}=\ConfReq{U}{Equatable}\]
The archetype $\archetype{U}$ appearing in our substitution map is from the generic environment of the extension declaring the conformance to \verb|Q|, where it was not subjected to any requirements. In particular, $\archetype{U}$ does not conform to \texttt{Equatable}. Thus, if $\ConfReq{G<T>}{P}$ is declared as above, the conformance $\ConfReq{G<T>}{Q}$ is rejected, because the conditional requirement $\FormalReq{T == Int}$ of $\ConfReq{G<T>}{Q}$ does not imply the conditional requirement $\ConfReq{U}{Equatable}$ of $\ConfReq{G<T>}{P}$.
\end{enumerate}

\section{Source Code Reference}\label{extensionssourceref}

Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/Decl.h}
\item \SourceFile{lib/AST/Decl.cpp}
\end{itemize}

\IndexSource{extension declaration}%
\apiref{ExtensionDecl}{class}
Represents an extension declaration.
\begin{itemize}
\item \texttt{getExtendedNominal()} returns the extended type declaration. Returns \verb|nullptr| if extension binding failed to resolve the extended type. Asserts if extension binding has not yet visited this extension.
\item \texttt{computeExtendedNominal()} actually evaluates the request which resolves the extended type to a nominal type declaration. Only used by extension binding.
\IndexSource{extended type}
\item \texttt{getExtendedType()} returns the written extended type, which might be a type alias type or a generic nominal type.
\item \texttt{getDeclaredInterfaceType()} returns the declared interface type of the extended type declaration.
\Index{protocol Self type@protocol \texttt{Self} type}
\item \texttt{getSelfInterfaceType()} returns the self interface type of the extended type declaration. Different than the declared interface type for protocol extensions, where the declared interface type is the protocol type, but the self interface type is the protocol \texttt{Self} type.
\end{itemize}

\subsection*{Extension Binding}

Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/NameLookup.h}
\item \SourceFile{lib/AST/Decl.cpp}
\item \SourceFile{lib/AST/NameLookup.cpp}
\item \SourceFile{lib/Sema/TypeChecker.cpp}
\end{itemize}

\IndexSource{extension binding}
\apiref{bindExtensions()}{function}
Takes a \texttt{ModuleDecl *}, which must be the main module, and implements Algorithm~\ref{extension binding algorithm}.

\apiref{ExtendedNominalRequest}{class}
The request evaluator request which resolves the extended type to a nominal type declaration. This calls out to a restricted form of type resolution which does not apply generic arguments or perform substitution.

\apiref{directReferencesForTypeRepr()}{function}
Takes a \texttt{TypeRepr *} and the extension's parent declaration context, which is usually a source file. Returns a vector of \texttt{TypeDecl *}. Some of the type declarations might be type alias declarations; the next entry point fully resolves everything to a list of nominal types.

\apiref{resolveTypeDeclsToNominal()}{function}
Takes a list of \texttt{TypeDecl *} and outputs a list of \texttt{NominalTypeDecl *}, by resolving any type alias declarations to nominal types, using the same restricted form of type resolution recursively.

If the output list is empty, type resolution failed and the extension cannot be bound. If the output list contains more than one entry, type resolution produced an ambiguous result. For now, we always take the first nominal type declaration from the output list in that case.

\subsection*{Direct Lookup and Lazy Member Loading}

Key source files:
\begin{itemize}
\item \SourceFile{lib/AST/NameLookup.cpp}
\item \SourceFile{include/swift/AST/LazyResolver.h}
\end{itemize}

\IndexSource{direct lookup}
\apiref{DirectLookupRequest}{class}
The request evaluator request implementing direct lookup. The entry point is the \texttt{NominalTypeDecl::lookupDirect()} method, which was introduced in Section~\ref{compilation model source reference}. This request is uncached, because the member lookup table effectively implements caching outside of the request evaluator.

You can read through the implementation of \verb|DirectLookupRequest::evaluate()| and the functions that it calls to understand how lazy member loading works:
\begin{itemize}
\item \texttt{prepareLookupTable()} adds all members from extensions without lazy loaders, and members loaded so far from extensions with lazy loaders, without marking any entries as complete.
\item \texttt{populateLookupTableEntryFromLazyIDCLoader()} asks a lazy member loader to load a single entry and adds it to the member lookup table.
\item \texttt{populateLookupTableEntryFromExtensions()} adds all members from extensions that do not have lazy member loaders.
\end{itemize}

\IndexSource{member lookup table}
\apiref{MemberLookupTable}{class}
Every \texttt{NominalTypeDecl} has an instance of \texttt{MemberLookupTable}, which maps declaration names to lists of \texttt{ValueDecl}. The most important methods:
\begin{itemize}
\item \texttt{find()} returns an iterator pointing at an entry, which might be missing or incomplete.
\item \texttt{isLazilyComplete()} answers if an entry is complete.
\item \texttt{markLazilyComplete()} marks an entry as complete.
\end{itemize}

\IndexSource{lazy member loader}
\apiref{LazyMemberLoader}{class}
Abstract base class implemented by different kinds of modules to look up top-level declarations and members of types and extensions. For the \index{main module}main module, this consults lookup tables built from source, for \index{serialized module}serialized modules this deserializes records and builds declarations from them, for \index{imported module}imported modules this constructs Swift declarations from \index{Clang}Clang declarations.

\subsection*{Constrained Extensions}

\IndexSource{constrained extension}
\index{generic signature request}
Key source files:
\begin{itemize}
\item \SourceFile{lib/Sema/TypeCheckDecl.cpp}
\item \SourceFile{lib/Sema/TypeCheckGeneric.cpp}
\end{itemize}
The \texttt{GenericSignatureRequest} was previously introduced in Section~\ref{buildinggensigsourceref}. It delegates to a pair of utility functions to implement special behaviors of extensions.

\apiref{collectAdditionalExtensionRequirements()}{function}
Collects an extension's requirements from the extended type, which handles extensions of pass-through type aliases (\verb|extension CountableRange {...}|) and extensions of bound generic types (\verb|extension Array<Int> {...}|).

\IndexSource{pass-through type alias}
\apiref{isPassthroughTypealias()}{function}
Answers if a generic type alias satisfies the conditions that allow it to be the extended type of an extension.

\subsection*{Conditional Conformances}

\IndexSource{conditional conformance}
\IndexSource{conditional requirement}

Key source files:
\begin{itemize}
\item \SourceFile{include/swift/AST/GenericSignature.h}
\item \SourceFile{include/swift/AST/ProtocolConformance.h}
\item \SourceFile{lib/AST/GenericSignature.cpp}
\item \SourceFile{lib/AST/ProtocolConformance.cpp}
\item \SourceFile{lib/Sema/TypeCheckProtocol.cpp}
\end{itemize}
The \verb|NormalProtocolConformance| and \verb|SpecializedProtocolConformance| classes were previously introduced in Section~\ref{conformancesourceref}.
\apiref{NormalProtocolConformance}{class}
\begin{itemize}
\item \texttt{getConditionalRequirements()} returns an array of conditional requirements, which is empty if the conformance is unconditional.
\end{itemize}
\apiref{SpecializedProtocolConformance}{class}
\begin{itemize}
\item \texttt{getConditionalRequirements()} returns an array of substituted conditional requirements with the conformance substitution map applied, which is empty if the conformance is unconditional.
\end{itemize}
\apiref{GenericSignatureImpl}{class}
See also Section~\ref{genericsigsourceref}.
\begin{itemize}
\item \texttt{requirementsNotSatisfiedBy()} returns an array of those requirements of this generic signature not satisfied by the given generic signature. This is used for computing conditional requirements of a \texttt{NormalProtocolConformance}.
\end{itemize}

\apiref{TypeChecker::conformsToProtocol()}{function}
Utility wrapper around \texttt{ModuleDecl::lookupConformance()} which checks conditional requirements, returning an invalid conformance if they are not satisfied.

\end{document}