summaryrefslogtreecommitdiff
path: root/compiler/parser
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2017-01-18 13:25:30 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2017-01-26 00:22:46 +0000
commit1a3f1eebf81952accb6340252816211c7d391300 (patch)
tree03fbe6fac6518c3da73282266833941d76b34736 /compiler/parser
parent078c21140d4f27e586c9fa893d4ac94d28d6013c (diff)
downloadhaskell-1a3f1eebf81952accb6340252816211c7d391300.tar.gz
COMPLETE pragmas for enhanced pattern exhaustiveness checking
This patch adds a new pragma so that users can specify `COMPLETE` sets of `ConLike`s in order to sate the pattern match checker. A function which matches on all the patterns in a complete grouping will not cause the exhaustiveness checker to emit warnings. ``` pattern P :: () pattern P = () {-# COMPLETE P #-} foo P = () ``` This example would previously have caused the checker to warn that all cases were not matched even though matching on `P` is sufficient to make `foo` covering. With the addition of the pragma, the compiler will recognise that matching on `P` alone is enough and not emit any warnings. Reviewers: goldfire, gkaracha, alanz, austin, bgamari Reviewed By: alanz Subscribers: lelf, nomeata, gkaracha, thomie Differential Revision: https://phabricator.haskell.org/D2669 GHC Trac Issues: #8779
Diffstat (limited to 'compiler/parser')
-rw-r--r--compiler/parser/Lexer.x7
-rw-r--r--compiler/parser/Parser.y13
-rw-r--r--compiler/parser/RdrHsSyn.hs2
3 files changed, 19 insertions, 3 deletions
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x
index 6c4abe047a..63715a08a8 100644
--- a/compiler/parser/Lexer.x
+++ b/compiler/parser/Lexer.x
@@ -636,6 +636,7 @@ data Token
| ITunpack_prag SourceText
| ITnounpack_prag SourceText
| ITann_prag SourceText
+ | ITcomplete_prag SourceText
| ITclose_prag
| IToptions_prag String
| ITinclude_prag String
@@ -2716,7 +2717,7 @@ ignoredPrags = Map.fromList (map ignored pragmas)
-- CFILES is a hugs-only thing.
pragmas = options_pragmas ++ ["cfiles", "contract"]
-oneWordPrags = Map.fromList([
+oneWordPrags = Map.fromList [
("rules", rulePrag),
("inline",
strtoken (\s -> (ITinline_prag (SourceText s) Inline FunLike))),
@@ -2744,7 +2745,9 @@ oneWordPrags = Map.fromList([
("overlappable", strtoken (\s -> IToverlappable_prag (SourceText s))),
("overlapping", strtoken (\s -> IToverlapping_prag (SourceText s))),
("incoherent", strtoken (\s -> ITincoherent_prag (SourceText s))),
- ("ctype", strtoken (\s -> ITctype (SourceText s)))])
+ ("ctype", strtoken (\s -> ITctype (SourceText s))),
+ ("complete", strtoken (\s -> ITcomplete_prag (SourceText s)))
+ ]
twoWordPrags = Map.fromList([
("inline conlike",
diff --git a/compiler/parser/Parser.y b/compiler/parser/Parser.y
index 222867483c..2b70fb7999 100644
--- a/compiler/parser/Parser.y
+++ b/compiler/parser/Parser.y
@@ -441,6 +441,7 @@ are the most common patterns, rewritten as regular expressions for clarity:
'{-# OVERLAPPABLE' { L _ (IToverlappable_prag _) }
'{-# OVERLAPS' { L _ (IToverlaps_prag _) }
'{-# INCOHERENT' { L _ (ITincoherent_prag _) }
+ '{-# COMPLETE' { L _ (ITcomplete_prag _) }
'#-}' { L _ ITclose_prag }
'..' { L _ ITdotdot } -- reserved symbols
@@ -1672,6 +1673,10 @@ opt_asig :: { ([AddAnn],Maybe (LHsType RdrName)) }
: {- empty -} { ([],Nothing) }
| '::' atype { ([mu AnnDcolon $1],Just $2) }
+opt_tyconsig :: { ([AddAnn], Maybe (Located RdrName)) }
+ : {- empty -} { ([], Nothing) }
+ | '::' gtycon { ([mu AnnDcolon $1], Just $2) }
+
sigtype :: { LHsType RdrName }
: ctype { $1 }
@@ -2248,6 +2253,13 @@ sigdecl :: { LHsDecl RdrName }
| pattern_synonym_sig { sLL $1 $> . SigD . unLoc $ $1 }
+ | '{-# COMPLETE' con_list opt_tyconsig '#-}'
+ {% let (dcolon, tc) = $3
+ in ams
+ (sLL $1 $>
+ (SigD (CompleteMatchSig (getCOMPLETE_PRAGs $1) $2 tc)))
+ ([ mo $1 ] ++ dcolon ++ [mc $4]) }
+
-- This rule is for both INLINE and INLINABLE pragmas
| '{-# INLINE' activation qvar '#-}'
{% ams ((sLL $1 $> $ SigD (InlineSig $3
@@ -3393,6 +3405,7 @@ getTH_ID_TY_SPLICE (L _ (ITidTyEscape x)) = x
getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl)
getSPEC_INLINE (L _ (ITspec_inline_prag _ True)) = (Inline, FunLike)
getSPEC_INLINE (L _ (ITspec_inline_prag _ False)) = (NoInline,FunLike)
+getCOMPLETE_PRAGs (L _ (ITcomplete_prag x)) = x
getDOCNEXT (L _ (ITdocCommentNext x)) = x
getDOCPREV (L _ (ITdocCommentPrev x)) = x
diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 2c9600427c..64a60c4841 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -7,7 +7,7 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
-module RdrHsSyn (
+module RdrHsSyn (
mkHsOpApp,
mkHsIntegral, mkHsFractional, mkHsIsString,
mkHsDo, mkSpliceDecl,