SwiftNIO is unusable with the aggresive `Sendable` checking in recent toolchains

Having upgraded from an october toolchain to a more recent december toolchain, i’m experiencing a deluge of Sendable-related warnings from SwiftNIO types in my codebase. common offenders so far include:

  • MultiThreadedEventLoopGroup
  • Channel
  • NIOSSLContext (from nio-ssl)
  • HTTPClient (from async-http-client)

anybody else know of a good workaround to deal with this?

I’ve had similar compilation failures with Swift for TensorFlow as early as Swift 5.4.

Can you produce the list of warnings? This might require work on our part.

Specifically what I care about is whether the usage site that causes the warning is in your code or ours. If it's in yours, you could try using @predatesConcurrency on your import to silence the warnings.

currently, i am getting usage site warnings:

remote.swift:14:13: warning: stored property 'threads' of 'Sendable'-conforming struct 'Remote' has non-sendable type 'MultiThreadedEventLoopGroup'
        let threads:MultiThreadedEventLoopGroup, 
            ^
.build/checkouts/swift-nio/Sources/NIOPosix/MultiThreadedEventLoopGroup.swift:54:20: note: class 'MultiThreadedEventLoopGroup' does not conform to the 'Sendable' protocol
public final class MultiThreadedEventLoopGroup: EventLoopGroup {
                   ^
remote.swift:15:13: warning: stored property 'security' of 'Sendable'-conforming struct 'Remote' has non-sendable type 'NIOSSLContext'
            security:NIOSSLContext, 
            ^
.build/checkouts/swift-nio-ssl/Sources/NIOSSL/SSLContext.swift:125:20: note: class 'NIOSSLContext' does not conform to the 'Sendable' protocol
public final class NIOSSLContext {
                   ^
remote.swift:18:13: warning: stored property 'http' of 'Sendable'-conforming struct 'Remote' has non-sendable type 'HTTPClient'
        let http:HTTPClient
            ^
.build/checkouts/async-http-client/Sources/AsyncHTTPClient/HTTPClient.swift:66:14: note: class 'HTTPClient' does not conform to the 'Sendable' protocol
public class HTTPClient {
             ^
io/fix/fix.swift:259:13: warning: stored property 'channel' of 'Sendable'-conforming generic struct 'Session' has non-sendable type 'Channel'
        let channel:Channel 
            ^
.build/checkouts/swift-nio/Sources/NIOCore/Channel.swift:105:17: note: protocol 'Channel' does not conform to the 'Sendable' protocol
public protocol Channel: AnyObject, ChannelOutboundInvoker {
                ^
io/websocket/websocket.swift:176:13: warning: stored property 'channel' of 'Sendable'-conforming generic struct 'Session' has non-sendable type 'Channel'
        let channel:Channel 
            ^
.build/checkouts/swift-nio/Sources/NIOCore/Channel.swift:105:17: note: protocol 'Channel' does not conform to the 'Sendable' protocol
public protocol Channel: AnyObject, ChannelOutboundInvoker {
                ^
io/websocket/websocket.swift:176:13: warning: stored property 'channel' of 'Sendable'-conforming generic struct 'Session' has non-sendable type 'Channel'
        let channel:Channel 
            ^
.build/checkouts/swift-nio/Sources/NIOCore/Channel.swift:105:17: note: protocol 'Channel' does not conform to the 'Sendable' protocol
public protocol Channel: AnyObject, ChannelOutboundInvoker {
                ^
io/websocket/websocket.swift:214:64: warning: cannot use parameter 'channel' with a non-sendable type 'Channel' from concurrently-executed code
                        try await connected(Self.init(channel: channel), control)
                                                               ^
.build/checkouts/swift-nio/Sources/NIOCore/Channel.swift:105:17: note: protocol 'Channel' does not conform to the 'Sendable' protocol
public protocol Channel: AnyObject, ChannelOutboundInvoker {
                ^
io/fix/fix.swift:259:13: warning: stored property 'channel' of 'Sendable'-conforming generic struct 'Session' has non-sendable type 'Channel'
        let channel:Channel 
            ^
.build/checkouts/swift-nio/Sources/NIOCore/Channel.swift:105:17: note: protocol 'Channel' does not conform to the 'Sendable' protocol
public protocol Channel: AnyObject, ChannelOutboundInvoker {
                ^
remote.swift:14:13: warning: stored property 'threads' of 'Sendable'-conforming struct 'Remote' has non-sendable type 'MultiThreadedEventLoopGroup'
        let threads:MultiThreadedEventLoopGroup, 
            ^
.build/checkouts/swift-nio/Sources/NIOPosix/MultiThreadedEventLoopGroup.swift:54:20: note: class 'MultiThreadedEventLoopGroup' does not conform to the 'Sendable' protocol
public final class MultiThreadedEventLoopGroup: EventLoopGroup {
                   ^
remote.swift:15:13: warning: stored property 'security' of 'Sendable'-conforming struct 'Remote' has non-sendable type 'NIOSSLContext'
            security:NIOSSLContext, 
            ^
.build/checkouts/swift-nio-ssl/Sources/NIOSSL/SSLContext.swift:125:20: note: class 'NIOSSLContext' does not conform to the 'Sendable' protocol
public final class NIOSSLContext {
                   ^
remote.swift:18:13: warning: stored property 'http' of 'Sendable'-conforming struct 'Remote' has non-sendable type 'HTTPClient'
        let http:HTTPClient
            ^
.build/checkouts/async-http-client/Sources/AsyncHTTPClient/HTTPClient.swift:66:14: note: class 'HTTPClient' does not conform to the 'Sendable' protocol
public class HTTPClient {
             ^
ephemera.swift:106:91: warning: cannot use let 'threads' with a non-sendable type 'MultiThreadedEventLoopGroup' from concurrently-executed code
        async let service:Void      = server.bind(host: "127.0.0.1", port: 8888, threads: threads)
                                                                                          ^
.build/checkouts/swift-nio/Sources/NIOPosix/MultiThreadedEventLoopGroup.swift:54:20: note: class 'MultiThreadedEventLoopGroup' does not conform to the 'Sendable' protocol
public final class MultiThreadedEventLoopGroup: EventLoopGroup {
                   ^

most of these (except for Channel) are types i am told should be Sendable, but cannot be marked so without causing another cascade of warnings. Channel is a protocol and cannot be marked Sendable by extension.

the @predatesConcurrency attribute does not appear to be defined:

error: unknown attribute 'predatesConcurrency'
@predatesConcurrency
import class NIO.MultiThreadedEventLoopGroup

okay apparently @predatesConcurrency needed an underscore, but it is still not compiling:

error: '@_predatesConcurrency' attribute cannot be applied to this declaration
@_predatesConcurrency
import class NIO.MultiThreadedEventLoopGroup

I think @beccadax knows the current state of @_predatesConcurrency, but it is the "correct" way to solve this problem. In the meantime, most of these warnings can be fixed by adding @unchecked Sendable conformances to your own types and just asserting that ours are.

Terms of Service

Privacy Policy

Cookie Policy