From 985eb24e88ed727f0712105eb44a0a2e3f1bfc6b Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 5 Feb 2023 11:04:11 -0500 Subject: [PATCH] Remove workaround for compiler bug breaking constrained existential types on iOS 15 release builds Closes #178 --- Tusker/MultiThreadDictionary.swift | 47 ++++++++++-------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/Tusker/MultiThreadDictionary.swift b/Tusker/MultiThreadDictionary.swift index 26392bb5..2b0147fa 100644 --- a/Tusker/MultiThreadDictionary.swift +++ b/Tusker/MultiThreadDictionary.swift @@ -13,20 +13,24 @@ import os // to make the lock semantics more clear @available(iOS, obsoleted: 16.0) class MultiThreadDictionary { - private let lock: LockHolder<[AnyHashable: Any]> + private let lock: any Lock<[Key: Value]> init() { - self.lock = LockHolder(initialState: [:]) + if #available(iOS 16.0, *) { + self.lock = OSAllocatedUnfairLock(initialState: [:]) + } else { + self.lock = UnfairLock(initialState: [:]) + } } subscript(key: Key) -> Value? { get { - return try! lock.withLock { dict in + return lock.withLock { dict in dict[key] - } as! Value? + } } set(value) { - _ = try! lock.withLock { dict in + _ = lock.withLock { dict in dict[key] = value } } @@ -34,40 +38,21 @@ class MultiThreadDictionary { /// If the result of this function is unused, it is preferable to use `removeValueWithoutReturning` as it executes asynchronously and doesn't block the calling thread. func removeValue(forKey key: Key) -> Value? { - return try! lock.withLock { dict in + return lock.withLock { dict in dict.removeValue(forKey: key) - } as! Value? + } } func contains(key: Key) -> Bool { - return try! lock.withLock { dict in + return lock.withLock { dict in dict.keys.contains(key) - } as! Bool + } } // TODO: this should really be throws/rethrows but the stupid type-erased lock makes that not possible - func withLock(_ body: @Sendable (inout [Key: Value]) -> R) -> R where R: Sendable { - return try! lock.withLock { dict in - var downcasted = dict as! [Key: Value] - defer { dict = downcasted } - return body(&downcasted) - } as! R - } -} - -// this type erased struct is necessary due to a compiler bug with stored constrained existential types -// see https://github.com/apple/swift/issues/61403 -// see #178 -fileprivate struct LockHolder { - let withLock: (_ body: @Sendable (inout State) throws -> any Sendable) throws -> any Sendable - - init(initialState: State) { - if #available(iOS 16.0, *) { - let lock = OSAllocatedUnfairLock(initialState: initialState) - self.withLock = lock.withLock(_:) - } else { - let lock = UnfairLock(initialState: initialState) - self.withLock = lock.withLock(_:) + func withLock(_ body: @Sendable (inout [Key: Value]) throws -> R) rethrows -> R where R: Sendable { + return try lock.withLock { dict in + return try body(&dict) } } }