Skip to content

Commit 1ab367b

Browse files
authored
Merge pull request #19500 from lorentey/updateValue-but-not-the-key
[stdlib] Dictionary.updateValue(_:,forKey:): Don’t overwrite the existing key
2 parents 698dd39 + a293ce1 commit 1ab367b

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

stdlib/public/core/NativeDictionary.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,6 @@ extension _NativeDictionary { // Insertions
413413
if found {
414414
let oldValue = (_values + index.bucket).move()
415415
(_values + index.bucket).initialize(to: value)
416-
// FIXME: Replacing the old key with the new is unnecessary, unintuitive,
417-
// and actively harmful to some usecases. We shouldn't do it.
418-
// rdar://problem/32144087
419-
(_keys + index.bucket).pointee = key
420416
return oldValue
421417
}
422418
_insert(at: index, key: key, value: value)
@@ -432,10 +428,6 @@ extension _NativeDictionary { // Insertions
432428
let (index, found) = mutatingFind(key, isUnique: isUnique)
433429
if found {
434430
(_values + index.bucket).pointee = value
435-
// FIXME: Replacing the old key with the new is unnecessary, unintuitive,
436-
// and actively harmful to some usecases. We shouldn't do it.
437-
// rdar://problem/32144087
438-
(_keys + index.bucket).pointee = key
439431
} else {
440432
_insert(at: index, key: key, value: value)
441433
}

validation-test/stdlib/Dictionary.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ DictionaryTestSuite.test("COW.Fast.UpdateValueForKeyDoesNotReallocate") {
411411
}
412412
}
413413

414-
DictionaryTestSuite.test("COW.Slow.AddDoesNotReallocate") {
414+
DictionaryTestSuite.test("COW.Slow.UpdateValueForKeyDoesNotReallocate") {
415415
do {
416416
var d1 = getCOWSlowDictionary()
417417
let identity1 = d1._rawIdentifier()
@@ -4642,6 +4642,32 @@ DictionaryTestSuite.test("removeAt") {
46424642
}
46434643
}
46444644

4645+
DictionaryTestSuite.test("updateValue") {
4646+
let key1 = TestKeyTy(42)
4647+
let key2 = TestKeyTy(42)
4648+
let value1 = TestValueTy(1)
4649+
let value2 = TestValueTy(2)
4650+
4651+
var d: [TestKeyTy: TestValueTy] = [:]
4652+
4653+
expectNil(d.updateValue(value1, forKey: key1))
4654+
4655+
expectEqual(d.count, 1)
4656+
let index1 = d.index(forKey: key2)
4657+
expectNotNil(index1)
4658+
expectTrue(d[index1!].key === key1)
4659+
expectTrue(d[index1!].value === value1)
4660+
4661+
expectTrue(d.updateValue(value2, forKey: key2) === value1)
4662+
4663+
expectEqual(d.count, 1)
4664+
let index2 = d.index(forKey: key2)
4665+
expectEqual(index1, index2)
4666+
// We expect updateValue to keep the original key in place.
4667+
expectTrue(d[index2!].key === key1) // Not key2
4668+
expectTrue(d[index2!].value === value2)
4669+
}
4670+
46454671
DictionaryTestSuite.test("localHashSeeds") {
46464672
// With global hashing, copying elements in hash order between hash tables
46474673
// can become quadratic. (See https://bugs.swift.org/browse/SR-3268)

0 commit comments

Comments
 (0)