Codable got introduce in Swift 4. My project language version is Swift 3.3 but still I am able to use Codable in my project. This is not the issue but how is it possible? I
The Swift compiler version and "Swift Language Version" build setting (corresponding to the
-swift-version
command-line flag) are two different things. The former is the actual version of compiler and standard library you're using, whereas the latter is just a flag to tell the compiler to attempt to mimic the behaviour of previous Swift versions. This allows for a smoother migration experience – you can update to the latest Swift compiler without having to immediately update your codebase to accommodate for the latest changes in the language.
In your case, it sounds like you're using a Swift 4.1 compiler with the "Swift Language Version" set to Swift 3.3. This is known as "Swift 3 compatibility mode". Note that the version Swift 3.3 is a pseudo version – it exists only to represent the Swift 4.1 compiler running in Swift 3 compatibility mode.
Here's a handy table (info taken from SE-0212) that maps compiler to language version per compatibility mode:
(note that now SE-0212 is implemented, this version bumping for compatibility modes will no longer take place for Swift 5 and above)
So this means that you're using the Swift 4.1 standard library (which includes the new Codable
protocol) and compiling with the Swift 4.1 compiler (which includes the necessary compiler magic for Codable
synthesis). This is why you're still able to take advantage of the new Codable
protocol.
However by running in Swift 3 compatibility mode, you're instructing the compiler to mimic the behaviour of a Swift 3 compiler. This will, for example, cause it to allow you to access declarations marked @available(swift, obsoleted: 4)
, prevent you from accessing declarations marked @available(swift, introduced: 4)
, ignore code within a #if swift(>=4)
conditional compilation block, and otherwise do its best to preserve source compatibility with Swift 3.
The latter it doesn't always achieve perfectly, for example this compiles with a Swift 3.1 compiler:
protocol P {}
typealias X = protocol<P, AnyObject>
class C : X {}
but it doesn't compile with a Swift 4.1 compiler running in Swift 3 compatibility mode (SR-8153).
If the Decodable
and Encodable
protocols were marked as @available(swift, introduced: 4)
, then you indeed wouldn't be able to access them in Swift 3 compatibility mode. But there's no real reason to mark them as such, as there's no real reason to prevent people from taking advantage of them in Swift 3 mode, as they're fully supported by the Swift 4 compiler.
However because Swift 3 compatibility mode is just that – a temporary mode for source compatibility, it's not something you'll be able to use forever with future compiler versions. It will no longer be an option in the Swift 5 compiler (you will have a compatibility mode for Swift 4, however). So you need to make sure you update your codebase at some point to Swift 4 in order to be able to have a smooth migration to the Swift 5 compiler.
Finally, it's worth noting that a new compiler
directive (that can be used in a conditional compilation block) is being introduced in Swift 4.2. Unlike #if swift(...)
which checks against the language version as supplied by -swift-version
, #if compiler(...)
will check against the actual version of the compiler, ignoring any compatibility mode it might be running in.
I think may be you are using latest Swift compiler.