[swift-evolution] Warning when omitting default case for imported enums

Slava Pestov spestov at apple.com
Tue Feb 7 22:51:17 CST 2017


> On Feb 7, 2017, at 6:16 PM, Dany St-Amant via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> Le 7 févr. 2017 à 14:45, Robert Widmann via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> a écrit :
> 
>> I lean +1, but this answer on its own seems incomplete.  Exhaustiveness is an important property, and it’s not clear what happens here now when you fall through a “complete” case tree without matching a pattern, and in that sense this plan solves a problem.  But it also would hinder a “future-you” from going back and dealing with the ramifications of swapping a dependency for a newer version, in that with a default now covering the rest of the cases the compiler is unable to tell you which cases you are actually missing post-upgrade.
>> 
> 
> I have not read the ABI stability stuff, so not sure if adding a new case to an enum inside a library can be made backward compatible but that would be nice.

The plan of record currently is to have a ‘closed’ attribute for enums which allows the default case to be omitted for an exhaustive switch. Closed enums cannot have new cases added after the fact. Enums that are not marked ‘closed’ will require a default case when used outside of their defining module, and adding new cases will be permitted without breaking ABI.

(If anyone wants to take a look, this is sort of implemented today, except you have to enable the resilient ABI explicitly with the -enable-resilience frontend flag, and @closed is spelled ‘@_fixed_layout’. Also 100% unsupported and undocumented).

> Handling this unexpected new value in the currently compiled user code should be as important as telling the owner of the user code that he must handle a new case.
> 
> Would a new pseudo-default keyword (unexpected, undefined) help here? Such keyword would require the switch statement to be exhaustive so it doesn't act like 'default' for switch exhaustiveness status at compile time,  but does act like 'default' at runtime.
> 
> switch data {
>   case .one: { print("one') }
>   case .two: { print("two") }
>   undefined: { print("unexpected value") }
> }
> 
> Replacing the library with one providing .three, will cause this previously compile code to print "unexpected value", and would cause the code to fail to compile against this same new library.
> 
> Dany
> 
> 
>> Library Evolution <https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst> includes what I think is the more complete response here: An @closed attribute for enums where a switch is guaranteed to be exhaustive.  (Though, after the open discussion, I wonder if that keyword can’t be reused in some way to provide the inverse restriction instead).
>> 
>>> On Feb 7, 2017, at 10:12 AM, Tanner Nelson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> Hello Swift Evolution,
>>> 
>>> I'd like to propose that a warning be emitted when default cases are omitted for enums from other modules. 
>>> 
>>> What this would look like:
>>> 
>>> OtherModule:
>>> ```
>>> public enum SomeEnum {
>>>     case one
>>>     case two
>>> }
>>> 
>>> public let global: SomeEnum = .one
>>> ```
>>> 
>>> executable:
>>> ```
>>> import OtherModule
>>> 
>>> switch OtherModule.global {
>>>     case .one: break
>>>     case .two: break
>>>     ^~~~~ ⚠︎ Warning: Default case recommended for imported enums. Fix-it: Add `default: break`
>>> }
>>> ```
>>> 
>>> Why:
>>> 
>>> Allowing the omission of a default case in an exhaustive switch makes the addition of a new case to the enum a breaking change. 
>>> In other words, if you're exhaustively switching on an enum from an imported library, the imported library can break your code by adding a new case to that enum (which the library authors may erroneously view as an additive/minor-bump change).
>>> 
>>> Background:
>>> 
>>> As a maintainer of a Swift framework, public enums have been a pain point in maintaining semver. They've made it difficult to implement additive features and have necessitated the avoidance of enums in our future public API plans.
>>> 
>>> Related Twitter thread: https://twitter.com/tanner0101/status/796860273760104454 <https://twitter.com/tanner0101/status/796860273760104454>
>>> 
>>> Looking forward to hearing your thoughts.
>>> 
>>> Best,
>>> Tanner
>>> 
>>> Tanner Nelson
>>> Vapor 
>>> +1 (435) 773-2831
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170207/7b28ddb4/attachment.html>


More information about the swift-evolution mailing list