From 6630cc6c6f776cc8f4a06787e0ace18ea2bc3981 Mon Sep 17 00:00:00 2001 From: Franz Busch Date: Wed, 24 Jul 2024 10:35:35 +0200 Subject: [PATCH] Change `unsafeDownCast` to `as!` (#2802) # Motivation In Swift 5.10 the usage of `unsafeDownCast` can lead to a miss-compile which will result in bad runtime behaviour. # Modification This PR changes the `unsafeDownCast` to use a `as!` instead. This is safe and should result in the same performance when done with `ManagedBuffer` which is inlinable. # Result No more miss compiles in 5.10 --- Sources/NIOConcurrencyHelpers/NIOLock.swift | 5 ++++- Sources/NIOPosix/Pool.swift | 11 +++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Sources/NIOConcurrencyHelpers/NIOLock.swift b/Sources/NIOConcurrencyHelpers/NIOLock.swift index df04bb7736..21902e27d5 100644 --- a/Sources/NIOConcurrencyHelpers/NIOLock.swift +++ b/Sources/NIOConcurrencyHelpers/NIOLock.swift @@ -130,7 +130,10 @@ final class LockStorage: ManagedBuffer { let buffer = Self.create(minimumCapacity: 1) { _ in value } - let storage = unsafeDowncast(buffer, to: Self.self) + // Intentionally using a force cast here to avoid a miss compiliation in 5.10. + // This is as fast as an unsafeDownCast since ManagedBuffer is inlined and the optimizer + // can eliminate the upcast/downcast pair + let storage = buffer as! Self storage.withUnsafeMutablePointers { _, lockPtr in LockOperations.create(lockPtr) diff --git a/Sources/NIOPosix/Pool.swift b/Sources/NIOPosix/Pool.swift index e46f57537b..f4856a9dab 100644 --- a/Sources/NIOPosix/Pool.swift +++ b/Sources/NIOPosix/Pool.swift @@ -164,7 +164,11 @@ extension PooledBuffer { } // Here we set up our memory bindings. - let storage = unsafeDowncast(baseStorage, to: Self.self) + + // Intentionally using a force cast here to avoid a miss compiliation in 5.10. + // This is as fast as an unsafeDownCast since ManagedBuffer is inlined and the optimizer + // can eliminate the upcast/downcast pair + let storage = baseStorage as! Self storage.withUnsafeMutablePointers { headPointer, tailPointer in UnsafeRawPointer(tailPointer + headPointer.pointee.iovectorOffset).bindMemory( to: IOVector.self, @@ -277,7 +281,10 @@ struct PooledMsgBuffer: PoolElement { head } - let storage = unsafeDowncast(baseStorage, to: Self.self) + // Intentionally using a force cast here to avoid a miss compiliation in 5.10. + // This is as fast as an unsafeDownCast since ManagedBuffer is inlined and the optimizer + // can eliminate the upcast/downcast pair + let storage = baseStorage as! Self storage.withUnsafeMutablePointers { headPointer, tailPointer in UnsafeRawPointer(tailPointer + headPointer.pointee.msgHdrsOffset).bindMemory( to: MMsgHdr.self,