Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this Swift switch statement with two enums not exhaustive?

I'm writing a bit of Swift code (Swift 3.1, Xcode 8.3.2) that switches on two enums. I believe I've written an exhaustive list of cases, but the compiler disagrees with me. My code is a bit complicated, with some associated values and such, so I boiled this down to as simple an example as I could in a playground, like so:

enum Test {
    case one
    case two
    case three
    case four
}

let allValues: [Test] = [.one, .two, .three, .four]
let test1 = Test.one
let test2 = Test.two

for i in 0..<4 {
    for j in 0..<4 {
        let test1 = allValues[i]
        let test2 = allValues[j]
        switch (test1, test2) {
        case (.one, _):
            print("one, _")
        case (_, .one):
            print("_, one")
        case (.two, _):
            print("two, _")
        case (_, .two):
            print("_, two")
        case (.three, .three):
            print("three, three")
        case (.three, .four):
            print("three, four")
        case (.four, .three):
            print("four, three")
        case (.four, .four):
            print("four, four")
//Won't compile with this commented out, but when enabled,
//we never print out "default"
//      default:
//          print("default")
        }
    }
}

Which prints out:

one, _
one, _
one, _
one, _
_, one
two, _
two, _
two, _
_, one
_, two
three, three
three, four
_, one
_, two
four, three
four, four

I would expect this to compile without the default clause, but the compiler gives "error: switch must be exhaustive, consider adding a default clause". If I add the default clause, it compiles and runs fine, but of course it never hits the default clause because all the previous case statements handle every variation of the two enums.

The default clause doesn't really harm anything, but I'd really like to understand why this switch isn't considered exhaustive by the compiler. Any ideas?

like image 541
Brian Webster Avatar asked Apr 24 '17 21:04

Brian Webster


People also ask

What does switch must be exhaustive?

This means your switch statement should cover all possible cases. If you're not sure about all, so you can't make it exhaustive, you just need to provide a default case.

Can you override structs and enums in Swift?

Only Classes support inheritance, Enum and Struct don't.

What does exhaustive mean in programming?

Exhaustive testing is the process of testing for absolutely everything just to make sure that the product cannot be destroyed or crashed by some random happenstance. It takes into consideration all possible combinations of inputs, usage scenarios as well as random situations and inputs.

Should enums be capitalized Swift?

The name of an enum in Swift should follow the PascalCase naming convention in which the first letter of each word in a compound word is capitalized.


1 Answers

On Twitter, CodaFi pointed me towards the following, which indicates that it's a bug/shortcoming in the current version of the Swift compiler.

https://bugs.swift.org/browse/SR-483

https://bugs.swift.org/browse/SR-1313

like image 104
Brian Webster Avatar answered Sep 28 '22 01:09

Brian Webster