Skip to content

`case (x :: Void) of _ -> ()` should be flagged as redundant

Simon and Richard rightly pointed out that case with non-empty list of alternatives indeed is not strict, so this ticket is invalid. The testcase T17376 tests whether we the code below indeed does not trigger a warning.


We have special behavior for -XEmptyCase now that emulates the strictness put on the scrutinee by going through a very specific code path. But it turns out that the same reasoning is also important for the more general code path where we have more than one clause:

f :: Void -> ()
f x = case x of _ -> ()

This currently goes by the pattern-match checker undisturbed. But really the single clause is redundant and the user had better activated -XEmptyCase to write

f :: Void -> ()
f x = case x of {}

Of course this is all just a huge setup by me to highlight how unfortunate this strange special handling of -XEmptyCase within is. The problem currently is that both regular function clauses (which don't force matches before the first clause) and case matches (which do) are handled by the same code.

There's a simple solution: Pass into checkMatches whether or not it's a strict match and prepend a shadow clause of the form !_ !_ ... | False. After !1851 (closed) we can conveniently express this as PmBang x, PmBang y, ..., let b = False, True <- False. Now both code paths (-XEmptyCase or not) can call pmCheck and discard the coverage results of the first match. 🎉

Edited by Sebastian Graf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information