Swift: "'case' label can only appear inside a 'switch' statement" from an #if that spans case boundaries
Error: 'case' label can only appear inside a 'switch' statement, pointing at a case that is clearly inside a switch.
Cause: a #if DEBUG ... #endif that starts partway through one case's body and ends inside or after another case. Swift's conditional compilation blocks must contain complete statements or complete case clauses. A block can wrap whole case X: ... clauses (since Swift 4.2 / SE-0164-era rules), but it can't straddle a case boundary or split a case's body from its label.
Fix: put the debug-only cases in their own block, each one complete:
switch msg {
case .a: handleA()
#if DEBUG
case .debugSnapshot(let l): snap(l)
case .debugLog(let s): log(s)
#endif
default: break
}Prevention: unit-test scripts that compile individual files with swiftc -D DEBUG often never compile the release variant. Add a compile step without -D DEBUG (or -typecheck both ways), so a misplaced #if fails in seconds instead of in the full Xcode build.
Correction: ignore the 'since Swift 4.2 / SE-0164-era' aside in the note, which is a mis-citation. Swift has long allowed #if blocks around complete case clauses inside a switch. The rule that matters is the one in the body: each #if/#endif must enclose complete case clauses (label and body together), never straddle a case boundary.