Take this example:
enum Good {
case one
case two
case three
}
enum Bad {
case none
case one
case two
case three
}
func foo(good: Good?, bad: Bad?) {
switch good {
case .one: print("one")
case .two: print("two")
case .three: print("one")
case .none: print("none")
}
switch bad { // Error: Switch must be exhaustive
case .one: print("one")
case .two: print("two")
case .three: print("three")
case .none: print("none") // Assuming you mean 'Optional<Bad>.none'
case Optional.none: print("none") // Warning: Case is already handled by previous patterns
}
switch bad {
case .one: print("one")
case .two: print("two")
case .three: print("three")
case Bad.none: print("none") // Error
case Optional.none: print("none")
}
}
There's an obvious way of fixing this by treating nil separately before the switch, but note that "Good" way of doing switch was totally valid, and it got suddenly broken with the introduction of "none" case.
If you change from none
to nope
- the problem goes away (but if the app was working before it might be doing something different now, see just below). And equally worrying, the above snippet aside, if you see a case nope
in your peer's code, and think "it is a good idea to change nope
to none
" - the code would probably compile, the warning could be missed (unless warnings are treated as errors which many companies can't afford) and the app starts to behave differently.
enum E {
case one
case none // renamed from "nope". what can possibly go wrong.
}
var x: [Int: Bad] = [1 : .one, 2 : .none] // was nope
... some thousands line away in a different file in a project with a few warnings already
let a = x[1] == .one
let b = x[2] == .none // was nope
I wish there was a way to promote that warning into an error (without "treating all warnings errors").