
Indeed I'm quite uncertain of the right way forward here as all options are quite bad,
On one hand, remaining silent in this case means that the user may rely on the compiler's pattern checker when it can't be relied upon. In passing `-Wall` to GHC, the user has requested that we provide warnings on non-exhaustive
deliver on this promise it seems to me that we have a duty to ensure
this. To remain silent will mean that users may be taken by surprise when their warning-free code nevertheless crashes. For this reason I think it is quite important
#11316: Too many guards warning causes issues -------------------------------------+------------------------------------- Reporter: NeilMitchell | Owner: Type: bug | Status: new Priority: high | Milestone: 8.0.1 Component: Compiler | Version: 7.11 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by gkaracha): Replying to [comment:1 bgamari]: patterns. If we can't that the user knows that a warning of
this sort is available (although perhaps not enabled by default).
Of course, this is made slightly trickier by the fact that pattern match checking is a hard problem and therefore will always be approximate. Moreover, before George's work we couldn't reason about guards at all. Further, even now the check necessarily breaks down completely in the face of boolean guards.
Given the fact that guard checking is merely nice to have and will always be approximate, I tend to think we should just disable this warning by default.
I think after all I agree with this decision. By oversimplifying guards, we lose precision but the check is always reliable, in the sense that we always play on the safe side, no matter what is our choice about guards: * If a match is deemed exhaustive, it certainly is * If a clause is deemed redundant, it certainly is * If a clause is deemed to have inaccessible RHS, the RHS is certainly inaccessible I summary, this means that by oversimplifying guards, we simply increase the possibility for: * Detecting less matches as exhaustive * Detecting less clauses as redundant * Detecting more clauses as with inaccessible RHS instead of redundant (safe side in terms of laziness) The part of the check that is bit more than the rest with guard simplification is coverage checking: It is less likely to see that something is redundant if guards are oversimplified, but this is something we can live with I think. Hence, I also vote for turning `-Wtoo-many-guards` off by default if you feel that makes GHC too chatty. Replying to [comment:2 NeilMitchell]:
Note that at the moment I am not using {{{-Wall}}}, only {{{-Werror}}}, so I haven't asked for exhaustiveness checking of the guards (at least I haven't turned it on specially), so having a warning that it couldn't produce a warning I didn't even ask for seems even more dubious. Is the exhaustiveness of guards on by default?
Ah, I see. By default, GHC has `-fwarn-overlapping-patterns` (coverage checking) enabled. Hence, even without `-Wall`, the checker will run (but only print warnings about redundant or clauses with inaccessible right hand side). About the guards, there is a misconception in general: They are not something special that the checker can completely drop. The only thing a check can do is oversimplify (like the old checker used to do -- and that's why we would get all these wrong messages) but never drop: A guard that might fail makes the clause in question not total so we cannot just say "forget about the guard", one way or the other, a guard changes the semantics of pattern matching and has to be reasoned about. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11316#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler