Thoughts about releasing SwiftNIO 2.0.0 together with Swift 4.2 and making it 4.2 only

Hi SwiftNIO interested folks,

tl;dr: Swift 4.2 will warn about @_inlineable/@_versioned as they have been renamed to @inlineable/@usableFromInline. SwiftNIO uses the old spellings so to remain warning-free, we're planning to release SwiftNIO 2.0.0 together with Swift 4.2 and making SwiftNIO 2.0.0 a Swift 4.2-only release (no longer supporting Swift 4.0 & 4.1). Any thoughts about that?

For clients of SwiftNIO to have acceptable performance we rely on cross-module inlining (at the moment through @_inlineable/@_versioned). That works well and SE-0193 fortunately decided to make this public (non-underscored) which is great. Unfortunately, Swift 4.2 will also warn about using the old spellings and the Swift team decided to not offer an alternative (CC @Slava_Pestov) to be able to support Swift 4.0, 4.1 and 4.2 without warnings :slightly_frowning_face:. Unfortunately, this can also not be solved with #if swift(...) constructs unless we'd copy the full body of everything that has @_inlineable/@_versioned decorations and the copying is unacceptable.

That essentially leaves SwiftNIO with two options:

  1. leave everything as is, continue supporting Swift 4.0, 4.1 and 4.2 which would mean the Swift 4.2 compilation will issue a lot of warnings about the fact that @_inlineable has been renamed to @inlinable
  2. rename @_inlineable to @inlinable and @_versioned to @usableFromInline and release SwiftNIO 2.0.0 (because that's SemVer major). That however means that Swift 4.0 & 4.1 will no longer be supported and that would apply to our users as well.

I realise that's not a great position to be in but we hope that's acceptable for our clients such as Vapor (CC @tanner0101), IBM (CC @Pushkar_N_Kulkarni, @IanPartridge, Chris Bailey), various libraries (CC @Helge_Hess1) and possibly others.
Please let me know your thoughts.

-- Johannes

3 Likes

I am +1 on only support 4.2 once its out.

+1 on going the 4.2+ only route.

I agree that major bump + supporting 4.2 only is the best solution here.

I wish the Swift #if system would not be so context sensitive so that we could use it to apply different annotations to the same function...

1 Like

@tanner0101 Great, that works well for us. Will Vapor release a version that is 4.2-only straight away when Swift 4.2 gets released too then?

Still trying to figure out the best option there. Probably worth a post over on #related-projects:vapor. Ideally we would follow semver and also do a major bump, but that could cause some confusion since there's typically ~10 months between our major releases. The other option would be a minor bump with special announcement.

1 Like

I just want to bring to attention that this means you won't be able to use Xcode on macOS 10.12 for development anymore. I personally know a lot of people who are still on Better Sierra.
I don't care too much right now, but I think it is generally the wrong approach for a base library to require the latest and greatest. Meaning: I would personally just do the ugly thing (just copy the relevant files into say Compat/ByteBuffer-4.0.swift and add the guards, maybe using a script).
I think in the Mac world LATEST-1 is the common support schema considered reasonable.

2 Likes

Could you cut down on the copying by doing something like this? Or does that defeat the purpose of the annotation since the actual impl does not have the decorator.

#if swift(>=4.2)
@inlineable
public func foo() { _foo() }
#else 
@_inlineable
public func foo() { _foo() }
#endif
private func _foo() { /* impl */ }

Unfortunately, that won't work as I would then make _foo @inlinable too in order to get what we need :|

I think what you'd need is something like the ability to alias an attribute:

#if swift(>=4.2)
@myInlineable := @inlineable
#else
@myInlineable := @_inlineable 
#endif

Then you could use @myInlineable and let the Swift version handle what it means.

Yes! I think also include modifiers so you could then create modifier groups in a similar fashion as how we can create group of protol aliases.

Edit. I think leave as is and break it at swift 5.

@felix91gr I totally agree, that would be good. However we don't have this feature yet in Swift 4.0 and 4.1 so even if it got introduced by Swift 4.2 it still wouldn't solve the issue we have today...

Maybe if it was introduced in 4.2, it could be made work as well in 4.1 and 4.0 compat mode...
But indeed, that's kind of a problem that we can't solve right now directly.

1 Like

Ok, I think we can close this thread because the Swift team is awesome and this warning will now only be active in the -swift-language 4.2 mode (and not in the -swift-language 4 mode). Given that SwiftNIO declares // swift-tools-version:4.0 in its Package.swift we'll be compiled in -swift-language 4 mode and won't see those warnings. Thanks @Slava_Pestov!

Needless to say, at some point in the future we will cut a SwiftNIO 2.0.0 which might (or might not) be a Swift 4.2-only release but fortunately we're now not forced to do this at the very point when Swift 4.2 gets released. Over time, the importance of Swift 4.0 and 4.1 will decline, especially when a future Swift version lands a feature that our consumers want to leverage and then we'll be able to deprecate Swift 4.[01] support :+1:.

So all back to plan A: The SwiftNIO 1.x series should compile warning-free on Swift 4.2 and we'll cut a 2.0.0 whenever it makes sense and most importantly coordinate that with the community.

3 Likes

I believe there is also another reason to make a Swift 4.2 only release. Replacing all those #if os() directives with #if canImport() would make portability much better.

That's true. There will for sure be a Swift 4.2-only release at some point in time and honestly I can't wait. But we want to coordinate with our users when we all feel that Swift pre-4.2 is no longer relevant, everybody will need to cut a major release before that can happen...

2 Likes

Sorry for the late arrival to this thread. Great to hear that NIO will retain support for Swift 4.0 and 4.1 once Swift 4.2 comes out. It would be odd to drop backwards compatibility just for some compiler warnings - annoying as they are.

I think a NIO 2.0 alongside Swift 5 would be the best option in the future.

Thanks,
Ian

1 Like