@@ -108,6 +108,57 @@ largely according to Swift's type grammar.
108
108
sil-type ::= '$' '*'? generic-parameter-list? type
109
109
```
110
110
111
+ ## Formal vs. Lowered Types
112
+
113
+ A formal type corresponds to a Swift type as it is defined in the source code.
114
+ The AST and the type checker work with formal types. Formal types can be
115
+ canonicalized which resolves type aliases and removes sugar. Later stages of
116
+ the compiler, like the SIL optimizer, only deal with canonical formal types.
117
+ Therefore, if we speak about formal types in the following sections, we always
118
+ refer to _ canonical_ formal types.
119
+
120
+ Each formal type has a corresponding lowered type. However, most lowered types
121
+ are identical to their original formal type, for example all nominal types,
122
+ like classes, structs or enums. Only a few kind of types are lowered to a
123
+ different lowered type. The most prominent example is function types: a lowered
124
+ function type adds information about the calling convention and it lowers tuple
125
+ arguments to individual arguments.
126
+
127
+ For example, the formal type of
128
+
129
+ ```
130
+ func foo(a: (Int, String), b: any P) { }
131
+ ```
132
+
133
+ is ` ((Int, String), any P) -> () ` whereas its lowered type is
134
+ ` (Int, @guaranteed String, @in_guaranteed any P) -> () ` .
135
+
136
+ Deriving a lowered type from a formal type is called _ type lowering_ . For
137
+ detailed information about type lowering see the
138
+ [ Types] ( Types.md#Type-Lowering ) document.
139
+
140
+ SIL types are always lowered types. The soundness of the SIL type system
141
+ depends on lowered types and the SIL optimizer needs lowered types to perform
142
+ correct optimizations.
143
+
144
+ However, there are a few places where SIL needs to refer to formal types. These
145
+ are operations on types which are "user visible", for example cast
146
+ instructions.
147
+
148
+ For example, a cast from ` ((Int, Bool)) -> () ` to ` (Int, Bool) -> () ` fails
149
+ because the two formal function types differ. If a SIL cast instruction would
150
+ operate on SIL types, the cast would incorrectly succeed because the formal
151
+ types of those functions types are equivalent.
152
+
153
+ To summarize:
154
+
155
+ | | Definition | Example |
156
+ | ------------------ | --------------------------------------------- | ----------------------------------- |
157
+ | ** Formal type** | original type from the source code | ` typealias C = ((Int, Bool)) -> () ` |
158
+ | ** Canonical type** | formal type minus sugar, aliases resolved | ` ((Int, Bool)) -> () ` |
159
+ | ** SIL type** | lowered canonical type, plus is-address flag | ` $*(Int, Bool) -> () ` |
160
+
161
+
111
162
## Loadable vs. Address-only Types
112
163
113
164
Most SIL types are _ loadable_ . That means that a value of such a type can be
0 commit comments