skip to main content

Lower your guards: a compositional pattern-match coverage checker

Published:03 August 2020Publication History
Skip Abstract Section

Abstract

A compiler should warn if a function defined by pattern matching does not cover its inputs—that is, if there are missing or redundant patterns. Generating such warnings accurately is difficult for modern languages due to the myriad of language features that interact with pattern matching. This is especially true in Haskell, a language with a complicated pattern language that is made even more complex by extensions offered by the Glasgow Haskell Compiler (GHC). Although GHC has spent a significant amount of effort towards improving its pattern-match coverage warnings, there are still several cases where it reports inaccurate warnings.

We introduce a coverage checking algorithm called Lower Your Guards, which boils down the complexities of pattern matching into guard trees. While the source language may have many exotic forms of patterns, guard trees only have three different constructs, which vastly simplifies the coverage checking process. Our algorithm is modular, allowing for new forms of source-language patterns to be handled with little changes to the overall structure of the algorithm. We have implemented the algorithm in GHC and demonstrate places where it performs better than GHC’s current coverage checker, both in accuracy and performance.

Skip Supplemental Material Section

Supplemental Material

Presentation at ICFP '20

References

  1. Lennart Augustsson. 1985. Compiling pattern matching. In Functional Programming Languages and Computer Architecture, Jean-Pierre Jouannaud (Ed.). Springer Berlin Heidelberg, Berlin, Heidelberg, 368-381.Google ScholarGoogle Scholar
  2. Jesper Cockx and Andreas Abel. 2018. Elaborating Dependent (Co)Pattern Matching. Proc. ACM Program. Lang. 2, ICFP, Article 75 ( July 2018 ), 30 pages. https://doi.org/10.1145/3236770 Google ScholarGoogle ScholarDigital LibraryDigital Library
  3. Joshua Dunfield. 2007. A Unified System of Type Refinements. Ph.D. Dissertation. Carnegie Mellon University. CMU-CS-07-129.Google ScholarGoogle Scholar
  4. Richard A. Eisenberg and Jan Stolarek. 2014. Promoting Functions to Type Families in Haskell. In Proceedings of the 2014 ACM SIGPLAN Symposium on Haskell (Gothenburg, Sweden) (Haskell '14). Association for Computing Machinery, New York, NY, USA, 95-106. https://doi.org/10.1145/2633357.2633361 Google ScholarGoogle ScholarDigital LibraryDigital Library
  5. Richard A. Eisenberg and Stephanie Weirich. 2012. Dependently Typed Programming with Singletons. In Proceedings of the 2012 Haskell Symposium (Copenhagen, Denmark) ( Haskell '12). ACM, New York, NY, USA, 117-130. https: //doi.org/10.1145/2364506.2364522 Google ScholarGoogle ScholarDigital LibraryDigital Library
  6. Jacques Garrigue and Jacques Le Normand. 2011. Adding GADTs to OCaml: the direct approach. In Workshop on ML.Google ScholarGoogle Scholar
  7. GHC issue. 2015a. New pattern-match check can be non-performant. https://gitlab.haskell.org/ghc/ghc/issues/11195Google ScholarGoogle Scholar
  8. GHC issue. 2015b. No non-exhaustive pattern match warning given for empty case analysis. https://gitlab.haskell.org/ghc/ ghc/issues/10746Google ScholarGoogle Scholar
  9. GHC issue. 2016a. In a record-update construct:ghc-stage2: panic! (the 'impossible' happened). https://gitlab.haskell.org/ ghc/ghc/issues/12957Google ScholarGoogle Scholar
  10. GHC issue. 2016b. Inaccessible RHS warning is confusing for users. https://gitlab.haskell.org/ghc/ghc/issues/13021Google ScholarGoogle Scholar
  11. GHC issue. 2016c. Pattern coverage checker ignores dictionary arguments. https://gitlab.haskell.org/ghc/ghc/issues/12949Google ScholarGoogle Scholar
  12. GHC issue. 2016d. Pattern match incompleteness / inaccessibility discrepancy. https://gitlab.haskell.org/ghc/ghc/issues/ 11984Google ScholarGoogle Scholar
  13. GHC issue. 2016e. Representation of value set abstractions as trees causes performance issues. https://gitlab.haskell.org/ ghc/ghc/issues/11528Google ScholarGoogle Scholar
  14. GHC issue. 2017a.-Woverlapping-patterns warns on wrong patterns for Int. https://gitlab.haskell.org/ghc/ghc/issues/14546Google ScholarGoogle Scholar
  15. GHC issue. 2017b. COMPLETE sets don't work at all with data family instances. https://gitlab.haskell.org/ghc/ghc/issues/ 14059Google ScholarGoogle Scholar
  16. GHC issue. 2017c. COMPLETE sets nerf redundant pattern-match warnings. https://gitlab.haskell.org/ghc/ghc/issues/13965Google ScholarGoogle Scholar
  17. GHC issue. 2017d. Incorrect pattern match warning on nested GADTs. https://gitlab.haskell.org/ghc/ghc/issues/14098Google ScholarGoogle Scholar
  18. GHC issue. 2017e. Pattern match checker mistakenly concludes pattern match on pattern synonym is unreachable. https://gitlab.haskell.org/ghc/ghc/issues/14253Google ScholarGoogle Scholar
  19. GHC issue. 2017f. Pattern synonym exhaustiveness checks don't play well with EmptyCase. https://gitlab.haskell.org/ghc/ ghc/issues/13717Google ScholarGoogle Scholar
  20. GHC issue. 2017g. Wildcard patterns and COMPLETE sets can lead to misleading redundant pattern-match warnings. https://gitlab.haskell.org/ghc/ghc/issues/13363Google ScholarGoogle Scholar
  21. GHC issue. 2018a.-Wincomplete-patterns gets confused when combining GADTs and pattern guards. https://gitlab.haskell. org/ghc/ghc/issues/15385Google ScholarGoogle Scholar
  22. GHC issue. 2018b. Bogus-Woverlapping-patterns warning with OverloadedStrings. https://gitlab.haskell.org/ghc/ghc/ issues/15713Google ScholarGoogle Scholar
  23. GHC issue. 2018c. Compiling a function with a lot of alternatives bottlenecks on insertIntHeap. https://gitlab.haskell.org/ ghc/ghc/issues/14667Google ScholarGoogle Scholar
  24. GHC issue. 2018d. Completeness of View Patterns With a Complete Set of Output Patterns. https://gitlab.haskell.org/ghc/ ghc/issues/15884Google ScholarGoogle Scholar
  25. GHC issue. 2018e. EmptyCase thinks pattern match involving type family is not exhaustive, when it actually is. https: //gitlab.haskell.org/ghc/ghc/issues/14813Google ScholarGoogle Scholar
  26. GHC issue. 2018f. Erroneous “non-exhaustive pattern match” using nested GADT with strictness annotation. https: //gitlab.haskell.org/ghc/ghc/issues/15305Google ScholarGoogle Scholar
  27. GHC issue. 2018g. Inconsistency w.r.t. coverage checking warnings for EmptyCase under unsatisfiable constraints. https: //gitlab.haskell.org/ghc/ghc/issues/15450Google ScholarGoogle Scholar
  28. GHC issue. 2018h. Inconsistent pattern-match warnings when using guards versus case expressions. https://gitlab.haskell. org/ghc/ghc/issues/15753Google ScholarGoogle Scholar
  29. GHC issue. 2018i. nonVoid is too conservative w.r.t. strict argument types. https://gitlab.haskell.org/ghc/ghc/issues/15584Google ScholarGoogle Scholar
  30. GHC issue. 2018j. “ Pattern match has inaccessible right hand side” with TypeRep. https://gitlab.haskell.org/ghc/ghc/issues/ 14851Google ScholarGoogle Scholar
  31. GHC issue. 2019a. 67-pattern COMPLETE pragma overwhelms the pattern match checker. https://gitlab.haskell.org/ghc/ ghc/issues/17096Google ScholarGoogle Scholar
  32. GHC issue. 2019b. Add Luke Maranget's series in “Warnings for Pattern Matching”. https://gitlab.haskell.org/ghc/ghc/ issues/17264Google ScholarGoogle Scholar
  33. GHC issue. 2019c. `case (x :: Void) of_-> ()` should be flagged as redundant. https://gitlab.haskell.org/ghc/ghc/issues/17376Google ScholarGoogle Scholar
  34. GHC issue. 2019d. GHC thinks pattern match is exhaustive. https://gitlab.haskell.org/ghc/ghc/issues/16289Google ScholarGoogle Scholar
  35. GHC issue. 2019e. Incorrect non-exhaustive pattern warning with PatternSynonyms. https://gitlab.haskell.org/ghc/ghc/ issues/16129Google ScholarGoogle Scholar
  36. GHC issue. 2019f. Minimality of missing pattern set depends on constructor declaration order. https://gitlab.haskell.org/ ghc/ghc/issues/17386Google ScholarGoogle Scholar
  37. GHC issue. 2019g. Panic during tyConAppArgs. https://gitlab.haskell.org/ghc/ghc/issues/17112Google ScholarGoogle Scholar
  38. GHC issue. 2019h. Pattern-match checker : True /= False. https://gitlab.haskell.org/ghc/ghc/issues/17251Google ScholarGoogle Scholar
  39. GHC issue. 2019i. Pattern match checking open unions. https://gitlab.haskell.org/ghc/ghc/issues/17149Google ScholarGoogle Scholar
  40. GHC issue. 2019j. Pattern match overlap checking doesn't consider-XBangPatterns. https://gitlab.haskell.org/ghc/ghc/ issues/17234Google ScholarGoogle Scholar
  41. GHC issue. 2019k. Pattern match warnings are per Match, not per GRHS. https://gitlab.haskell.org/ghc/ghc/issues/17465Google ScholarGoogle Scholar
  42. GHC issue. 2019l. PmCheck treats Newtype patterns the same as constructors. https://gitlab.haskell.org/ghc/ghc/issues/ 17248Google ScholarGoogle Scholar
  43. GHC issue. 2019m. Strictness of pattern synonym matches and pattern-match checking. https://gitlab.haskell.org/ghc/ghc/ issues/17357Google ScholarGoogle Scholar
  44. GHC issue. 2020a.-Wincomplete-record-updates ignores context. https://gitlab.haskell.org/ghc/ghc/issues/17783Google ScholarGoogle Scholar
  45. GHC issue. 2020b. Pattern match checker stumbles over reasonably tricky pattern-match. https://gitlab.haskell.org/ghc/ ghc/issues/17703Google ScholarGoogle Scholar
  46. GHC issue. 2020c. Pattern match coverage checker allocates twice as much for trivial program with instance constraint vs. without. https://gitlab.haskell.org/ghc/ghc/issues/17891Google ScholarGoogle Scholar
  47. GHC issue. 2020d. Pattern match warning emitted twice. https://gitlab.haskell.org/ghc/ghc/issues/17646Google ScholarGoogle Scholar
  48. GHC team. 2020. COMPLETE pragmas. https://downloads.haskell.org/~ghc/8.8.3/docs/html/users_guide/glasgow_exts. html#pragma-COMPLETEGoogle ScholarGoogle Scholar
  49. Pavel Kalvoda and Tom Sydney Kerckhove. 2019. Structural and semantic pattern matching analysis in Haskell. arXiv: 1909. 04160 [cs.PL]Google ScholarGoogle Scholar
  50. Georgios Karachalias, Tom Schrijvers, Dimitrios Vytiniotis, and Simon Peyton Jones. 2015. GADTs meet their match (extended version). Technical Report. KU Leuven. https://people.cs.kuleuven.be/~tom.schrijvers/Research/papers/icfp2015.pdfGoogle ScholarGoogle Scholar
  51. Luc Maranget. 2007. Warnings for pattern matching. Journal of Functional Programming 17 ( 2007 ), 387-421. Issue 3.Google ScholarGoogle Scholar
  52. Ulf Norell. 2007. Towards a practical programming language based on dependent type theory. Ph.D. Dissertation. Department of Computer Science and Engineering, Chalmers University of Technology, SE-412 96 Göteborg, Sweden.Google ScholarGoogle Scholar
  53. Nicolas Oury. 2007. Pattern Matching Coverage Checking with Dependent Types Using Set Approximations. In Proceedings of the 2007 Workshop on Programming Languages Meets Program Verification (Freiburg, Germany) (PLPV '07). Association for Computing Machinery, New York, NY, USA, 47-56. https://doi.org/10.1145/1292597.1292606 Google ScholarGoogle ScholarDigital LibraryDigital Library
  54. Matthew Pickering, Gergő Érdi, Simon Peyton Jones, and Richard A. Eisenberg. 2016. Pattern Synonyms. In Proceedings of the 9th International Symposium on Haskell (Nara, Japan) ( Haskell 2016 ). Association for Computing Machinery, New York, NY, USA, 80-91. https://doi.org/10.1145/2976002.2976013 Google ScholarGoogle ScholarDigital LibraryDigital Library
  55. John Rushby, Sam Owre, and Natarajan Shankar. 1998. Subtypes for specifications: Predicate subtyping in PVS. IEEE Transactions on Software Engineering 24, 9 ( 1998 ), 709-720.Google ScholarGoogle ScholarDigital LibraryDigital Library
  56. R. C. Sekar, R. Ramesh, and I. V. Ramakrishnan. 1995. Adaptive Pattern Matching. SIAM J. Comput. 24, 6 (Dec. 1995 ), 1207-1234. https://doi.org/10.1137/S0097539793246252 Google ScholarGoogle ScholarDigital LibraryDigital Library
  57. Peter Sestoft. 1996. ML pattern match compilation and partial evaluation. In Partial Evaluation. Springer, 446-464.Google ScholarGoogle Scholar
  58. Matthieu Sozeau. 2010. Equations: A Dependent Pattern-Matching Compiler. In Interactive Theorem Proving, Matt Kaufmann and Lawrence C. Paulson (Eds.). Springer Berlin Heidelberg, Berlin, Heidelberg, 419-434.Google ScholarGoogle Scholar
  59. Matthieu Sozeau and Cyprien Mangin. 2019. Equations Reloaded: High-Level Dependently-Typed Functional Programming and Proving in Coq. Proc. ACM Program. Lang. 3, ICFP, Article 86 ( July 2019 ), 29 pages. https://doi.org/10.1145/3341690 Google ScholarGoogle ScholarDigital LibraryDigital Library
  60. Niki Vazou, Eric L. Seidel, Ranjit Jhala, Dimitrios Vytiniotis, and Simon Peyton-Jones. 2014. Refinement Types for Haskell. In Proceedings of the 19th ACM SIGPLAN International Conference on Functional Programming (Gothenburg, Sweden) (ICFP '14). ACM, New York, NY, USA, 269-282. https://doi.org/10.1145/2628136.2628161 Google ScholarGoogle ScholarDigital LibraryDigital Library
  61. Niki Vazou, Anish Tondwalkar, Vikraman Choudhury, Ryan G. Scott, Ryan R. Newton, Philip Wadler, and Ranjit Jhala. 2017. Refinement Reflection: Complete Verification with SMT. Proc. ACM Program. Lang. 2, POPL, Article 53 ( Dec. 2017 ), 31 pages. https://doi.org/10.1145/3158141 Google ScholarGoogle ScholarDigital LibraryDigital Library
  62. Dimitrios Vytiniotis, Simon Peyton Jones, Tom Schrijvers, and Martin Sulzmann. 2011. OutsideIn(X): Modular Type Inference with Local Assumptions. J. Funct. Program. 21, 4-5 ( Sept. 2011 ), 333-412. https://doi.org/10.1017/S0956796811000098 Google ScholarGoogle ScholarDigital LibraryDigital Library
  63. Hongwei Xi. 1998a. Dead Code Elimination Through Dependent Types. In Proceedings of the First International Workshop on Practical Aspects of Declarative Languages (PADL '99). Springer-Verlag, London, UK, 228-242.Google ScholarGoogle ScholarCross RefCross Ref
  64. Hongwei Xi. 1998b. Dependent Types in Practical Programming. Ph.D. Dissertation. Carnegie Mellon University.Google ScholarGoogle ScholarDigital LibraryDigital Library
  65. Hongwei Xi. 2003. Dependently typed pattern matching. Journal of Universal Computer Science 9 ( 2003 ), 851-872.Google ScholarGoogle Scholar
  66. Hongwei Xi, Chiyan Chen, and Gang Chen. 2003. Guarded Recursive Datatype Constructors. In Proceedings of the 30th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (New Orleans, Louisiana, USA) ( POPL '03). ACM, New York, NY, USA, 224-235. https://doi.org/10.1145/604131.604150 Google ScholarGoogle ScholarDigital LibraryDigital Library
  67. Hongwei Xi and Frank Pfenning. 1998. Eliminating Array Bound Checking through Dependent Types. In Proceedings of the ACM SIGPLAN 1998 Conference on Programming Language Design and Implementation (Montreal, Quebec, Canada) ( PLDI '98). Association for Computing Machinery, New York, NY, USA, 249-257. https://doi.org/10.1145/277650.277732 Google ScholarGoogle ScholarDigital LibraryDigital Library
  68. Brent A. Yorgey, Stephanie Weirich, Julien Cretin, Simon Peyton Jones, Dimitrios Vytiniotis, and José Pedro Magalhães. 2012. Giving Haskell a Promotion. In Proceedings of the 8th ACM SIGPLAN Workshop on Types in Language Design and Implementation (Philadelphia, Pennsylvania, USA) ( TLDI '12). ACM, New York, NY, USA, 53-66. https://doi.org/10.1145/ 2103786.2103795 Google ScholarGoogle ScholarDigital LibraryDigital Library

Index Terms

  1. Lower your guards: a compositional pattern-match coverage checker

              Recommendations

              Comments

              Login options

              Check if you have access through your login credentials or your institution to get full access on this article.

              Sign in

              Full Access

              PDF Format

              View or Download as a PDF file.

              PDF

              eReader

              View online with eReader.

              eReader
              About Cookies On This Site

              We use cookies to ensure that we give you the best experience on our website.

              Learn more

              Got it!