Note [Empty case alternatives]
The alternatives of a case expression should be exhaustive. But this exhaustive list can be empty! * A case expression can have empty alternatives if (and only if) the scrutinee is bound to raise an exception or diverge. When do we know this? See Note [Bottoming expressions] in GHC.Core.Utils. * The possibility of empty alternatives is one reason we need a type on the case expression: if the alternatives are empty we can't get the type from the alternatives! * In the case of empty types (see Note [Bottoming expressions]), say data T we do NOT want to replace case (x::T) of Bool {} --> error Bool "Inaccessible case" because x might raise an exception, and *that*'s what we want to see! (#6067 is an example.) To preserve semantics we'd have to say x `seq` error Bool "Inaccessible case" but the 'seq' is just such a case, so we are back to square 1. * We can use the empty-alternative construct to coerce error values from one type to another. For example f :: Int -> Int f n = error "urk" g :: Int -> (# Char, Bool #) g x = case f x of { 0 -> ..., n -> ... } Then if we inline f in g's RHS we get case (error Int "urk") of (# Char, Bool #) { ... } and we can discard the alternatives since the scrutinee is bottom to give case (error Int "urk") of (# Char, Bool #) {} This is nicer than using an unsafe coerce between Int ~ (# Char,Bool #), if for no other reason that we don't need to instantiate the (~) at an unboxed type. * We treat a case expression with empty alternatives as trivial iff its scrutinee is (see GHC.Core.Utils.exprIsTrivial). This is actually important; see Note [Empty case is trivial] in GHC.Core.Utils * We lower empty cases in GHC.CoreToStg.coreToStgExpr to an eval on the scrutinee. Historical Note: We used to lower EmptyCase in CorePrep by way of an unsafeCoercion on the scrutinee, but that yielded panics in CodeGen when we were beginning to eta expand in arguments, plus required to mess with heterogenously-kinded coercions. It's simpler to stick to it just a bit longer.
References 2
- Bottoming expressions GHC.Core.Opt.Arity
- Empty case is trivial GHC.Core.Utils
Referenced by 12
- GHC.Core.Opt.Arity call site ×2
- Case expression invariants GHC.Core
- GHC.Core.Lint call site
- GHC.Core.Make call site
- Empty case alternatives GHC.Core.Map.Expr
- Case-to-let for strictly-used binders GHC.Core.Opt.Simplify.Iteration
- Empty case is trivial GHC.Core.Utils
- GHC.Core.Utils call site
- GHC.CoreToStg call site
- Empty case alternatives GHC.Iface.Syntax
- GHC.StgToByteCode call site