[GHC] #14547: Wrong warning by -Wincomplete-patterns

GHC ghc-devs at haskell.org
Wed Apr 25 09:00:35 UTC 2018


#14547: Wrong warning by -Wincomplete-patterns
-------------------------------------+-------------------------------------
        Reporter:  YoshikuniJujo     |                Owner:  (none)
            Type:  bug               |               Status:  patch
        Priority:  low               |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:  incomplete-
                                     |  patterns OverloadedLists,
                                     |  PatternMatchWarnings TypeFamilies
Operating System:  Linux             |         Architecture:  x86
 Type of failure:  Incorrect         |            Test Case:
  error/warning at compile-time      |  deSugar/should_compile/T14547
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D4624
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Ah, hmm, I think I see. Given something like
 {{{
 f (toList -> [])     = e1
 f (toList -> (a:as)) = e2
 }}}
 we'd like to declare this function exhaustive.  (Clearly it is!)

 The `ListPat` case of `Check.translatePat` deals with a very special sub-
 case.

 * Using `OverloadedLists`, we generate a special kind of view pattern,
 encoded in the `ListPat` constructor of `Pat`:
 {{{
   | ListPat     (XListPat p)
                 [LPat p]
                 (PostTc p Type)                      -- The type of the
 elements
                 (Maybe (PostTc p Type, SyntaxExpr p)) -- For rebindable
 syntax
                    -- For OverloadedLists a Just (ty,fn) gives
                    -- overall type of the pattern, and the toList
                    -- function to convert the scrutinee to a list value
 }}}

 * You are checking that the function actually has type `[t1] -> [t2]`,
 where `normalise t1 = normalise t2`.

 * In that case, you discard the `toList` view thing altogether, and
 pretend (for the purposes of pattern-match checking) that you wrote
 {{{
 f [] = e1
 f (a:as) = e2
 }}}

 This would not be valid if you'd had
 {{{
 f (toList      -> [])     = e1
 f (weirdToList -> (a:as)) = e2
 }}}
 with two different `toList` functions.  But in this special case the view
 function was injected by the type-driven overloading machinery, so we can
 be confident (I think) that both functions are the same.

 So ''at least'' all this should be explained in a Note.

 But it also seems like a special case that is easily defeated.  For
 example, what about this:
 {{{
 f :: T -> blah
 f (toList -> [])    = ...
 f (toList -> (x:xs) = ...
 }}}
 This too is exhaustive, but it won't be recorded as such, even if you use
 `OverloadedLists`.

 And of course if you use explicit view patterns, things are even worse.

 At least the Note should point out these deficiencies

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14547#comment:7>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list