[commit: ghc] master: Don't allow orphan COMPLETE pragmas (#13349) (fce3d37)

git at git.haskell.org git at git.haskell.org
Fri Mar 3 00:58:47 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/fce3d37c367346c67467ce3d56bc015fa9ed6062/ghc

>---------------------------------------------------------------

commit fce3d37c367346c67467ce3d56bc015fa9ed6062
Author: Reid Barton <rwbarton at gmail.com>
Date:   Thu Mar 2 16:29:55 2017 -0500

    Don't allow orphan COMPLETE pragmas (#13349)
    
    We might support them properly in the future, but for now it's simpler
    to disallow them.
    
    Test Plan: validate
    
    Reviewers: mpickering, austin, bgamari, simonpj
    
    Reviewed By: mpickering, simonpj
    
    Subscribers: simonpj, thomie
    
    Differential Revision: https://phabricator.haskell.org/D3243


>---------------------------------------------------------------

fce3d37c367346c67467ce3d56bc015fa9ed6062
 compiler/rename/RnBinds.hs                       | 36 +++++++++++++++++++++++-
 docs/users_guide/glasgow_exts.rst                | 13 +++++----
 testsuite/tests/patsyn/should_compile/T13349b.hs |  8 ++++++
 testsuite/tests/patsyn/should_compile/all.T      |  1 +
 testsuite/tests/patsyn/should_fail/T13349.hs     |  5 ++++
 testsuite/tests/patsyn/should_fail/T13349.stderr |  6 ++++
 testsuite/tests/patsyn/should_fail/all.T         |  1 +
 7 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/compiler/rename/RnBinds.hs b/compiler/rename/RnBinds.hs
index f8b3347..705befd 100644
--- a/compiler/rename/RnBinds.hs
+++ b/compiler/rename/RnBinds.hs
@@ -952,10 +952,44 @@ renameSig ctxt sig@(SCCFunSig st v s)
 
 -- COMPLETE Sigs can refer to imported IDs which is why we use
 -- lookupLocatedOccRn rather than lookupSigOccRn
-renameSig _ctxt (CompleteMatchSig s (L l bf) mty)
+renameSig _ctxt sig@(CompleteMatchSig s (L l bf) mty)
   = do new_bf <- traverse lookupLocatedOccRn bf
        new_mty  <- traverse lookupLocatedOccRn mty
+
+       this_mod <- fmap tcg_mod getGblEnv
+       unless (any (nameIsLocalOrFrom this_mod . unLoc) new_bf) $ do
+         -- Why 'any'? See Note [Orphan COMPLETE pragmas]
+         addErrCtxt (text "In" <+> ppr sig) $ failWithTc orphanError
+
        return (CompleteMatchSig s (L l new_bf) new_mty, emptyFVs)
+  where
+    orphanError :: SDoc
+    orphanError =
+      text "Orphan COMPLETE pragmas not supported" $$
+      text "A COMPLETE pragma must mention at least one data constructor" $$
+      text "or pattern synonym defined in the same module."
+
+{-
+Note [Orphan COMPLETE pragmas]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We define a COMPLETE pragma to be a non-orphan if it includes at least
+one conlike defined in the current module. Why is this sufficient?
+Well if you have a pattern match
+
+  case expr of
+    P1 -> ...
+    P2 -> ...
+    P3 -> ...
+
+any COMPLETE pragma which mentions a conlike other than P1, P2 or P3
+will not be of any use in verifying that the pattern match is
+exhaustive. So as we have certainly read the interface files that
+define P1, P2 and P3, we will have loaded all non-orphan COMPLETE
+pragmas that could be relevant to this pattern match.
+
+For now we simply disallow orphan COMPLETE pragmas, as the added
+complexity of supporting them properly doesn't seem worthwhile.
+-}
 
 ppr_sig_bndrs :: [Located RdrName] -> SDoc
 ppr_sig_bndrs bs = quotes (pprWithCommas ppr bs)
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index 205e12a..3e6e50c 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -13128,11 +13128,14 @@ and ``RightChoice`` is total. ::
 definition matches on all the constructors specified in the pragma then the
 compiler will produce no warning.
 
-``COMPLETE`` pragmas can contain any data constructors or pattern synonyms
-which are in scope. Once defined, they are automatically imported and exported
-from modules. ``COMPLETE`` pragmas should be thought of as asserting a universal
-truth about a set of patterns and as a result, should not be used to silence
-context specific incomplete match warnings.
+``COMPLETE`` pragmas can contain any data constructors or pattern
+synonyms which are in scope, but must mention at least one data
+constructor or pattern synonym defined in the same module.
+``COMPLETE`` pragmas may only appear at the top level of a module.
+Once defined, they are automatically imported and exported from
+modules. ``COMPLETE`` pragmas should be thought of as asserting a
+universal truth about a set of patterns and as a result, should not be
+used to silence context specific incomplete match warnings.
 
 When specifing a ``COMPLETE`` pragma, the result types of all patterns must
 be consistent with each other. This is a sanity check as it would be impossible
diff --git a/testsuite/tests/patsyn/should_compile/T13349b.hs b/testsuite/tests/patsyn/should_compile/T13349b.hs
new file mode 100644
index 0000000..9d77d56
--- /dev/null
+++ b/testsuite/tests/patsyn/should_compile/T13349b.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PatternSynonyms #-}
+
+module T13349b where
+
+pattern Nada = Nothing
+
+-- Not orphan because it mentions the locally-defined Nada.
+{-# COMPLETE Just, Nada #-}
diff --git a/testsuite/tests/patsyn/should_compile/all.T b/testsuite/tests/patsyn/should_compile/all.T
index a5066ea..87de2f0 100644
--- a/testsuite/tests/patsyn/should_compile/all.T
+++ b/testsuite/tests/patsyn/should_compile/all.T
@@ -63,3 +63,4 @@ test('T12615', normal, compile, [''])
 test('T12698', normal, compile, [''])
 test('T12746', normal, multi_compile, ['T12746', [('T12746A.hs', '-c')],'-v0'])
 test('T12968', normal, compile, [''])
+test('T13349b', normal, compile, [''])
diff --git a/testsuite/tests/patsyn/should_fail/T13349.hs b/testsuite/tests/patsyn/should_fail/T13349.hs
new file mode 100644
index 0000000..45bdc23
--- /dev/null
+++ b/testsuite/tests/patsyn/should_fail/T13349.hs
@@ -0,0 +1,5 @@
+{-# LANGUAGE PatternSynonyms #-}
+
+module T13349 where
+
+{-# COMPLETE False #-}
diff --git a/testsuite/tests/patsyn/should_fail/T13349.stderr b/testsuite/tests/patsyn/should_fail/T13349.stderr
new file mode 100644
index 0000000..5bf91cb
--- /dev/null
+++ b/testsuite/tests/patsyn/should_fail/T13349.stderr
@@ -0,0 +1,6 @@
+
+T13349.hs:5:1: error:
+    • Orphan COMPLETE pragmas not supported
+      A COMPLETE pragma must mention at least one data constructor
+      or pattern synonym defined in the same module.
+    • In {-# COMPLETE False #-}
diff --git a/testsuite/tests/patsyn/should_fail/all.T b/testsuite/tests/patsyn/should_fail/all.T
index 50a3eea..f674a8b 100644
--- a/testsuite/tests/patsyn/should_fail/all.T
+++ b/testsuite/tests/patsyn/should_fail/all.T
@@ -34,3 +34,4 @@ test('T11667', normal, compile_fail, [''])
 test('T12165', normal, compile_fail, [''])
 test('T12819', normal, compile_fail, [''])
 test('UnliftedPSBind', normal, compile_fail, [''])
+test('T13349', normal, compile_fail, [''])



More information about the ghc-commits mailing list