You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Swift 5.5.1 in Xcode 13.1 (13A1030d)
swift-driver version: 1.26.9 Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6)
Target: x86_64-apple-macosx12.0
Additional Detail from JIRA
Votes
1
Component/s
Compiler
Labels
Bug
Assignee
None
Priority
Medium
md5: f873aa77f48f33dc661c3181887b2ad6
Issue Description:
In the swift-collections package, we have an OrderedDictionary type that provides a unique-keys-and-values initializer:
extension OrderedDictionary {
public init<S: Sequence>(
uniqueKeysWithValues keysAndValues: S
) where S.Element == (Key, Value) { ... }
}
I think it is reasonable to expect that we should be able to pass a standard `Dictionary` to this initializer. Alas, this doesn't work, as `Dictionary` uses the labeled tuple `(key: Key, value: Value)` as its `Element` type, and the tuple labels are evidently considered significant in this case. Simplified example:
func test<S: Sequence>(_ value: S)
where S.Element == (Int, String) {
print(1)
}
let d = [1: "one", 2: "two", 3: "three"]
test(d)
// error: Global function 'test' requires the types 'Dictionary<Int, String>.Element' (aka '(key: Int, value: String)') and '(Int, String)' be equivalent
To work around this issue, we added an overload for the initializer that took a sequence with a labeled tuple:
func test<S: Sequence>(_ value: S)
where S.Element == (Int, String) {
print(1)
}
func test<S: Sequence>(_ value: S)
where S.Element == (key: Int, value: String) {
print(2)
}
let d = [1: "one", 2: "two", 3: "three"]
test(d) // OK, prints 2
This resolved this usability issue, but it turns out it introduces a bogus ambiguity in certain cases where type inference is used: (see apple/swift-collections#125
func test<S: Sequence>(_ value: S)
where S.Element == (Int, String) {
print(1)
}
func test<S: Sequence>(_ value: S)
where S.Element == (key: Int, value: String) {
print(2)
}
test([1, 2, 3].map { ($0, "\($0)") })
// error: ambiguous use of 'test'
test([1, 2, 3].map { (key: $0, value: "\($0)") })
// error: ambiguous use of 'test'
Removing either of the overloads allows both expressions to successfully type check. (But breaks the case where inference isn't used.)
It seems to me that there is no ambiguity here, even if we allow tuple labels to be inferred in this case – the type checker should prefer the overload that has matching labels.
The text was updated successfully, but these errors were encountered:
(We could use the `@_disfavoredOverload` attribute on one of the initializers to work around this issue; however, that attribute isn't public, and I think ideally this ought to work without such workarounds.)
Environment
Swift 5.5.1 in Xcode 13.1 (13A1030d)
swift-driver version: 1.26.9 Apple Swift version 5.5.1 (swiftlang-1300.0.31.4 clang-1300.0.29.6)
Target: x86_64-apple-macosx12.0
Additional Detail from JIRA
md5: f873aa77f48f33dc661c3181887b2ad6
Issue Description:
In the swift-collections package, we have an OrderedDictionary type that provides a unique-keys-and-values initializer:
I think it is reasonable to expect that we should be able to pass a standard `Dictionary` to this initializer. Alas, this doesn't work, as `Dictionary` uses the labeled tuple `(key: Key, value: Value)` as its `Element` type, and the tuple labels are evidently considered significant in this case. Simplified example:
To work around this issue, we added an overload for the initializer that took a sequence with a labeled tuple:
This resolved this usability issue, but it turns out it introduces a bogus ambiguity in certain cases where type inference is used: (see apple/swift-collections#125
Removing either of the overloads allows both expressions to successfully type check. (But breaks the case where inference isn't used.)
It seems to me that there is no ambiguity here, even if we allow tuple labels to be inferred in this case – the type checker should prefer the overload that has matching labels.
The text was updated successfully, but these errors were encountered: