[GHC] #10746: No non-exhaustive pattern match warning given for empty case analysis
GHC
ghc-devs at haskell.org
Sun Apr 10 16:04:09 UTC 2016
#10746: No non-exhaustive pattern match warning given for empty case analysis
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.2
Resolution: | Keywords:
| PatternMatchWarnings
Operating System: Unknown/Multiple | Architecture:
Type of failure: Incorrect | Unknown/Multiple
warning at compile-time | Test Case:
Blocked By: | Blocking:
Related Tickets: #7669, #11806 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by gkaracha):
I guess my wording was not clear in #11806 after all, I will try to
elaborate here in more detail. :-)
== Current state ==
Indeed the guard in `checkMatches'` is responsible for the current
behaviour on empty case expressions:
{{{
| null matches = return ([], [], [])
}}}
By default, the new checker would issue a non-exhaustive warning for empty
cases, which is correct. Yet, there has been a request (#7669) to **not**
issue a warning in these cases.
Hence, Simon changed this with commit
9162d159a62d19d4b371b7348eb1b524001fddcd. I have added the above guard in
the new implementation to keep the same behaviour (even though I
strongly disagree with it) and by removing it we get the default
behaviour, which #11806 & #10746 request.
== Laziness ==
Replying to [comment:12 dfeuer]:
> Replying to [comment:11 erikd]:
> > Hmm, wit this fix, building base fails due to:
> >
> > {{{
> > absurd :: Void -> a
> > absurd a = case a of {}
> > }}}
> >
> > which triggers:
> >
> > {{{
> > libraries/base/Data/Void.hs:66:12: warning: [-Wincomplete-patterns]
> > Pattern match(es) are non-exhaustive
> > In a case alternative: Patterns not matched: _
> > }}}
>
> Argh! That seems surprising. I'd have expected `mkInitialUncovered` to
have produced an empty list there.
This is the right behaviour! The call `(absurd undefined) :: Int` will
crash, not because of evaluating `undefined` but because the match is non-
exhaustive, try it out and see! About `mkInitialUncovered`, it should
**not** produce an empty list: If you check our paper
(https://people.cs.kuleuven.be/~george.karachalias/papers/p424-karachalias.pdf,
paragraph Initialisation, Section 4.2), you will see that U_0 is not
empty, independently of the argument types.
Replying to [comment:14 dfeuer]:
> If I understand it correctly, empty case *always* forces its scrutinee,
and thus should be considered complete if that is guaranteed to diverge. I
don't really understand gkaracha's argument to the contrary, but he knows
much more about this than I do, so I could be missing some key point.
This is probably the key point that is not clear. The part `case x of`
does not force `x`, the patterns that appear after do that. This means
that, for example, `case x of { y -> ... }` does not force x.
== Type Inhabitation ==
All the related tickets give me the impression that it is expected for `f`
to be non-exhaustive and `g` to be exhaustive, which is not in accordance
with Haskell's operational semantics.
{{{#!hs
f :: Int -> a
f x = case x of {}
g :: Void -> a
g x = case x of {}
}}}
Unless you force `x` in another way, both `case x of {}` are equally non-
exhaustive. In OCaml for example this is different, and this is precisely
why the OCaml community identifies the
pattern match checking as a type inhabitation problem
http://www.math.nagoya-u.ac.jp/~garrigue/papers/gadtspm.pdf, in contrast
to what we do.
Nevertheless, there are ways in Haskell to force arguments explicitly
(e.g. via `seq`) which means that it becomes an inhabitation problem for
us as well (like for `g'` below) in some
cases.
{{{#!hs
g' :: Void -> a
g' x = x `seq` case x of {}
}}}
Indeed, this kind of reasoning we lack at the moment. I can imagine that
if the strictness analysis phase came before our checking we would be able
to use this information and improve our reasoning for cases like `g'`, by
checking type inhabitation, where possible.
== Conclusion ==
Personally, I am really happy that the guard from `checkMatches'` is
finally removed, and I surely vote for non-exhaustive warnings in empty
case expressions, including function `absurd` above which **is** non-
exhaustive. I'd be happy to see how we can make `g'` issue no warnings,
but this, I think, is a quite different problem.
Sorry for the long post, I just hope things are more clear now :-)
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10746#comment:15>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list