- Proposal: SE-NNNN
- Authors: Rintaro Ishziaki
- Review Manager: TBD
- Status: Awaiting review
This proposal adds ability to guard switch case
clauses with #if
directives.
Swift-evolution thread: Not yet
When you want to switch cases only for certain compilation condition, say switching #if os(Linux)
guarded enum cases, right now you have to write switch
twice:
enum Operation {
case output(String)
#if os(Linux)
case syscall(Syscall)
#endif
}
func execute(operation: Operation) {
#if !os(Linux)
switch operation {
case .output(let str):
print(str)
}
#else
switch operation {
case output(let str):
print(str)
case .syscall(let call):
call.execute()
}
#endif
}
This is annoying and error prone.
This proposal allows #if
to guard switch case clauses.
func execute(operation: Operation) {
switch operation {
case .output(let str):
print(str)
#if os(Linux)
case .syscall(let call):
call.execute()
#endif
}
}
This change shouldn't affect existing #if
directives within case
clauses. This code should works as expected:
func foo(x: MyEnum) {
switch x {
case .some(let str):
doSomething(str)
#if PRINT_SOME
print(str)
#endif
case .other:
doOther()
}
}
Only if the next token after #if
line is case
or default
, the Parser treat it as guarding case
clauses.
func foo(x: MyEnum) {
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
case .other:
doOther()
}
#endif
}
func foo(x: MyEnum) {
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
default:
break
#endif
}
Error cases:
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
case .other:
doOther()
#else
doMore() // error: all statements inside a switch must be covered by a 'case' or 'default'
#endif
}
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
doMore()
case .other:
doOther() // error: 'case' label can only appear inside a 'switch' statement
#endif
}
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
case .other:
doOther()
#endif
doMore() // error: all statements inside a switch must be covered by a 'case' or 'default'
}
You can guard multiple cases as long as it is guarding whole case
s:
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHERS
case .other:
doOther()
case .more:
doMore()
#endif
}
As this is purely additive proposal, it does not affect existing code
This change does not affect ABI.
N/A