Extending compilation conditions

Currently there are some compilation conditions like #if SOME, #if swift(..), #if os(..), but it is certainly not enough of them in some cases. Examples:

Example #1

Swift 4.2 brings us Arrays that conforms to Hashable if Element conforms to Hashable. So, if we want our code to compile both in Swift 4.1 and 4.2 we must write something like this:

#if swift(>=4.2)
#else
extension Array: Hashable where Element: Hashable {
  public var hashValue: Int { return ... }
}
#endif

But, if we compile it with compatibility mode, compiler will yell at us:

Conformance of 'Array<Element>' to protocol 'Hashable' was already stated in the type's module 'Swift'

And there is no way we can distinguish those two compilation configurations.

Example #2

Also, there is no condition for sdk we are compiling with. Consider this:

// SDK Version 1.0:
enum Foo: Int { case a, b }
// SDK Version 2.0:
enum Foo: Int { case a, b, c }

For our code to compile with both 1.0 and 2.0 sdks we must resort to barbaric constructs, for example:

let val: Foo = ...
switch val.rawValue {
case Foo.a.rawValue: ...
case Foo.b.rawValue: ...
case Foo.b.rawVaule + 1: ...
case default: fatalError()
}

So, good it has raw value, otherwise it needed to be implemented with else if .. {..} else if .. {..} constructs.


As you propbably know, there are times, about a couple of months in a year, when we want our code to compile with both versions of sdk, to prepare our products for future os releases, but now, it's often not a trivial task to do. So, are there any plans to improve this situation?

Your #1 has been solved with #if compiler, SE-0212. Unfortunately that was implemented only this year, so for now you have to use the workaround of knowing that Swift 4 mode in Swift 4.2 is "4.1.50".

#2 is a reasonable request; for now you can fake that with #if compiler as well, since so far every major new SDK version has also come with a new Xcode that has a new Swift compiler.

1 Like

Thanks! Didn't know about that hack with version. That solves a lot of problems :)