Skip to content

Commit 80b0888

Browse files
committed
Simplify the description of same-type requirements involving parameter packs.
1 parent 38c3871 commit 80b0888

File tree

1 file changed

+13
-35
lines changed

1 file changed

+13
-35
lines changed

proposals/NNNN-parameter-packs.md

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -365,47 +365,28 @@ All existing kinds of generic requirements generalize to type parameter packs. S
365365
func variadic<each S>(_: repeat each S) where each S: Sequence { ... }
366366
```
367367

368-
A valid substitution for the above might replace `S` with `{Array<Int>, Set<String>}`.
368+
A valid substitution for the above might replace `S` with `{Array<Int>, Set<String>}`. Expanding the substitution into the requirement `each S: Sequence` conceptually produces the following conformance requirements: `Array<Int>: Sequence, Set<String>: Sequence`.
369369

370-
2. A same-type requirement where one side is a type parameter pack and the other type is a concrete type that does not capture any type parameter packs is interpreted as constraining each element of the replacement type pack to _the same_ concrete type:
370+
2. A same-type requirement where one side is a type parameter pack and the other type is a scalar type that does not capture any type parameter packs is interpreted as constraining each element of the replacement type pack to _the same_ scalar type:
371371

372372
```swift
373373
func variadic<each S: Sequence, T>(_: repeat each S) where (each S).Element == T {}
374374
```
375375

376-
This is called a _concrete same-element requirement_.
376+
This is called a _same-element requirement_.
377377

378378
A valid substitution for the above might replace `S` with `{Array<Int>, Set<Int>}`, and `T` with `Int`.
379379

380-
3. A same-type requirement where one side is a type parameter pack and the other type is a scalar type parameter is interpreted as constraining each element of the replacement type pack to the type parameter:
381380

382-
```swift
383-
func variadic<each S: Sequence, each T>(_: repeat each S) where (each S).Element == each T {}
384-
```
385-
386-
This is called an _abstract same-element requirement_.
387-
388-
A valid substitution for the above might replace `S` with `{Array<Int>, Set<String>}`, and `T` with `{Int, String}`.
389-
390-
4. A same-type requirement where one side is a type parameter pack and the other side is a concrete type capturing at least one type parameter pack is interpreted as expanding the concrete type and constraining each element of the replacement type pack to the concrete element type:
381+
3. A same-type requirement where each side is a pattern type that captures at least one type parameter pack is interpreted as expanding the type packs on each side of the requirement, equating each element pair-wise.
391382

392383
```swift
393384
func variadic<each S: Sequence, each T>(_: repeat each S) where (each S).Element == Array<each T> {}
394385
```
395386

396-
This is called a _concrete same-type pack requirement_.
397-
398-
A valid substitution for the above might replace `S` with `{Array<Array<Int>>, Set<Array<String>>}`, and `T` with `{Int, String}`.
387+
This is called a _same-type-pack requirement_.
399388

400-
5. A same-type requirement where both sides are type parameter packs constrains the elements of the replacement type pack element-wise:
401-
402-
```swift
403-
func append<each S: Sequence, each T: Sequence>(_: repeat each S, _: repeat each T) where (each T).Element == (each S).Element {}
404-
```
405-
406-
This is called an _abstract same-type pack requirement_.
407-
408-
A valid substitution for the above would replace `S` with `{Array<Int>, Set<String>}`, and `T` with `{Set<Int>, Array<String>}`.
389+
A valid substitution for the above might replace `S` with `{Array<Array<Int>>, Set<Array<String>>}`, and `T` with `{Int, String}`. Expanding `(each S).Element == Array<each T>` will produce the following list of same-type requirements: `Array<Array<Int>.Element == Array<Int>, Set<Array<String>>.Element == String`.
409390

410391
There is an additional kind of requirement called a _same-shape requirement_. There is no surface syntax for spelling a same-shape requirement; they are always inferred, as described in the next section.
411392

@@ -417,22 +398,19 @@ There is an additional kind of requirement called a _same-shape requirement_. Th
417398

418399
A same-shape requirement states that two type parameter packs have the same number of elements, with pack expansion types occurring at identical positions.
419400

420-
At this time, we are not proposing a spelling for same-shape requirements in the surface language, since we do not believe it is necessary given the inference behavior outlined below. However, we will use the notation `shape(T) == shape(U)` to denote same-shape requirements in this proposal.
401+
This proposal does not include a spelling for same-shape requirements in the surface language; same-shape requirements are always inferred, and an explicit same-shape requirement syntax is a future direction. However, we will use the notation `shape(T) == shape(U)` to denote same-shape requirements in this proposal.
421402

422403
A same-shape requirement always relates two root type parameter packs. Member types always have the same shape as the root type parameter pack, so `shape(T.A) == shape(U.B)` reduces to `shape(T) == shape(U)`.
423404

424-
**Inference:** Same-shape requirements are inferred in one of three ways:
425-
426-
1. An abstract same-type requirement implies a same-shape requirement between two type parameter packs.
427-
428-
2. A concrete same-type requirement implies a same-shape requirement between the type parameter packs on the left hand side and all type parameter packs captured by the concrete type on the right hand side.
405+
**Inference:** Same-shape requirements are inferred in the following ways:
429406

430-
3. Finally, a same-shape requirement is inferred between each pair of type parameter packs captured by a pack expansion type appearing in certain positions.
407+
1. A same-type-pack requirement implies a same-shape requirement between all type parameter packs captured by the pattern types on each side of the requirement.
431408

432-
The following positions are subject to the same-shape requirement inference in Case 3:
409+
For example, given the parameter packs `<each First, each Second, each S: Sequence>`, the same-type-pack requirement `Pair<each First, each Second> == (each S).Element` implies `shape(First) == shape(Second), shape(First) == shape(S), shape(Second) == shape(S)`.
433410

434-
* all types appearing in the requirements of a trailing `where` clause of a generic function
435-
* the parameter types and return type of a generic function
411+
2. A same-shape requirement is inferred between each pair of type parameter packs captured by a pack expansion type appearing in the following positions
412+
* all types appearing in the requirements of a trailing `where` clause of a generic function
413+
* the parameter types and the return type of a generic function
436414

437415
Recall that if the pattern of a pack expansion type contains more than one type parameter pack, all type parameter packs must be known to have the same shape, as outlined in the [Type substitution](#type-substitution) section. Same-shape requirement inference ensures that these invariants are satisfied when the pack expansion type occurs in one of the two above positions.
438416

0 commit comments

Comments
 (0)