Skip to content

Commit b76dfc1

Browse files
committed
Add an overloading example with parameter packs that is ambiguous.
1 parent de4b6a2 commit b76dfc1

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

proposals/0393-parameter-packs.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func overload<T>(_: T) {}
561561
func overload<each T>(_: repeat each T) {}
562562
```
563563

564-
If the parameters of the scalar overload have the same or refined requirements as the parameter pack overload, the scalar overload is considered a subtype of the parameter pack overload, because the parameters of the scalar overload can be forwarded to the parameter pack overload. Generally, if a function call successfully type checks with two different overloads, the subtype is preferred. This effectively means that scalar overloads are preferred over parameter pack overloads when the scalar requirements meet the requirements of the parameter pack:
564+
If the parameters of the scalar overload have the same or refined requirements as the parameter pack overload, the scalar overload is considered a subtype of the parameter pack overload, because the parameters of the scalar overload can be forwarded to the parameter pack overload. Currently, if a function call successfully type checks with two different overloads, the subtype is preferred. This overload ranking rule generalizes to overloads with parameter packs, which effectively means that scalar overloads are preferred over parameter pack overloads when the scalar requirements meet the requirements of the parameter pack:
565565

566566
```swift
567567
func overload() {}
@@ -584,7 +584,27 @@ func overload<each T>(_: repeat each T) {}
584584
overload(1, "") // prefers the parameter pack overload because the scalar overload would require an existential conversion
585585
```
586586

587-
This overload resolution behavior enables library authors to introduce new function overloads using parameter packs that generalize existing fixed-arity overloads while preserving the overload resolution behavior of existing code.
587+
More complex scenarios can still result in ambiguities. For example, if multiple overloads match a function call, but each parameter list can be forwarded to the other, the call is ambiguous:
588+
589+
```swift
590+
func overload(_: repeat each T) {}
591+
func overload(vals: repeat each T) {}
592+
593+
overload() // error: ambiguous
594+
```
595+
596+
Similarly, if neither overload can forward their parameter lists to the other, the call is ambiguous:
597+
598+
```swift
599+
func overload<each T: BinaryInteger>(str: String, _: repeat each T) {}
600+
func overload<each U: StringProtocol>(str: repeat each U) {}
601+
602+
func test<Z: BinaryInteger & StringProtocol>(_ z: Z) {
603+
overload(str: "Hello, world!", z, z) // error: ambiguous
604+
}
605+
```
606+
607+
Generalizing the existing overload resolution ranking rules to parameter packs enables library authors to introduce new function overloads using parameter packs that generalize existing fixed-arity overloads while preserving the overload resolution behavior of existing code.
588608

589609
## Effect on ABI stability
590610

0 commit comments

Comments
 (0)