[commit: ghc] wip/rae: Fix #13391 by checking for kind-GADTs (75fedb8)

git at git.haskell.org git at git.haskell.org
Wed Aug 16 19:18:46 UTC 2017


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

On branch  : wip/rae
Link       : http://ghc.haskell.org/trac/ghc/changeset/75fedb89688808b9bf0d1516e0b90cf2e1d0b20b/ghc

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

commit 75fedb89688808b9bf0d1516e0b90cf2e1d0b20b
Author: Richard Eisenberg <rae at cs.brynmawr.edu>
Date:   Tue Aug 15 17:22:50 2017 -0400

    Fix #13391 by checking for kind-GADTs
    
    The check is a bit gnarly, but I couldn't think of a better way.
    See the new code in TcTyClsDecls.
    
    test case: polykinds/T13391


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

75fedb89688808b9bf0d1516e0b90cf2e1d0b20b
 compiler/basicTypes/DataCon.hs                     |  2 ++
 compiler/typecheck/TcTyClsDecls.hs                 | 29 ++++++++++++++++++++++
 .../should_compile/Dep2.hs => polykinds/T13391.hs} |  6 ++---
 testsuite/tests/polykinds/T13391.stderr            |  7 ++++++
 testsuite/tests/polykinds/all.T                    |  1 +
 5 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/compiler/basicTypes/DataCon.hs b/compiler/basicTypes/DataCon.hs
index fa8e0a8..06bb504 100644
--- a/compiler/basicTypes/DataCon.hs
+++ b/compiler/basicTypes/DataCon.hs
@@ -310,6 +310,8 @@ data DataCon
         -- Universally-quantified type vars [a,b,c]
         -- INVARIANT: length matches arity of the dcRepTyCon
         -- INVARIANT: result type of data con worker is exactly (T a b c)
+        -- COROLLARY: The dcUnivTyVars are always in one-to-one correspondence with
+        --            the tyConTyVars of the parent TyCon
         dcUnivTyVars    :: [TyVarBinder],
 
         -- Existentially-quantified type vars [x,y]
diff --git a/compiler/typecheck/TcTyClsDecls.hs b/compiler/typecheck/TcTyClsDecls.hs
index ba35db5..a944e09 100644
--- a/compiler/typecheck/TcTyClsDecls.hs
+++ b/compiler/typecheck/TcTyClsDecls.hs
@@ -2492,6 +2492,26 @@ checkValidDataCon dflags existential_ok tc con
         ; checkTc (existential_ok || isVanillaDataCon con)
                   (badExistential con)
 
+        ; typeintype <- xoptM LangExt.TypeInType
+        ; let invisible_gadt_eq_specs = filter is_invisible_eq_spec (dataConEqSpec con)
+              univ_tvs = dataConUnivTyVars con
+              tc_bndrs = tyConBinders tc
+
+                -- find the index of the univ tv mentioned in the eq_spec
+                -- then, look that up in the TyConBinders to see if it's visible
+                -- Maybe there's a better way, but I don't see it.
+                -- See Note [Wrong visibility for GADTs], though.
+              is_invisible_eq_spec eq_spec
+                = let eq_tv    = eqSpecTyVar eq_spec
+                      tv_index = expectJust "checkValidDataCon" $
+                                 elemIndex eq_tv univ_tvs
+                      tc_bndr  = tc_bndrs `getNth` tv_index
+                  in
+                  isInvisibleTyConBinder tc_bndr
+
+        ; checkTc (typeintype || null invisible_gadt_eq_specs)
+                  (badGADT con invisible_gadt_eq_specs)
+
           -- Check that UNPACK pragmas and bangs work out
           -- E.g.  reject   data T = MkT {-# UNPACK #-} Int     -- No "!"
           --                data T = MkT {-# UNPACK #-} !a      -- Can't unpack
@@ -3154,6 +3174,15 @@ badExistential con
        2 (vcat [ ppr con <+> dcolon <+> ppr (dataConUserType con)
                , parens $ text "Use ExistentialQuantification or GADTs to allow this" ])
 
+badGADT :: DataCon -> [EqSpec] -> SDoc
+badGADT con eq_specs
+  = hang (text "Data constructor" <+> quotes (ppr con) <+>
+               text "constrains the choice of kind parameter" <> plural eq_specs <> colon)
+       2 (vcat (map ppr_eq_spec eq_specs)) $$
+    text "Use TypeInType to allow this"
+  where
+    ppr_eq_spec eq_spec = ppr (eqSpecTyVar eq_spec) <+> char '~' <+> ppr (eqSpecType eq_spec)
+
 badStupidTheta :: Name -> SDoc
 badStupidTheta tc_name
   = text "A data type declared in GADT style cannot have a context:" <+> quotes (ppr tc_name)
diff --git a/testsuite/tests/dependent/should_compile/Dep2.hs b/testsuite/tests/polykinds/T13391.hs
similarity index 50%
copy from testsuite/tests/dependent/should_compile/Dep2.hs
copy to testsuite/tests/polykinds/T13391.hs
index 34be3cf..6de3c3a 100644
--- a/testsuite/tests/dependent/should_compile/Dep2.hs
+++ b/testsuite/tests/polykinds/T13391.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE PolyKinds, GADTs #-}
 
-module Dep2 where
+module T13391 where
 
 data G (a :: k) where
-  G1 :: G Int
-  G2 :: G Maybe
+  GInt   :: G Int
+  GMaybe :: G Maybe
diff --git a/testsuite/tests/polykinds/T13391.stderr b/testsuite/tests/polykinds/T13391.stderr
new file mode 100644
index 0000000..55fff35
--- /dev/null
+++ b/testsuite/tests/polykinds/T13391.stderr
@@ -0,0 +1,7 @@
+
+T13391.hs:6:3: error:
+    • Data constructor ‘GInt’ constrains the choice of kind parameter:
+        k ~ *
+      Use TypeInType to allow this
+    • In the definition of data constructor ‘GInt’
+      In the data type declaration for ‘G’
diff --git a/testsuite/tests/polykinds/all.T b/testsuite/tests/polykinds/all.T
index 900faca..ebe5f85 100644
--- a/testsuite/tests/polykinds/all.T
+++ b/testsuite/tests/polykinds/all.T
@@ -163,3 +163,4 @@ test('T13393', normal, compile_fail, [''])
 test('T13555', normal, compile_fail, [''])
 test('T13659', normal, compile_fail, [''])
 test('T13625', normal, compile_fail, [''])
+test('T13391', normal, compile_fail, [''])



More information about the ghc-commits mailing list