SE-0192 (Non-Exhaustive Enums): what happened in Swift 4.2?

TLDR: It'll be enforced in Swift 5 instead.

SE-0192, which took quite a while to go through review, was accepted before the Swift 4.2 deadline. However, those who've been paying attention might have noticed that no new warnings appeared in Swift 4.2, even though Apple's SDKs have plenty of enums that can grow new cases. What's the deal?

In experimenting with the additional diagnostics ("please add @unknown default to handle future enum cases"), we found that this came up quite a bit. That's generally correct behavior, but it did mean an awful lot of changes for what was supposed to be a minor release with compatible language rules. The decision we came to was to move from the proposal's "warning in Swift 4 / error in Swift 5" to a much lighter "trap-at-runtime in Swift 4 / warning in Swift 5". This makes Swift 4.2's behavior roughly the same as Swift 4.1's, but with the extra runtime guarantee, and will make the transition to Swift 5 a little softer than it would be otherwise.

Two parts of the work around SE-0192 did make it into Swift 4.2:

  • As mentioned, switching on an unexpected enum value now results in a deterministic trap if the enum is @objc, rather than, um, the complete undefined behavior that was present in Swift 4.1 and earlier. (In practice, this usually resulted in the compiled code treating the value as if it matched one of the known cases.) People have run into this a few times in Swift 4.2 when they've been switching over an enum from Apple's SDKs; the usual workaround is to switch over the raw value or provide a default instead. Which brings us to the second change…

  • @unknown default is actually permitted in Swift 4.2 as well, with the behavior described in the proposal: if a switch is missing cases, that's just a warning, not an error. If you'd like to use it within your project for enums that frequently change, feel free to do so.