Skip to content

Commit ac0c075

Browse files
committed
[HashCollections] Ensure self doesn’t get destroyed before we’re done working with it
The HashCollections module includes several mutating methods that dereference unmanaged references to internal nodes after the last usage of `self`. Prevent the compiler from destroying `self` before we’re done working within descendants of its tree.
1 parent 1ea846b commit ac0c075

File tree

3 files changed

+6
-0
lines changed

3 files changed

+6
-0
lines changed

Sources/HashTreeCollections/TreeDictionary/TreeDictionary.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ extension TreeDictionary {
345345
public mutating func updateValue(
346346
_ value: __owned Value, forKey key: Key
347347
) -> Value? {
348+
defer { _fixLifetime(self) }
348349
let hash = _Hash(key)
349350
let r = _root.updateValue(.top, forKey: key, hash) {
350351
$0.initialize(to: (key, value))
@@ -364,6 +365,7 @@ extension TreeDictionary {
364365
internal mutating func _updateValue(
365366
_ value: __owned Value, forKey key: Key
366367
) -> Bool {
368+
defer { _fixLifetime(self) }
367369
let hash = _Hash(key)
368370
let r = _root.updateValue(.top, forKey: key, hash) {
369371
$0.initialize(to: (key, value))
@@ -470,6 +472,7 @@ extension TreeDictionary {
470472
default defaultValue: @autoclosure () -> Value,
471473
with body: (inout Value) throws -> R
472474
) rethrows -> R {
475+
defer { _fixLifetime(self) }
473476
let hash = _Hash(key)
474477
let r = _root.updateValue(.top, forKey: key, hash) {
475478
$0.initialize(to: (key, defaultValue()))

Sources/HashTreeCollections/TreeSet/TreeSet+Extras.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ extension TreeSet {
5454
/// - Complexity: O(log(`count`)) if set storage might be shared; O(1)
5555
/// otherwise.
5656
public mutating func update(_ member: Element, at index: Index) -> Element {
57+
defer { _fixLifetime(self) }
5758
precondition(_isValid(index), "Invalid index")
5859
precondition(index._path.isOnItem, "Can't get element at endIndex")
5960
_invalidateIndices()

Sources/HashTreeCollections/TreeSet/TreeSet+SetAlgebra basics.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ extension TreeSet: SetAlgebra {
5151
public mutating func insert(
5252
_ newMember: __owned Element
5353
) -> (inserted: Bool, memberAfterInsert: Element) {
54+
defer { _fixLifetime(self) }
5455
let hash = _Hash(newMember)
5556
let r = _root.insert(.top, (newMember, ()), hash)
5657
if r.inserted {
@@ -117,6 +118,7 @@ extension TreeSet: SetAlgebra {
117118
@discardableResult
118119
@inlinable
119120
public mutating func update(with newMember: __owned Element) -> Element? {
121+
defer { _fixLifetime(self) }
120122
let hash = _Hash(newMember)
121123
let r = _root.updateValue(.top, forKey: newMember, hash) {
122124
$0.initialize(to: (newMember, ()))

0 commit comments

Comments
 (0)