
#13964: Pattern-match warnings for datatypes with COMPLETE sets break abstraction -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.1-rc2 Resolution: | Keywords: | PatternSynonyms, | PatternMatchWarnings Operating System: Unknown/Multiple | Architecture: Type of failure: Poor/confusing | Unknown/Multiple error message | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): Perhaps I'm fundamentally misunderstanding something about `COMPLETE` sets, but this doesn't feel like a very satisfying explanation. My intuition is that specifying a `COMPLETE` set for a data type is tantamount to overriding the pattern match exhaustiveness checker's behavior w.r.t. to that particular data type, and as such, I would any warnings that are emitted under the `-Wincomplete-patterns` label to be adjusted according to whatever `COMPLETE` sets are in scope. For example, in my original example, I would simply expect that in this warning: {{{ Foo.hs:6:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘catchAll2’: Patterns not matched: Bug.T }}} It would warn about `TooGoodToBeTrue`, not `Bug.T`. That's all. Replying to [comment:2 mpickering]:
This is nothing unique to `COMPLETE` pragmas, the exhaustiveness checker already breaks abstraction in this way.
For example:
{{{ module T (D(A)) where
data D = A | B }}}
{{{ module M where
import T
foo A = () }}}
warns with
{{{ M.hs:5:1: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘foo’: Patterns not matched: T.B | 5 | foo A = () | }}}
That seems fine to me, since the user didn't specify `{-# COMPLETE A #-}` for the data type `D`. If she did, I wouldn't expect a warning for `foo`.
and after all, to retain safety it has to. A function exported by `T` could mention `B` and then be used in `M`.
I don't understand what you mean. A function exported from `T` surely doesn't have any effect on whether a function defined in `M` is exhaustive, right? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13964#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler