Skip to content

Commit c99e9e4

Browse files
committed
[embedded] Support Dictionary.init(uniqueKeysWithValues:) in Embedded Swift
1 parent 5770d59 commit c99e9e4

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

stdlib/public/core/Dictionary.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,13 @@ public struct Dictionary<Key: Hashable, Value> {
486486
// error instead of calling fatalError() directly because we want the
487487
// message to include the duplicate key, and the closure only has access to
488488
// the conflicting values.
489-
try! native.merge(
489+
native.merge(
490490
keysAndValues,
491491
isUnique: true,
492-
uniquingKeysWith: { _, _ in throw _MergeError.keyCollision })
492+
uniquingKeysWith: { _, _ throws(_MergeError) in
493+
throw _MergeError.keyCollision
494+
}
495+
)
493496
self.init(_native: native)
494497
}
495498

stdlib/public/core/NativeDictionary.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,33 @@ extension _NativeDictionary { // High-level operations
791791
}
792792
}
793793

794+
@inlinable
795+
internal mutating func merge<S: Sequence>(
796+
_ keysAndValues: __owned S,
797+
isUnique: Bool,
798+
uniquingKeysWith combine: (Value, Value) throws(_MergeError) -> Value
799+
) where S.Element == (Key, Value) {
800+
var isUnique = isUnique
801+
for (key, value) in keysAndValues {
802+
let (bucket, found) = mutatingFind(key, isUnique: isUnique)
803+
isUnique = true
804+
if found {
805+
do throws(_MergeError) {
806+
let newValue = try combine(uncheckedValue(at: bucket), value)
807+
_values[bucket.offset] = newValue
808+
} catch {
809+
#if !$Embedded
810+
fatalError("Duplicate values for key: '\(key)'")
811+
#else
812+
fatalError("Duplicate values for a key in a Dictionary")
813+
#endif
814+
}
815+
} else {
816+
_insert(at: bucket, key: key, value: value)
817+
}
818+
}
819+
}
820+
794821
@inlinable
795822
@inline(__always)
796823
internal init<S: Sequence>(

test/embedded/dict-init.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-run-simple-swift(-enable-experimental-feature Embedded -wmo) | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: executable_test
5+
// REQUIRES: swift_feature_Embedded
6+
7+
public func foo() {
8+
let d = Dictionary<Int, StaticString>.init(uniqueKeysWithValues: [(10, "hello"), (20, "world")])
9+
print(d[10]!)
10+
print(d[20]!)
11+
}
12+
13+
foo()
14+
15+
// CHECK: hello
16+
// CHECK: world

0 commit comments

Comments
 (0)