Skip to content

Commit f2048ce

Browse files
authored
Merge pull request #19638 from lorentey/merge-double-deinit
2 parents 5414747 + 2b7ef24 commit f2048ce

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

stdlib/public/core/NativeDictionary.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,8 @@ extension _NativeDictionary { // High-level operations
613613
isUnique = true
614614
if found {
615615
do {
616-
let v = (_values + bucket.offset).move()
617-
let newValue = try combine(v, value)
618-
(_values + bucket.offset).initialize(to: newValue)
616+
let newValue = try combine(uncheckedValue(at: bucket), value)
617+
_values[bucket.offset] = newValue
619618
} catch _MergeError.keyCollision {
620619
fatalError("Duplicate values for key: '\(key)'")
621620
}

validation-test/stdlib/Dictionary.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,30 @@ DictionaryTestSuite.test("COW.Fast.MergeDictionaryDoesNotReallocate")
734734
}
735735
}
736736

737+
738+
DictionaryTestSuite.test("Merge.ThrowingIsSafe") {
739+
var d: [TestKeyTy: TestValueTy] = [
740+
TestKeyTy(10): TestValueTy(1),
741+
TestKeyTy(20): TestValueTy(2),
742+
TestKeyTy(30): TestValueTy(3),
743+
]
744+
745+
let d2: [TestKeyTy: TestValueTy] = [
746+
TestKeyTy(40): TestValueTy(4),
747+
TestKeyTy(50): TestValueTy(5),
748+
TestKeyTy(10): TestValueTy(1),
749+
]
750+
751+
struct TE: Error {}
752+
do {
753+
// Throwing must not leave the dictionary in an inconsistent state.
754+
try d.merge(d2) { v1, v2 in throw TE() }
755+
expectTrue(false, "merge did not throw")
756+
} catch {
757+
expectTrue(error is TE)
758+
}
759+
}
760+
737761
DictionaryTestSuite.test("COW.Fast.DefaultedSubscriptDoesNotReallocate") {
738762
do {
739763
var d1 = getCOWFastDictionary()

0 commit comments

Comments
 (0)