Swift 4.0.2 records the stabilized toolchain in source
The Swift 4.0.2 tag identifies a maintenance toolchain. Its source history includes runtime compatibility and diagnostic repairs that illustrate the work behind a patch release.
A maintenance compiler release includes more than changes to accepted syntax. Runtime calls have deployment requirements, and diagnostics need to distinguish modifying a value from modifying an object reached through a reference. Swift 4.0.2 provides a tagged toolchain whose history includes work on those less visible parts of compatibility.
The release tag identifies revision efb12f4d7a6aa7575333c13fbcdb7782426b130a and records tagging on November 2 in UTC. The tag's message changes the version string to swift-4.0.2-RELEASE. This post uses that source record as its date. A tag identifies the source being discussed more precisely than an unqualified reference to the current release branch.
I find Swift's language design appealing, but the toolchain has to preserve the assumptions of an application using it. Maintenance work matters when it keeps a program usable on its deployment targets or makes a warning describe the program correctly. Neither improvement needs a new language construct to affect application development.
Runtime compatibility includes calls made on the application's behalf
The source comparison with the Swift 4.0 release tag includes a runtime change by Greg Parker that avoids calling object_isClass. Its explanation says that function is unavailable on Swift's oldest deployment targets. The source comment names macOS 10.9 and iOS 7.
The replacement determines whether the object's class is a metaclass. It composes object_getClass with class_isMetaClass to obtain the required result without that unavailable convenience function. The runtime then uses the result while fetching formal dynamic type metadata for a potentially Objective-C object.
This is a concrete example of compatibility work below the application source level. An application's own code need not mention the unavailable function. A runtime implementation can introduce the dependency on its behalf. Preserving a deployment target therefore requires checking the functions used by support code as well as the declarations imported into the application's source.
The comparison establishes that this repair is present in the tagged source history. It is a cumulative comparison, so it should not be read as a list in which every change first appears in 4.0.2. The relevant observation is that the maintenance toolchain includes the corrected implementation. Attribution to a particular intermediate release would require a narrower comparison.
Key-path diagnostics need the right model of mutation
Another change in that history handles ReferenceWritableKeyPath applications as reads of their base. The accompanying tests distinguish changing a reference variable from changing a property reached through it. The difference is familiar in ordinary reference semantics but needs an explicit treatment in the compiler's usage analysis.
A variable holding an object reference can remain unchanged while code modifies the object's property. A diagnostic that sees only an assignment through a key path can classify the base incorrectly. The repair marks the base as read for a reference-writable key path, while an ordinary writable key path has separate read-and-write handling.
The test includes an immutable copy used through a reference-writable key path. It should not receive a warning that the copy is unused. It also includes a mutable local whose reference value never changes, which should still receive the warning that it was never mutated. The pair of expectations captures both sides of the distinction.
This matters for a language that encourages let when a binding does not need reassignment. A warning should help a developer choose the appropriate binding. Treating mutation of a referenced object as mutation of the binding would make that advice less accurate. Treating the key-path access as no use of the binding would be wrong for a different reason.
Compiler identity and source mode remain separate
The Swift 4 announcement describes Swift 3.2 compatibility mode and Swift 4.0 mode under the same compiler. The compatibility mode accepts the majority of source from Swift 3.x and hides updates to existing APIs where necessary. Swift 4 mode exposes the complete language and API changes.
A patch toolchain revision therefore does not by itself describe a module's source mode. A report about a compiler diagnostic needs both the toolchain identity and the rules under which the module was compiled. The release tag supplies the former. The build's language-mode selection supplies the latter.
I value this distinction because it keeps an upgrade discussion specific. A runtime deployment repair and a source migration are different changes to assess. The September announcement also states that the release branch remains open for potential bug-fix releases, which gives the maintenance tag a defined place in the release process.
The source comparison provides inspectable implementations and regression tests for the examples discussed here. It does not supply an application-wide performance measurement or a comprehensive compatibility guarantee. For this toolchain, the concrete evidence is the tagged revision and the changes present in its source, including the runtime's avoidance of an unavailable function and the usage analysis applied to reference-writable key paths.