Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,413
    • Issues 5,413
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 600
    • Merge requests 600
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #14546
Closed
Open
Issue created Nov 30, 2017 by Lemming@trac-Lemming

-Woverlapping-patterns warns on wrong patterns for Int

GHC-8.0 introduced a new warning on redundant pattern matches in case clauses. But there is something strange.

$ cat RedundantCase.hs
main :: IO ()
main = do
   case 0::Int of
      0 -> putStrLn "A"
      1 -> putStrLn "B"
      _ -> putStrLn "C"

   case 0::Int of
      0 -> putStrLn "A"
      1 -> putStrLn "B"
      2 -> putStrLn "C"

   case 0::Integer of
      0 -> putStrLn "A"
      1 -> putStrLn "B"
      _ -> putStrLn "C"

   case 0::Integer of
      0 -> putStrLn "A"
      1 -> putStrLn "B"
      2 -> putStrLn "C"

   case 0::Integer of
      1 -> putStrLn "B"
      2 -> putStrLn "C"

   let dummy :: Integer
       dummy = 0
   case dummy of
      0 -> putStrLn "A"
      1 -> putStrLn "B"
      _ -> putStrLn "C"

   case "foo" of
      "foo" -> putStrLn "A"
      "bar" -> putStrLn "B"
      "baz" -> putStrLn "C"

   if True
     then putStrLn "X"
     else putStrLn "Y"
$ ghc-8.2.2 -Wall RedundantCase.hs 
[1 of 1] Compiling Main             ( RedundantCase.hs, RedundantCase.o )

RedundantCase.hs:4:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 0 -> ...
  |
4 |       0 -> putStrLn "A"
  |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:5:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 1 -> ...
  |
5 |       1 -> putStrLn "B"
  |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:8:4: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In a case alternative: Patterns not matched: 0
  |
8 |    case 0::Int of
  |    ^^^^^^^^^^^^^^...

RedundantCase.hs:9:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 0 -> ...
  |
9 |       0 -> putStrLn "A"
  |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:10:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 1 -> ...
   |
10 |       1 -> putStrLn "B"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:11:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 2 -> ...
   |
11 |       2 -> putStrLn "C"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:15:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 1 -> ...
   |
15 |       1 -> putStrLn "B"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:16:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: _ -> ...
   |
16 |       _ -> putStrLn "C"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:20:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 1 -> ...
   |
20 |       1 -> putStrLn "B"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:21:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 2 -> ...
   |
21 |       2 -> putStrLn "C"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:23:4: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In a case alternative: Patterns not matched: 0
   |
23 |    case 0::Integer of
   |    ^^^^^^^^^^^^^^^^^^...

RedundantCase.hs:24:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 1 -> ...
   |
24 |       1 -> putStrLn "B"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:25:7: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In a case alternative: 2 -> ...
   |
25 |       2 -> putStrLn "C"
   |       ^^^^^^^^^^^^^^^^^

RedundantCase.hs:34:4: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In a case alternative:
        Patterns not matched:
            []
            (p:_) where p is not one of {'b', 'f'}
            ['b']
            ('b':p:_) where p is not one of {'a'}
            ...
   |
34 |    case "foo" of
   |    ^^^^^^^^^^^^^...
Linking RedundantCase ...

In the first case it warns about the wrong patterns, in the second case it warns about all patterns and a non-exhaustive pattern list. In the following three cases using Integer the warnings seem to be correct. The next case shows that I can suppress the warning if I hide the constant nature of the case selector a bit. Then a case on a String - GHC does not seem to try to detect redundant pattern matches but falls back to a general test on exhaustive pattern lists. Finally, in a constant case on Bool I can avoid the warning using a plain if-then-else.

Now I wonder what the purpose of the warning is at all. First I thought that it wants to warn me, that the patterns overlap, i.e. pattern _ contains the already handled case 0. This does not seem to be the purpose of the warning - and such overlapping patterns are pretty common, aren't they? Second thought: GHC wants to warn me about redundant patterns in the presence of a constant case selector. But then, it does so with varying degrees of success: For Integer it works, but not for Int or String. Is it really only about constant case selectors? Then, not only some pattern matches are redundant but the whole case clause is redundant. Then again, can't we assume that the programmer wrote such a case clause by intend? At least, this is how I use a case clause with constant selector: as a type-safe way to out-comment alternative implementations. Thus my question: Where is this warning useful?

Trac metadata
Trac field Value
Version 8.2.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (Type checker)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking