From 86a316fe422993da3f9cc1adb1fb32587f9e5d74 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Tue, 14 Jan 2025 11:24:20 +0000 Subject: [PATCH 1/5] Fix compiling on 6.1 Motivation: Swift 6.1 nightlies have added many new warnings and errors to NIO. This patch resolves all but one of them. Modifications: - Clean up missing imports - Move away from @_implementationOnly where necessary - Fix a few things where Sendable mismatches were present. Result: Clean compile again --- .../NIOCore/AsyncChannel/AsyncChannelHandler.swift | 2 +- .../NIOThrowingAsyncSequenceProducer.swift | 2 +- Sources/NIOCore/EventLoop.swift | 5 +++-- Sources/NIOCore/FileRegion.swift | 3 --- Sources/NIOEmbedded/AsyncTestingEventLoop.swift | 9 +++++---- Sources/NIOHTTP1/HTTPDecoder.swift | 11 ++++++++--- Sources/NIOPosix/DatagramVectorReadManager.swift | 1 + Sources/NIOPosix/PendingDatagramWritesManager.swift | 1 + Sources/NIOPosix/SelectorKqueue.swift | 1 + Tests/NIOPosixTests/HappyEyeballsTest.swift | 1 + Tests/NIOPosixTests/MulticastTest.swift | 2 +- 11 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift b/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift index 149c0ff5ea4..726cb8c4d8c 100644 --- a/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift +++ b/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -import DequeModule +@preconcurrency import DequeModule /// A ``ChannelHandler`` that is used to transform the inbound portion of a NIO /// ``Channel`` into an asynchronous sequence that supports back-pressure. It's also used diff --git a/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift b/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift index b807f6f4079..70f93327068 100644 --- a/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift +++ b/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -import DequeModule +@preconcurrency import DequeModule import NIOConcurrencyHelpers /// This is an `AsyncSequence` that supports a unicast `AsyncIterator`. diff --git a/Sources/NIOCore/EventLoop.swift b/Sources/NIOCore/EventLoop.swift index 021725af97f..1b619a3b0f4 100644 --- a/Sources/NIOCore/EventLoop.swift +++ b/Sources/NIOCore/EventLoop.swift @@ -761,12 +761,13 @@ extension EventLoop { /// - Returns: An `EventLoopFuture` containing the result of `task`'s execution. @inlinable @preconcurrency - public func submit(_ task: @escaping @Sendable () throws -> T) -> EventLoopFuture { + public func submit(_ task: @escaping @Sendable () throws -> T) -> EventLoopFuture { let promise: EventLoopPromise = makePromise(file: #fileID, line: #line) self.execute { do { - promise.succeed(try task()) + // UnsafeUnchecked is allowed here because we know we are on the EL. + promise.assumeIsolatedUnsafeUnchecked().succeed(try task()) } catch let err { promise.fail(err) } diff --git a/Sources/NIOCore/FileRegion.swift b/Sources/NIOCore/FileRegion.swift index 1b1f1c5b032..7ceaacd5dfc 100644 --- a/Sources/NIOCore/FileRegion.swift +++ b/Sources/NIOCore/FileRegion.swift @@ -93,9 +93,6 @@ public struct FileRegion: Sendable { } } -@available(*, unavailable) -extension FileRegion: Sendable {} - extension FileRegion { /// Create a new `FileRegion` forming a complete file. /// diff --git a/Sources/NIOEmbedded/AsyncTestingEventLoop.swift b/Sources/NIOEmbedded/AsyncTestingEventLoop.swift index 3321a6a601a..b0ee04036e8 100644 --- a/Sources/NIOEmbedded/AsyncTestingEventLoop.swift +++ b/Sources/NIOEmbedded/AsyncTestingEventLoop.swift @@ -131,7 +131,7 @@ public final class NIOAsyncTestingEventLoop: EventLoop, @unchecked Sendable { self.scheduledTasks.removeFirst { $0.id == taskID } } - private func insertTask( + private func insertTask( taskID: UInt64, deadline: NIODeadline, promise: EventLoopPromise, @@ -145,7 +145,8 @@ public final class NIOAsyncTestingEventLoop: EventLoop, @unchecked Sendable { insertOrder: self.nextTaskNumber(), task: { do { - promise.succeed(try task()) + // UnsafeUnchecked is acceptable because we know we're in the loop here. + promise.assumeIsolatedUnsafeUnchecked().succeed(try task()) } catch let err { promise.fail(err) } @@ -159,7 +160,7 @@ public final class NIOAsyncTestingEventLoop: EventLoop, @unchecked Sendable { /// - see: `EventLoop.scheduleTask(deadline:_:)` @discardableResult @preconcurrency - public func scheduleTask( + public func scheduleTask( deadline: NIODeadline, _ task: @escaping @Sendable () throws -> T ) -> Scheduled { @@ -201,7 +202,7 @@ public final class NIOAsyncTestingEventLoop: EventLoop, @unchecked Sendable { /// - see: `EventLoop.scheduleTask(in:_:)` @discardableResult @preconcurrency - public func scheduleTask(in: TimeAmount, _ task: @escaping @Sendable () throws -> T) -> Scheduled { + public func scheduleTask(in: TimeAmount, _ task: @escaping @Sendable () throws -> T) -> Scheduled { self.scheduleTask(deadline: self.now + `in`, task) } diff --git a/Sources/NIOHTTP1/HTTPDecoder.swift b/Sources/NIOHTTP1/HTTPDecoder.swift index a38c775cf4b..7e5589bcd78 100644 --- a/Sources/NIOHTTP1/HTTPDecoder.swift +++ b/Sources/NIOHTTP1/HTTPDecoder.swift @@ -12,7 +12,12 @@ // //===----------------------------------------------------------------------===// +#if compiler(>=6.1) +private import CNIOLLHTTP +#else @_implementationOnly import CNIOLLHTTP +#endif + import NIOCore extension UnsafeMutablePointer where Pointee == llhttp_t { @@ -631,7 +636,7 @@ public final class HTTPDecoder: ByteToMessageDecoder, HTTPDecoderDelega self.url = String(decoding: bytes, as: Unicode.UTF8.self) } - func didFinishHead( + fileprivate func didFinishHead( versionMajor: Int, versionMinor: Int, isUpgrade: Bool, @@ -815,7 +820,7 @@ extension HTTPParserError { /// - Parameter fromCHTTPParserErrno: The error from the underlying library. /// - Returns: The corresponding `HTTPParserError`, or `nil` if there is no /// corresponding error. - static func httpError(fromCHTTPParserErrno: llhttp_errno_t) -> HTTPParserError? { + fileprivate static func httpError(fromCHTTPParserErrno: llhttp_errno_t) -> HTTPParserError? { switch fromCHTTPParserErrno { case HPE_INTERNAL: return .invalidInternalState @@ -874,7 +879,7 @@ extension HTTPMethod { /// /// - Parameter httpParserMethod: The method returned by `http_parser`. /// - Returns: The corresponding `HTTPMethod`. - static func from(httpParserMethod: llhttp_method) -> HTTPMethod { + fileprivate static func from(httpParserMethod: llhttp_method) -> HTTPMethod { switch httpParserMethod { case HTTP_DELETE: return .DELETE diff --git a/Sources/NIOPosix/DatagramVectorReadManager.swift b/Sources/NIOPosix/DatagramVectorReadManager.swift index 7f6ced454e2..88224bf1dd6 100644 --- a/Sources/NIOPosix/DatagramVectorReadManager.swift +++ b/Sources/NIOPosix/DatagramVectorReadManager.swift @@ -11,6 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +import CNIODarwin import CNIOLinux import NIOCore diff --git a/Sources/NIOPosix/PendingDatagramWritesManager.swift b/Sources/NIOPosix/PendingDatagramWritesManager.swift index 8c058bd4e44..e9f201ce90d 100644 --- a/Sources/NIOPosix/PendingDatagramWritesManager.swift +++ b/Sources/NIOPosix/PendingDatagramWritesManager.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import Atomics +import CNIODarwin import CNIOLinux import NIOCore diff --git a/Sources/NIOPosix/SelectorKqueue.swift b/Sources/NIOPosix/SelectorKqueue.swift index 4c45dd15997..34651bd4932 100644 --- a/Sources/NIOPosix/SelectorKqueue.swift +++ b/Sources/NIOPosix/SelectorKqueue.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import NIOConcurrencyHelpers import NIOCore #if canImport(Darwin) diff --git a/Tests/NIOPosixTests/HappyEyeballsTest.swift b/Tests/NIOPosixTests/HappyEyeballsTest.swift index 29f35820f81..7e91b60a6bf 100644 --- a/Tests/NIOPosixTests/HappyEyeballsTest.swift +++ b/Tests/NIOPosixTests/HappyEyeballsTest.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import CNIOLinux import NIOEmbedded import XCTest diff --git a/Tests/NIOPosixTests/MulticastTest.swift b/Tests/NIOPosixTests/MulticastTest.swift index c9ae19d2914..e2fe3a8b05a 100644 --- a/Tests/NIOPosixTests/MulticastTest.swift +++ b/Tests/NIOPosixTests/MulticastTest.swift @@ -11,7 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// - +import CNIOLinux import NIOCore import NIOPosix import XCTest From 139e637c105723a33f5e4d3f243cc50dcf5b3647 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Tue, 14 Jan 2025 12:04:15 +0000 Subject: [PATCH 2/5] Fix the remaining --- Package.swift | 1 + Sources/NIOPosix/SelectableEventLoop.swift | 2 +- Tests/NIOPosixTests/PendingDatagramWritesManagerTests.swift | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 610fbf6dbdc..e83fb10646c 100644 --- a/Package.swift +++ b/Package.swift @@ -443,6 +443,7 @@ let package = Package( "NIOConcurrencyHelpers", "NIOEmbedded", "CNIOLinux", + "CNIODarwin", "NIOTLS", ] ), diff --git a/Sources/NIOPosix/SelectableEventLoop.swift b/Sources/NIOPosix/SelectableEventLoop.swift index 9449d629782..04e0cc0bbde 100644 --- a/Sources/NIOPosix/SelectableEventLoop.swift +++ b/Sources/NIOPosix/SelectableEventLoop.swift @@ -60,7 +60,7 @@ public protocol NIOEventLoopMetricsDelegate: Sendable { /// The whole processing of I/O and tasks is done by a `NIOThread` that is tied to the `SelectableEventLoop`. This `NIOThread` /// is guaranteed to never change! @usableFromInline -internal final class SelectableEventLoop: EventLoop { +internal final class SelectableEventLoop: EventLoop, @unchecked Sendable { static let strictModeEnabled: Bool = { switch getenv("SWIFTNIO_STRICT").map({ String.init(cString: $0).lowercased() }) { diff --git a/Tests/NIOPosixTests/PendingDatagramWritesManagerTests.swift b/Tests/NIOPosixTests/PendingDatagramWritesManagerTests.swift index b94e37cf94a..dee71c2a6ef 100644 --- a/Tests/NIOPosixTests/PendingDatagramWritesManagerTests.swift +++ b/Tests/NIOPosixTests/PendingDatagramWritesManagerTests.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import CNIODarwin import CNIOLinux import NIOEmbedded import XCTest From 7e5ff760421446e763e5fa71731cf41599841f3e Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Tue, 14 Jan 2025 14:44:57 +0000 Subject: [PATCH 3/5] Remove preconcurrency --- Package.swift | 2 +- Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift | 2 +- .../AsyncSequences/NIOThrowingAsyncSequenceProducer.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Package.swift b/Package.swift index e83fb10646c..14f9183f9c8 100644 --- a/Package.swift +++ b/Package.swift @@ -559,7 +559,7 @@ let package = Package( if Context.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { package.dependencies += [ .package(url: "https://github.com/apple/swift-atomics.git", from: "1.1.0"), - .package(url: "https://github.com/apple/swift-collections.git", from: "1.0.2"), + .package(url: "https://github.com/apple/swift-collections.git", from: "1.1.0"), .package(url: "https://github.com/apple/swift-system.git", from: "1.4.0"), ] } else { diff --git a/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift b/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift index 726cb8c4d8c..149c0ff5ea4 100644 --- a/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift +++ b/Sources/NIOCore/AsyncChannel/AsyncChannelHandler.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -@preconcurrency import DequeModule +import DequeModule /// A ``ChannelHandler`` that is used to transform the inbound portion of a NIO /// ``Channel`` into an asynchronous sequence that supports back-pressure. It's also used diff --git a/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift b/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift index 70f93327068..b807f6f4079 100644 --- a/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift +++ b/Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -@preconcurrency import DequeModule +import DequeModule import NIOConcurrencyHelpers /// This is an `AsyncSequence` that supports a unicast `AsyncIterator`. From 4229b36e1e0828cac6f1cb5dc17cb0b3844e9cd9 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Tue, 14 Jan 2025 14:56:31 +0000 Subject: [PATCH 4/5] Formatting --- Sources/NIOHTTP1/HTTPDecoder.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/NIOHTTP1/HTTPDecoder.swift b/Sources/NIOHTTP1/HTTPDecoder.swift index 7e5589bcd78..ade277559fd 100644 --- a/Sources/NIOHTTP1/HTTPDecoder.swift +++ b/Sources/NIOHTTP1/HTTPDecoder.swift @@ -12,14 +12,13 @@ // //===----------------------------------------------------------------------===// +import NIOCore #if compiler(>=6.1) private import CNIOLLHTTP #else @_implementationOnly import CNIOLLHTTP #endif -import NIOCore - extension UnsafeMutablePointer where Pointee == llhttp_t { /// Returns the `KeepAliveState` for the current message that is parsed. fileprivate var keepAliveState: KeepAliveState { From 542eb22c1ddb2d417925aba3db0fa37b69bc0b4a Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Tue, 14 Jan 2025 15:00:29 +0000 Subject: [PATCH 5/5] Apparently still formatting --- Sources/NIOHTTP1/HTTPDecoder.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/NIOHTTP1/HTTPDecoder.swift b/Sources/NIOHTTP1/HTTPDecoder.swift index ade277559fd..7633198918d 100644 --- a/Sources/NIOHTTP1/HTTPDecoder.swift +++ b/Sources/NIOHTTP1/HTTPDecoder.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import NIOCore + #if compiler(>=6.1) private import CNIOLLHTTP #else