Skip to content

Commit 4127a4e

Browse files
committed
docs: Document Unsafe*Pointer conversions in TypeChecker.md
1 parent 2149731 commit 4127a4e

File tree

1 file changed

+208
-142
lines changed

1 file changed

+208
-142
lines changed

docs/TypeChecker.md

Lines changed: 208 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -93,151 +93,217 @@ e.g., a tuple type `(T0, Int, (T0) -> Int)` involving the type
9393
variable `T0`.
9494

9595
There are a number of different kinds of constraints used to describe
96-
the Swift type system:
97-
98-
**Equality**
99-
An equality constraint requires two types to be identical. For
100-
example, the constraint `T0 == T1` effectively ensures that `T0` and
101-
`T1` get the same concrete type binding. There are two different
102-
flavors of equality constraints:
103-
104-
- Exact equality constraints, or "binding", written `T0 := X`
105-
for some type variable `T0` and type `X`, which requires
106-
that `T0` be exactly identical to `X`;
107-
- Equality constraints, written `X == Y` for types `X` and
108-
`Y`, which require `X` and `Y` to have the same type,
109-
ignoring lvalue types in the process. For example, the
110-
constraint `T0 == X` would be satisfied by assigning `T0`
111-
the type `X` and by assigning `T0` the type `@lvalue X`.
112-
113-
**Subtyping**
114-
A subtype constraint requires the first type to be equivalent to or
115-
a subtype of the second. Subtyping constraints are written `X < Y`.
116-
117-
The following are the basic subtyping rules in the Swift language.
118-
First, we have class inheritance relationships:
119-
- If `X` is a subclass of `Y`, then `X < Y`.
120-
- If `X` is an archetype, and `Y` is the superclass bound of `X`, then `X < Y`.
121-
122-
Second, we have existential erasure:
123-
- If `X` is a concrete type, and `X` conforms to a protocol `P`, then `X < any P`.
124-
- If `X` is an archetype, and `X` conforms to a protocol `P`, then `X < any P`.
125-
- If `X` is a class or class-bound archetype, then `X < AnyObject`.
126-
- If `X` is a type, `X < any P`, and `X < any Q`, then `X < any P & Q`.
127-
128-
Third, we have conversions between existential types:
129-
- If protocol `P` inherits from protocol `Q`, then `any P < any Q`.
130-
- If `any P` and `any Q` are existential types, then `any P & Q < any P` and `any P & Q < any Q`.
131-
- If `P` is a protocol and `C` is a class, then `any P < any P & C`.
132-
- If `P` is a protocol, then `any P<...> < any P`.
133-
134-
An existential type converts to a class in a few special cases:
135-
- If `P` is a protocol and `C` is a class, then `any P & C < any P`.
136-
- If `P` is a protocol and `C` is a class, then `any P & C < C`.
137-
- If `P` is a protocol and `C` is the superclass bound of `P`, then `any P < C`.
138-
139-
Functions:
140-
- If `X < Y`, then `(..., Y, ...) -> Z < (..., X, ...) -> Z` (function parameters are contravariant).
141-
- If `X < Y`, then `(...) -> X < (...) -> Y` (function results are covariant).
142-
143-
Tuples:
144-
- If `X < Y`, then `(..., X, ...) < (..., Y, ...)` (tuple elements are covariant).
145-
146-
Optionals:
147-
- If `X` is an arbitrary type, then `X < Optional<X>`.
148-
- If `X < Y`, then `Optional<X> < Optional<Y>`.
149-
150-
Metatypes:
151-
- If `X < Y` via class inheritance, existential erasure, and existential conversion, then `X.Type < Y.Type`. However, this does not hold for arbitrary subtype relationships; for example, `X.Type < Optional<X>.Type` does not hold.
152-
153-
Collections:
154-
- If `X < Y`, then `Array<X> < Array<Y>`.
155-
- If `K1 < K2` and `V1 < V2`, then `Dictionary<K1, K2> < Dictionary<V1, V2>`.
156-
- If `X < Y`, then `Set<X> < Set<Y>`.
157-
158-
Toll-free bridging:
159-
- `NSString < CFString` and also `CFString < NSString`.
160-
- Similar conversions exist for various other CF/NS types that
161-
we won't discuss here.
162-
163-
CGFloat:
164-
- `CGFloat < Double` and `Double < CGFloat`, but with certain restrictions.
165-
166-
AnyHashable:
167-
- If `X` is an archetype or concrete type that conforms to
168-
`Hashable`, then `X < AnyHashable`.
169-
170-
Metatype to AnyObject:
171-
- If Objective-C interop is enabled and `X` is an arbitrary type,
172-
then `X.Type < AnyObject`.
96+
the Swift type system. This only lists the most important kinds; for
97+
the full list, see `include/swift/Sema/Constraint.h`.
98+
99+
### Bind
100+
101+
Written `X := Y` for arbitrary types `X` and `Y`, this constraint
102+
requires that `X` and `Y` can both be derived by performing substitution
103+
on some common type `Z`.
104+
105+
### Equal
106+
107+
Equality constraints, written `X == Y` for types `X` and `Y`, are
108+
satisfied if and only if erasing `@lvalue` types from `X` and `Y`
109+
yields a pair of types that would satisfy a **Bind** constraint.
110+
111+
### BindParam
112+
113+
BindParam constraints appear when type checking closures. Given two
114+
types `X` and `Y`, `X BindParam Y` is satisfied if `X := Y`, or if
115+
`X` is an `@lvalue` type, `Y` is an `inout` type, and stripping off
116+
the specifiers from both sides yields a pair of types that would
117+
satisfy a **Bind** constraint.
118+
119+
### Subtype
120+
121+
A Subtype constraint requires the first type to be equivalent to, or
122+
a subtype of, the second. Subtyping constraints are written `X < Y`.
123+
124+
However, be warned that this relation is neither anti-reflexive
125+
(because `X < X` for all `X`), nor is it transitive (because `X < Y`
126+
and `Y < Z` does not always imply that `X < Z`. For example, suppose
127+
that `X` does not conform to `P`, but `Optional<X>` does. Then we have
128+
`X < Optional<X>` and `Optional<X> < any P`, but _not_ `X < any P`).
129+
130+
The following are the basic subtyping rules in the Swift language.
131+
132+
First, we have class inheritance relationships:
133+
- If `X` is a subclass of `Y`, then `X < Y`.
134+
- If `X` is an archetype, and `Y` is the superclass bound of `X`, then `X < Y`.
135+
136+
Second, we have existential erasure:
137+
- If `X` is a concrete type, and `X` conforms to a protocol `P`, then `X < any P`.
138+
- If `X` is an archetype, and `X` conforms to a protocol `P`, then `X < any P`.
139+
- If `X` is a class or class-bound archetype, then `X < AnyObject`.
140+
- If `X` is a type, `X < any P`, and `X < any Q`, then `X < any P & Q`.
141+
142+
Third, we have conversions between existential types:
143+
- If protocol `P` inherits from protocol `Q`, then `any P < any Q`.
144+
- If `any P` and `any Q` are existential types, then `any P & Q < any P` and `any P & Q < any Q`.
145+
- If `P` is a protocol and `C` is a class, then `any P < any P & C`.
146+
- If `P` is a protocol, then `any P<...> < any P`.
147+
148+
An existential type converts to a class in a few special cases:
149+
- If `P` is a protocol and `C` is a class, then `any P & C < any P`.
150+
- If `P` is a protocol and `C` is a class, then `any P & C < C`.
151+
- If `P` is a protocol and `C` is the superclass bound of `P`, then `any P < C`.
152+
153+
Functions:
154+
- If `X < Y`, then `(..., Y, ...) -> Z < (..., X, ...) -> Z` (function parameters are contravariant).
155+
- If `X < Y`, then `(...) -> X < (...) -> Y` (function results are covariant).
156+
157+
Tuples:
158+
- If `X < Y`, then `(..., X, ...) < (..., Y, ...)` (tuple elements are covariant).
159+
- Tuple labels can be eliminated, so `(X, Y) < (x: X, y: Y)`.
160+
- Tuple labels can be introduced, so `(x: X, y: Y) < (X, Y)`.
161+
162+
Optionals:
163+
- If `X` is an arbitrary type, then `X < Optional<X>`.
164+
- If `X < Y`, then `Optional<X> < Optional<Y>`.
165+
166+
Metatypes:
167+
- If `X < Y` via class inheritance, existential erasure, and existential conversion,
168+
then `X.Type < Y.Type`. However, this does not extend to other subtype
169+
relationships; for example, `X.Type < Optional<X>.Type` does not hold.
170+
171+
Collections:
172+
- If `X < Y`, then `Array<X> < Array<Y>`.
173+
- If `K1 < K2` and `V1 < V2`, then `Dictionary<K1, K2> < Dictionary<V1, V2>`.
174+
- If `X < Y`, then `Set<X> < Set<Y>`.
175+
176+
Toll-free bridging:
177+
- `NSString < CFString` and also `CFString < NSString`.
178+
- Similar conversions exist for various other CF/NS types that
179+
we won't discuss here.
180+
181+
CGFloat:
182+
- `CGFloat < Double` and `Double < CGFloat`, but with certain restrictions.
183+
184+
AnyHashable:
185+
- If `X` is an archetype or concrete type that conforms to
186+
`Hashable`, then `X < AnyHashable`.
187+
188+
Metatype to AnyObject:
189+
- If Objective-C interop is enabled and `X` is an arbitrary type,
190+
then `X.Type < AnyObject`.
173191

174192
**Conversion**
175193

176-
The conversion relation is a superset of the subtype relation. Conversion
177-
constraints are written `X <c Y`, read as "`X` can be converted to `Y`".
178-
179-
Today, the main difference is that conversion allows _tuple shuffles_, where
180-
the elements of a tuple are re-ordered by considering labels. For example,
181-
`(x: Int, y: String) <c (y: String, x: Int)` is true, but
182-
`(x: Int, y: String) < (y: String, x: Int)` is false.
183-
184-
**Argument conversion**
185-
186-
An even more general relation, for conversions in function call argument
187-
position only. This adds conversions between various standard library
188-
`Unsafe*Pointer<T>` and `Unsafe*RawPointer` types.
189-
190-
**Member**
191-
A member constraint `X[.name] == Y` specifies that the first type
192-
(`X`) have a member (or an overloaded set of members) with the
193-
given name, and that the type of that member be bound to the second
194-
type (`Y`). There are two flavors of member constraint: value
195-
member constraints, which refer to the member in an expression
196-
context, and type member constraints, which refer to the member in a
197-
type context (and therefore can only refer to types).
198-
199-
**Conformance**
200-
A conformance constraint `X conforms to Y` specifies that the
201-
first type (`X`) must conform to the protocol `Y`. Note that
202-
this is stricter than a subtype constraint `X < any P`, because
203-
if `X` is an existential type `any P`, then in general,
204-
`X` does not conform to `any P` (but there are some exceptions,
205-
such as `any Error`, and Objective-C protocol existentials).
206-
207-
**Checked cast**
208-
A constraint describing a checked cast from the first type to the
209-
second, i.e., for `x as T`.
210-
211-
**Applicable function**
212-
An applicable function requires that both types are function types
213-
with the same input and output types. It is used when the function
214-
type on the left-hand side is being split into its input and output
215-
types for function application purposes. Note, that it does not
216-
require the type attributes to match.
217-
218-
**Overload binding**
219-
An overload binding constraint binds a type variable by selecting a
220-
particular choice from an overload set. Multiple overloads are
221-
represented by a disjunction constraint.
222-
223-
**Conjunction**
224-
A constraint that is the conjunction of two or more other
225-
constraints. We solve the first constraint first, and then the second,
226-
and so on, in order. Conjunctions are used to model multi-statement
227-
closures, as well as `if` and `switch` expressions, where type
228-
information flows in one direction only.
229-
230-
**Disjunction**
231-
A constraint that is the disjunction of two or more constraints.
232-
Disjunctions are used to model overload sets, or different potential
233-
conversions, each of which might resolve in a (different) solution.
234-
235-
**Self object of protocol**
236-
An internal-use-only constraint that describes the conformance of a
237-
`Self` type to a protocol. It is similar to a conformance
238-
constraint but "looser" because it allows a protocol type to be the
239-
self object of its own protocol (even when an existential type would
240-
not conform to its own protocol).
194+
The conversion relation is a superset of the subtype relation. Conversion
195+
constraints are written `X <c Y`, read as "`X` can be converted to `Y`".
196+
197+
Today, the only difference is that conversion allows _tuple shuffles_, where
198+
the elements of a tuple are re-ordered by considering labels. For example,
199+
`(x: Int, y: String) <c (y: String, x: Int)` is true, but
200+
`(x: Int, y: String) < (y: String, x: Int)` is false.
201+
202+
### ArgumentConversion
203+
204+
An even more general relation, for conversions in function call argument
205+
position only. Written as `X <a Y`.
206+
207+
1. Conversions from `String` and `Array` to pointer:
208+
- `Array<X> <a UnsafePointer<X>`
209+
- `Array<X> <a UnsafeRawPointer`
210+
- `String <a UnsafePointer<Int8>`
211+
- `String <a UnsafePointer<UInt8>`
212+
- `String <a UnsafePointer<Void>`
213+
- `String <a UnsafeRawPointer`
214+
215+
2. Conversions from `inout String` and `inout Array` to pointer (*):
216+
- `inout X <a UnsafePointer<X>`
217+
- `inout Array<X> <a UnsafePointer<X>`
218+
- `inout Array<X> <a UnsafeRawPointer`
219+
- `inout X <a UnsafeMutablePointer<X>`
220+
- `inout Array<X> <a UnsafeMutablePointer<X>`
221+
- `inout Array<X> <a UnsafeMutableRawPointer`
222+
223+
3. Conversions from pointer to pointer:
224+
- `UnsafePointer<X> <a UnsafeRawPointer`
225+
- `UnsafeRawPointer <a UnsafePointer<Int8>`
226+
- `UnsafeRawPointer <a UnsafePointer<UInt8>`
227+
- `UnsafeMutablePointer<X> <a UnsafePointer<X>`
228+
- `UnsafeMutableRawPointer <a UnsafeRawPointer`
229+
230+
TODO: There is also `AutoreleasingUnsafeMutablePointer` on Darwin platforms.
231+
232+
TODO: When the argument is passed to the parameter of an imported C function,
233+
even more conversions are possible, such as
234+
`Unsafe[Mutable]Pointer<Int{8, 16, ...}> <-> Unsafe[Mutable]Pointer<UInt{8, 16, ...}>`.
235+
236+
### OperatorArgumentConversion
237+
238+
A further special case for arguments of operators.
239+
240+
Recall that an operator like `+=` mutates the left-hand side, so the
241+
first parameter in the declaration is an `inout` type. However, unlike
242+
a call of a function that has an `inout` parameter, you write `x += y`
243+
and not of `x += y` at the call site. Hence, this constraint allows
244+
conversion of an `@lvalue` into an `inout`.
245+
246+
On the other hand, operator argument conversion prohibits pointer conversions
247+
from groups (1) and (3) listed above. Only group (2) is supported.
248+
249+
### SubclassOf
250+
251+
A subclass constraint `X subclass Y` is satisfied if `Y` is a class type,
252+
and `X` is a class, class-bounded archetype, dynamic `Self` type, or similar
253+
that is a subtype of `X`. Subclass constraints are used to represent
254+
superclass requirements.
255+
256+
### ConformsTo
257+
258+
A "conforms to" constraint `X conforms Y` specifies that the
259+
first type (`X`) must conform to the protocol `Y`. Note that
260+
this is stricter than a subtype constraint `X < any P`, because
261+
if `X` is an existential type `any P`, then in general,
262+
`X` does not conform to `any P` (but there are some exceptions,
263+
such as `any Error`, and Objective-C protocol existentials).
264+
265+
### CheckedCast
266+
267+
A constraint describing a checked cast from the first type to the
268+
second, i.e., for `x as T`.
269+
270+
### ApplicableFunction
271+
272+
An applicable function requires that both types are function types
273+
with the same input and output types. It is used when the function
274+
type on the left-hand side is being split into its input and output
275+
types for function application purposes. Note, that it does not
276+
require the type attributes to match.
277+
278+
### BindOverload
279+
280+
An overload binding constraint binds a type variable by selecting a
281+
particular choice from an overload set. Multiple overloads are
282+
represented by a disjunction constraint.
283+
284+
### ValueMember
285+
286+
A member constraint `X[.name] == Y` specifies that the first type
287+
(`X`) have a member (or an overloaded set of members) with the
288+
given name, and that the type of that member be bound to the second
289+
type (`Y`). There are two flavors of member constraint: value
290+
member constraints, which refer to the member in an expression
291+
context, and type member constraints, which refer to the member in a
292+
type context (and therefore can only refer to types).
293+
294+
### Disjunction
295+
296+
A constraint that is the disjunction of two or more constraints.
297+
Disjunctions are used to model overload sets, or different potential
298+
conversions, each of which might resolve in a (different) solution.
299+
300+
### Conjunction
301+
302+
A constraint that is the conjunction of two or more other
303+
constraints. We solve the first constraint first, and then the second,
304+
and so on, in order. Conjunctions are used to model multi-statement
305+
closures, as well as `if` and `switch` expressions, where type
306+
information flows in one direction only.
241307

242308
### Constraint Generation
243309

0 commit comments

Comments
 (0)