[swift-dev] What can you change in a non-exhaustive enum?

David Sweeris davesweeris at mac.com
Sat Sep 30 01:02:21 CDT 2017

> On Sep 29, 2017, at 18:21, Jordan Rose via swift-dev <swift-dev at swift.org> wrote:
> Hello again, swift-dev! This is a sort of follow-up to "What can you change in a fixed-contents struct" from a few weeks ago, but this time concerning enums. Worryingly, this seems to be an important consideration even for non-exhaustive enums, which are normally the ones where we'd want to allow a developer to do anything and everything that doesn't break source compatibility.
> [This only affects libraries with binary compatibility concerns. Libraries distributed with an app can always allow the app to access the enum's representation directly. That makes this an Apple-centric problem in the near term.]
> So, what's the issue? We want to make it efficient to switch over a non-exhaustive enum, even from a client library that doesn't have access to the enum's guts. We do this by asking for the enum's tag separately from its payload (pseudocode):
> switch getMyOpaqueEnumTag(&myOpaqueEnum) {
> case 0:
>   var payload: Int
>   getMyOpaqueEnumPayload(&myOpaqueEnum, 0, &payload)
>   doSomething(payload)
> case 1:
>   var payload: String
>   getMyOpaqueEnumPayload(&myOpaqueEnum, 1, &payload)
>   doSomethingElse(payload)
> default:
>   print("unknown case")
> }
> The tricky part is those constant values "0" and "1". We'd really like them to be constants so that the calling code can actually emit a jump table rather than a series of chained conditionals, but that means case tags are part of the ABI, even for non-exhaustive enums.
> Like with struct layout, this means we need a stable ordering for cases. Since non-exhaustive enums can have new cases added at any time, we can't do a simple alphabetical sort, nor can we do some kind of ordering on the payload types. The naive answer, then, is that enum cases cannot be reordered, even in non-exhaustive enums. This isn't great, because people like being able to move deprecated enum cases to the end of the list, where they're out of the way, but it's at least explainable, and consistent with the idea of enums some day having a 'cases' property that includes all cases.
> Slava and I aren't happy with this, but we haven't thought of another solution yet.

If this is only an issue for things with “binary compatibility concerns”, could we pass the old (well, “current release”) version of the binary to the compiler and have it extract the ordering info from that? I mean it seems like a reasonable assumption that a vendor would have access to what would be the current version of their product.

- Dave Sweeris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20170929/b9b22780/attachment.html>

More information about the swift-dev mailing list