summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrevor Elliott <trevor@galois.com>2013-09-08 16:46:17 -0700
committerTrevor Elliott <trevor@galois.com>2013-09-08 16:46:17 -0700
commit86bf4164c30e210aa280610ec719d01e62cc95a4 (patch)
tree04bb65ac37c070628858a1b181925401d7dececd
parentc798a8c6c66d826efdc0201fa56d45337eecc2af (diff)
downloadhaskell-86bf4164c30e210aa280610ec719d01e62cc95a4.tar.gz
Squashed commit of the following:
commit 6549c3e569d0e0c3714814860201924432da2435 Author: Trevor Elliott <trevor@galois.com> Date: Sun Sep 8 16:43:42 2013 -0700 Document `data kind` syntax commit 81c6d7b884e819cf0b0569cef23b67bb5aff8944 Merge: 6c3f34c c798a8c Author: Trevor Elliott <trevor@galois.com> Date: Sun Sep 8 11:40:47 2013 -0700 Merge remote-tracking branch 'head/master' into data-kind-syntax-v2 commit 6c3f34c80bd8b17920a956e194ec29d1affbd776 Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Wed Aug 28 02:21:07 2013 -0400 Merge with the roles changes There a bunch of spots where the roles haven't been properly integrated with, so this patch should get some review. commit 6bb530f50f655e74fb4e337311699eee46b519b7 Merge: 7d27880 4b5238a Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Tue Aug 27 02:35:55 2013 -0400 Merge remote-tracking branch 'head/master' into data-kind-syntax-v2 Conflicts: compiler/basicTypes/DataCon.lhs compiler/iface/IfaceSyn.lhs compiler/main/PprTyThing.hs compiler/parser/Lexer.x compiler/parser/Parser.y.pp compiler/typecheck/TcInstDcls.lhs compiler/typecheck/TcTyClsDecls.lhs compiler/typecheck/TcTyDecls.lhs compiler/types/TyCon.lhs commit 7d2788021dab549ffd888deb9f28c8e7eab0d4ba Author: Trevor Elliott <trevor@galois.com> Date: Mon Jul 29 09:05:38 2013 -0700 Migrate through some lost instances commit 13e1f41ec9252fd9d547d8e4b9fb04ffaf43c105 Merge: e051060 9e185cc Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Sun Jul 28 14:28:05 2013 -0400 Merge remote-tracking branch 'origin/master' into data-kind-syntax-v2 Moved Binary instances for data-kind related types to IfaceSyn commit e051060bbef4d359f2b1caa1c6135b23df17ffe7 Merge: 08d7c2f 2f99cdb Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Wed Jul 17 01:58:16 2013 -0400 Merge remote-tracking branch 'origin/master' into data-kind-syntax-v2 commit 08d7c2fca10a8c89b6fd638536a28972753ae360 Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Mon Jul 1 21:56:48 2013 -0400 Fix some bugs from the merge with master * Figure out what the right choice for the kind checking strategy of kind decls should be commit 12f055d23a1b5c0a74d2db0784b779b605f3888f Merge: f0adbdc e56b9d5 Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Mon Jul 1 21:12:47 2013 -0400 Merge remote-tracking branch 'origin/master' into data-kind-syntax-v2 Conflicts: compiler/typecheck/TcTyClsDecls.lhs commit f0adbdc29fefc54675f0960e3178f3b079058eea Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Sun Jun 23 15:53:06 2013 -0400 Swap the names for PromotionFlavor and PromotionInfo commit e177270dc002f45286a9b644935ea339d8a6c8d3 Merge: 16df4be 3660ef9 Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Sat Jun 22 04:00:15 2013 -0400 Merge remote-tracking branch 'origin/master' into data-kind-syntax-v2 commit 16df4beac24065d3075a65b26add543452d1f2b2 Merge: b021b30 569b265 Author: Trevor Elliott <awesomelyawesome@gmail.com> Date: Sat Jun 22 02:41:14 2013 -0400 merge with master commit b021b30f66fdb66965f6c57fb0969317c9aeb9e3 Author: Trevor Elliott <trevor@galois.com> Date: Thu Jun 20 19:39:20 2013 -0700 Start reworking comments commit b765370181571c1922b508f8dd17648a090ac248 Merge: d1ac794 e4fc6fd Author: Trevor Elliott <trevor@galois.com> Date: Thu Jun 20 18:27:43 2013 -0700 Merge branch 'master' into data-kind-syntax-v2 commit d1ac794b5bd06ae04e014cabe4560628b70fcdeb Merge: 9ad0a3c 73991d6 Author: Trevor Elliott <trevor@galois.com> Date: Thu Jun 20 18:16:15 2013 -0700 Merge remote-tracking branch 'origin/master' into data-kind-syntax-v2 commit 9ad0a3c57a5b77f5040f1201b2c53a84680c1af2 Author: Trevor Elliott <trevor@galois.com> Date: Thu Jun 20 18:13:58 2013 -0700 Don't add the promotion tick to data kind constructors commit 8c37784e31702ecf7d91f2d7cf7dfab675a56927 Merge: 4dff379 db9b631 Author: Trevor Elliott <trevor@galois.com> Date: Mon Jun 17 10:55:51 2013 -0700 Merge remote-tracking branch 'origin/master' into data-kind-syntax-v2 Conflicts: compiler/main/PprTyThing.hs compiler/rename/RnTypes.lhs compiler/types/TyCon.lhs commit 4dff3791ac9d1175d26f8c3b44923aefbe6c3f40 Author: Trevor Elliott <trevor@galois.com> Date: Mon Jun 3 20:45:00 2013 -0700 When parsing interfaces, use forkM while checking type constructors commit 7903009475b3e89aecc0a8e5d328ea84ea53a39d Author: Trevor Elliott <trevor@galois.com> Date: Mon Jun 3 20:06:40 2013 -0700 When parsing data kind declarations, don't change the constructor namespace commit 78ff545601cedba106eda05a38ce8f24f8480961 Author: Trevor Elliott <trevor@galois.com> Date: Mon May 27 18:45:52 2013 -0700 Switch from Maybe TyCon to a richer type for promotion The new type distinguishes the two cases where promotion isn't possible: 1) Promotion isn't possible, as it's disabled by a 'data type' declaration 2) Promotion isn't possible because we don't know how to promote it commit 0573fd3e8f9822171ddeb0df937e10075b653678 Author: Trevor Elliott <trevor@galois.com> Date: Mon May 27 17:36:21 2013 -0700 Remove an old TODO commit e218d5d6848109e9dea129250199115a9db6b1d9 Author: Trevor Elliott <trevor@galois.com> Date: Mon May 27 17:36:15 2013 -0700 Properly print data kind declarations in ghci commit 22b011d43f84cb0478eded613344e1dd165664e5 Author: Trevor Elliott <trevor@galois.com> Date: Thu May 16 18:38:22 2013 -0700 Switch to using the PromotedDataCon for the RHS of a data kind Something is still wrong here: doing :browse will get a panic for some reason. commit 12db8c704765d2775b0299c2e718d015577a6f18 Author: Trevor Elliott <trevor@galois.com> Date: Sat May 4 19:06:43 2013 -0700 Thread data kind syntax through the interface Things are not quite right at the moment. The issue is that we can't distinguish abstract types from types that are constructors in a data kind. As such, we should introduce a new constructor to TyCon to help disambiguate these two cases. Also it might be nice to add a new TyCon for kinds, which would avoid the need for a new RHS in the AlgTyCon case. commit 73f19612444e2a3b1534ab41f02449c9a5191ccb Author: Trevor Elliott <trevor@galois.com> Date: Tue Apr 30 20:30:21 2013 -0700 Handle kind declarations separately commit 8d3bf040748026829382c5d13421f910b3f9fcf9 Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 20:40:49 2013 -0700 Partial type-kind checking of `data kind` declarations commit 2399eb788ed0fe571c22de4f810080a323ddaceb Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 18:01:28 2013 -0700 Support empty `data kind` declarations commit 61a28f2df42b34742219a97a22c029f840fef7f5 Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 17:34:31 2013 -0700 Rename `data kind` declarations commit 5d3485a3e3ab7a78f1055b872f78203d5d005b76 Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 16:53:26 2013 -0700 Fix a typo in a parser comment commit 7f631cf41a3ca84cd820b292711014b4e806a440 Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 16:53:00 2013 -0700 Add paring for `data kind` declarations commit d29733901b2cd195989cdc972ac74c1ed4f19670 Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 14:31:30 2013 -0700 Rename typeLiteralsBit to dataKindsBit in the lexer commit ca8ae194826fc47a2ba4f0188d62f5247b0fe631 Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 14:27:50 2013 -0700 Add a check for -XDataKinds when parsing a `data type` declaration commit 8588717e8ce224affa584bd1e27aa14e098f5a8f Author: Trevor Elliott <trevor@galois.com> Date: Fri Apr 26 14:18:41 2013 -0700 Implement the 'data type' syntax and checking Add a new form of data declaration where the 'type' modifier can be used to prevent data promotion. For example data type T = K will not yield a promoted kind T, and promoted type K, even though they are in principle promotable.
-rw-r--r--compiler/basicTypes/DataCon.lhs11
-rw-r--r--compiler/hsSyn/Convert.lhs4
-rw-r--r--compiler/hsSyn/HsDecls.lhs64
-rw-r--r--compiler/hsSyn/HsUtils.lhs3
-rw-r--r--compiler/iface/IfaceSyn.lhs86
-rw-r--r--compiler/iface/MkIface.lhs15
-rw-r--r--compiler/iface/TcIface.lhs34
-rw-r--r--compiler/main/HscTypes.lhs15
-rw-r--r--compiler/main/PprTyThing.hs28
-rw-r--r--compiler/parser/HaddockUtils.hs13
-rw-r--r--compiler/parser/Lexer.x14
-rw-r--r--compiler/parser/Parser.y.pp58
-rw-r--r--compiler/parser/RdrHsSyn.lhs92
-rw-r--r--compiler/prelude/TysWiredIn.lhs10
-rw-r--r--compiler/rename/RnSource.lhs45
-rw-r--r--compiler/rename/RnTypes.lhs14
-rw-r--r--compiler/typecheck/TcGenGenerics.lhs2
-rw-r--r--compiler/typecheck/TcHsType.lhs11
-rw-r--r--compiler/typecheck/TcInstDcls.lhs4
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs100
-rw-r--r--compiler/typecheck/TcTyDecls.lhs7
-rw-r--r--compiler/types/TyCon.lhs128
-rw-r--r--compiler/types/TypeRep.lhs5
-rw-r--r--compiler/vectorise/Vectorise/Generic/PData.hs2
-rw-r--r--compiler/vectorise/Vectorise/Type/TyConDecl.hs5
-rw-r--r--docs/users_guide/glasgow_exts.xml75
26 files changed, 751 insertions, 94 deletions
diff --git a/compiler/basicTypes/DataCon.lhs b/compiler/basicTypes/DataCon.lhs
index 51a096b10f..1c81934408 100644
--- a/compiler/basicTypes/DataCon.lhs
+++ b/compiler/basicTypes/DataCon.lhs
@@ -1004,13 +1004,13 @@ buildAlgTyCon :: Name
-> ThetaType -- ^ Stupid theta
-> AlgTyConRhs
-> RecFlag
- -> Bool -- ^ True <=> this TyCon is promotable
+ -> PromotionInfo ()
-> Bool -- ^ True <=> was declared in GADT syntax
-> TyConParent
-> TyCon
buildAlgTyCon tc_name ktvs roles cType stupid_theta rhs
- is_rec is_promotable gadt_syn parent
+ is_rec prom_flavor gadt_syn parent
= tc
where
kind = mkPiKinds ktvs liftedTypeKind
@@ -1018,11 +1018,10 @@ buildAlgTyCon tc_name ktvs roles cType stupid_theta rhs
-- tc and mb_promoted_tc are mutually recursive
tc = mkAlgTyCon tc_name kind ktvs roles cType stupid_theta
rhs parent is_rec gadt_syn
- mb_promoted_tc
+ promotion_info
- mb_promoted_tc
- | is_promotable = Just (mkPromotedTyCon tc (promoteKind kind))
- | otherwise = Nothing
+ promotion_info =
+ fmap (\ _ -> mkPromotedTyCon tc (promoteKind kind)) prom_flavor
\end{code}
diff --git a/compiler/hsSyn/Convert.lhs b/compiler/hsSyn/Convert.lhs
index 383b641262..123bfeac07 100644
--- a/compiler/hsSyn/Convert.lhs
+++ b/compiler/hsSyn/Convert.lhs
@@ -166,6 +166,7 @@ cvtDec (DataD ctxt tc tvs constrs derivs)
; cons' <- mapM cvtConstr constrs
; derivs' <- cvtDerivs derivs
; let defn = HsDataDefn { dd_ND = DataType, dd_cType = Nothing
+ , dd_try_promote = True
, dd_ctxt = ctxt'
, dd_kindSig = Nothing
, dd_cons = cons', dd_derivs = derivs' }
@@ -177,6 +178,7 @@ cvtDec (NewtypeD ctxt tc tvs constr derivs)
; con' <- cvtConstr constr
; derivs' <- cvtDerivs derivs
; let defn = HsDataDefn { dd_ND = NewType, dd_cType = Nothing
+ , dd_try_promote = True
, dd_ctxt = ctxt'
, dd_kindSig = Nothing
, dd_cons = [con'], dd_derivs = derivs' }
@@ -224,6 +226,7 @@ cvtDec (DataInstD ctxt tc tys constrs derivs)
; cons' <- mapM cvtConstr constrs
; derivs' <- cvtDerivs derivs
; let defn = HsDataDefn { dd_ND = DataType, dd_cType = Nothing
+ , dd_try_promote = True
, dd_ctxt = ctxt'
, dd_kindSig = Nothing
, dd_cons = cons', dd_derivs = derivs' }
@@ -237,6 +240,7 @@ cvtDec (NewtypeInstD ctxt tc tys constr derivs)
; con' <- cvtConstr constr
; derivs' <- cvtDerivs derivs
; let defn = HsDataDefn { dd_ND = NewType, dd_cType = Nothing
+ , dd_try_promote = True
, dd_ctxt = ctxt'
, dd_kindSig = Nothing
, dd_cons = [con'], dd_derivs = derivs' }
diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs
index ee4b0fab34..0828c6ec8f 100644
--- a/compiler/hsSyn/HsDecls.lhs
+++ b/compiler/hsSyn/HsDecls.lhs
@@ -16,7 +16,7 @@ module HsDecls (
HsDecl(..), LHsDecl, HsDataDefn(..),
-- ** Class or type declarations
TyClDecl(..), LTyClDecl, TyClGroup,
- isClassDecl, isDataDecl, isSynDecl, tcdName,
+ isClassDecl, isDataDecl, isKindDecl, isSynDecl, tcdName,
isFamilyDecl, isTypeFamilyDecl, isDataFamilyDecl,
isOpenTypeFamilyInfo, isClosedTypeFamilyInfo,
tyFamInstDeclName, tyFamInstDeclLName,
@@ -50,6 +50,8 @@ module HsDecls (
-- ** Data-constructor declarations
ConDecl(..), LConDecl, ResType(..),
HsConDeclDetails, hsConDeclArgTys,
+ TyConDecl(..), LTyConDecl,
+ HsTyConDeclDetails,
-- ** Document comments
DocDecl(..), LDocDecl, docDeclDoc,
-- ** Deprecations
@@ -456,6 +458,12 @@ data TyClDecl name
, tcdDataDefn :: HsDataDefn name
, tcdFVs :: NameSet }
+ | -- | @data kind@ declaration
+ KindDecl { tcdLName :: Located name
+ , tcdKVars :: [Located name]
+ , tcdTypeCons :: [LTyConDecl name]
+ , tcdFvs :: NameSet }
+
| ClassDecl { tcdCtxt :: LHsContext name, -- ^ Context...
tcdLName :: Located name, -- ^ Name of the class
tcdTyVars :: LHsTyVarBndrs name, -- ^ Class type variables
@@ -497,6 +505,10 @@ isDataDecl :: TyClDecl name -> Bool
isDataDecl (DataDecl {}) = True
isDataDecl _other = False
+isKindDecl :: TyClDecl name -> Bool
+isKindDecl (KindDecl {}) = True
+isKindDecl _ = False
+
-- | type or type instance declaration
isSynDecl :: TyClDecl name -> Bool
isSynDecl (SynDecl {}) = True
@@ -566,6 +578,7 @@ tyClDeclTyVars d = tcdTyVars d
\begin{code}
countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int)
-- class, synonym decls, data, newtype, family decls
+ -- we don't count `data kind` decls here
countTyClDecls decls
= (count isClassDecl decls,
count isSynDecl decls, -- excluding...
@@ -596,6 +609,9 @@ instance OutputableBndr name
ppr (DataDecl { tcdLName = ltycon, tcdTyVars = tyvars, tcdDataDefn = defn })
= pp_data_defn (pp_vanilla_decl_head ltycon tyvars) defn
+ ppr (KindDecl { tcdLName = lkcon, tcdKVars = kvars, tcdTypeCons = cons })
+ = pp_kind_decl lkcon kvars cons
+
ppr (ClassDecl {tcdCtxt = context, tcdLName = lclas, tcdTyVars = tyvars,
tcdFDs = fds,
tcdSigs = sigs, tcdMeths = methods,
@@ -660,6 +676,7 @@ pprTyClDeclFlavour (FamDecl {}) = ptext (sLit "family")
pprTyClDeclFlavour (SynDecl {}) = ptext (sLit "type")
pprTyClDeclFlavour (DataDecl { tcdDataDefn = (HsDataDefn { dd_ND = nd }) })
= ppr nd
+pprTyClDeclFlavour (KindDecl {}) = ptext (sLit "data kind")
pprTyClDeclFlavour (ForeignType {}) = ptext (sLit "foreign type")
\end{code}
@@ -682,6 +699,10 @@ data HsDataDefn name -- The payload of a data type defn
HsDataDefn { dd_ND :: NewOrData,
dd_ctxt :: LHsContext name, -- ^ Context
dd_cType :: Maybe CType,
+ dd_try_promote :: Bool,
+ -- ^ This boolean determines whether we should try to promote
+ -- the type. Even if it's True, the type may still not be
+ -- promotable.
dd_kindSig:: Maybe (LHsKind name),
-- ^ Optional kind signature.
--
@@ -769,6 +790,28 @@ data ConDecl name
-- need to report decprecated use
} deriving (Data, Typeable)
+type LTyConDecl name = Located (TyConDecl name)
+
+type HsTyConDeclDetails name = HsConDetails (LHsKind name) ()
+
+-- | The type constructor for the right hand side of a @data kind@ declaration.
+data TyConDecl name
+ = TyConDecl
+ { tycon_name :: Located name -- ^ name of type constructor
+ , tycon_details :: HsTyConDeclDetails name -- ^ argument kinds
+ , tycon_doc :: Maybe LHsDocString -- ^ optional documentation
+ } deriving (Data, Typeable)
+
+instance OutputableBndr name => Outputable (TyConDecl name) where
+ ppr TyConDecl { tycon_name = name, tycon_details = details
+ , tycon_doc = doc }
+ = sep [ppr_mbDoc doc, ppr_details]
+ where
+ ppr_details = case details of
+ InfixCon l r -> hsep [ppr l, pprInfixOcc (unLoc name), ppr r]
+ PrefixCon args -> hsep (pprPrefixOcc (unLoc name) : map (pprParendHsType . unLoc) args)
+ RecCon _ -> panic "Outputtable (TyConDecl name)" "unexpected record constructor"
+
type HsConDeclDetails name = HsConDetails (LBangType name) [ConDeclField name]
hsConDeclArgTys :: HsConDeclDetails name -> [LBangType name]
@@ -790,20 +833,35 @@ instance Outputable ty => Outputable (ResType ty) where
\begin{code}
+
+pp_kind_decl :: OutputableBndr name
+ => Located name -> [Located name] -> [LTyConDecl name] -> SDoc
+pp_kind_decl kname kvars cons
+ = ptext (sLit "data kind") <+> ppr (unLoc kname)
+ <+> hsep (map (ppr . unLoc) kvars) <+> rhs
+
+ where
+ rhs | null cons = empty
+ | otherwise = equals <+> sep (punctuate (ptext (sLit " |")) (map ppr cons))
+
pp_data_defn :: OutputableBndr name
=> (HsContext name -> SDoc) -- Printing the header
-> HsDataDefn name
-> SDoc
pp_data_defn pp_hdr (HsDataDefn { dd_ND = new_or_data, dd_ctxt = L _ context
+ , dd_try_promote = try_promote
, dd_kindSig = mb_sig
, dd_cons = condecls, dd_derivs = derivings })
| null condecls
- = ppr new_or_data <+> pp_hdr context <+> pp_sig
+ = ppr new_or_data <+> pp_prom <+> pp_hdr context <+> pp_sig
| otherwise
- = hang (ppr new_or_data <+> pp_hdr context <+> pp_sig)
+ = hang (ppr new_or_data <+> pp_prom <+> pp_hdr context <+> pp_sig)
2 (pp_condecls condecls $$ pp_derivings)
where
+ pp_prom | try_promote = empty
+ | otherwise = ptext (sLit "type")
+
pp_sig = case mb_sig of
Nothing -> empty
Just kind -> dcolon <+> ppr kind
diff --git a/compiler/hsSyn/HsUtils.lhs b/compiler/hsSyn/HsUtils.lhs
index 267b2cac0e..accae0dd06 100644
--- a/compiler/hsSyn/HsUtils.lhs
+++ b/compiler/hsSyn/HsUtils.lhs
@@ -655,6 +655,9 @@ hsTyClDeclBinders (ClassDecl { tcdLName = cls_name, tcdSigs = sigs
hsTyClDeclBinders (DataDecl { tcdLName = name, tcdDataDefn = defn })
= name : hsDataDefnBinders defn
+hsTyClDeclBinders (KindDecl { tcdLName = name, tcdTypeCons = cons })
+ = name : map (tycon_name . unLoc) cons
+
-------------------
hsInstDeclBinders :: Eq name => InstDecl name -> [Located name]
hsInstDeclBinders (ClsInstD { cid_inst = ClsInstDecl { cid_datafam_insts = dfis } })
diff --git a/compiler/iface/IfaceSyn.lhs b/compiler/iface/IfaceSyn.lhs
index f6e68e2836..b12906b3b4 100644
--- a/compiler/iface/IfaceSyn.lhs
+++ b/compiler/iface/IfaceSyn.lhs
@@ -16,6 +16,7 @@ module IfaceSyn (
IfaceDecl(..), IfaceSynTyConRhs(..), IfaceClassOp(..), IfaceAT(..),
IfaceConDecl(..), IfaceConDecls(..),
+ IfaceTyConDecl(..),
IfaceExpr(..), IfaceAlt, IfaceLetBndr(..),
IfaceBinding(..), IfaceConAlt(..),
IfaceIdInfo(..), IfaceIdDetails(..), IfaceUnfolding(..),
@@ -36,6 +37,7 @@ module IfaceSyn (
#include "HsVersions.h"
+import TyCon( PromotionInfo(..) )
import IfaceType
import PprCore() -- Printing DFunArgs
import Demand
@@ -76,6 +78,12 @@ data IfaceDecl
ifIdDetails :: IfaceIdDetails,
ifIdInfo :: IfaceIdInfo }
+ | IfaceDataKind { ifName :: OccName, -- Kind constructor
+ ifRec :: RecFlag, -- Recursive or not?
+ ifKVars :: [IfaceTvBndr], -- Kind parameters
+ ifTyCons :: [IfaceTyConDecl] -- Type constructors of this kind
+ }
+
| IfaceData { ifName :: OccName, -- Type constructor
ifCType :: Maybe CType, -- C type for CAPI FFI
ifTyVars :: [IfaceTvBndr], -- Type variables
@@ -83,7 +91,7 @@ data IfaceDecl
ifCtxt :: IfaceContext, -- The "stupid theta"
ifCons :: IfaceConDecls, -- Includes new/data/data family info
ifRec :: RecFlag, -- Recursive or not?
- ifPromotable :: Bool, -- Promotable to kind level?
+ ifPromotable :: PromotionInfo (),-- Promotable to kind level?
ifGadtSyntax :: Bool, -- True <=> declared using
-- GADT syntax
ifAxiom :: Maybe IfExtName -- The axiom, for a newtype,
@@ -173,6 +181,14 @@ instance Binary IfaceDecl where
put_ bh a3
put_ bh a4
+ put_ bh (IfaceDataKind a1 a2 a3 a4) = do
+ putByte bh 6
+ put_ bh (occNameFS a1)
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+
+
get bh = do
h <- getByte bh
case h of
@@ -212,12 +228,32 @@ instance Binary IfaceDecl where
a8 <- get bh
occ <- return $! mkOccNameFS clsName a2
return (IfaceClass a1 occ a3 a4 a5 a6 a7 a8)
- _ -> do a1 <- get bh
+ 5 -> do a1 <- get bh
a2 <- get bh
a3 <- get bh
a4 <- get bh
occ <- return $! mkOccNameFS tcName a1
return (IfaceAxiom occ a2 a3 a4)
+ 6 -> do a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ occ <- return $! mkOccNameFS tcName a1
+ return (IfaceDataKind occ a2 a3 a4)
+ _ -> error ("Binary.get(TyClDecl): Unknown tag " ++ show h)
+
+instance Binary (PromotionInfo ()) where
+ put_ bh p = case p of
+ NeverPromote -> putByte bh 0x0
+ NotPromotable -> putByte bh 0x1
+ Promotable () -> putByte bh 0x2
+ get bh = do
+ tag <- getByte bh
+ case tag of
+ 0x0 -> return NeverPromote
+ 0x1 -> return NotPromotable
+ 0x2 -> return (Promotable ())
+ _ -> error ("Binary.get(Promotable ()): Unknown tag " ++ show tag)
data IfaceSynTyConRhs
= IfaceOpenSynFamilyTyCon
@@ -398,6 +434,22 @@ instance Binary IfaceBang where
2 -> do return IfUnpack
_ -> do { a <- get bh; return (IfUnpackCo a) }
+data IfaceTyConDecl
+ = IfTyCon {
+ ifTyConOcc :: OccName, -- constructor name
+ ifTyConArgKs :: [IfaceKind] -- constructor argument kinds
+ }
+
+instance Binary IfaceTyConDecl where
+ put_ bh (IfTyCon a1 a2) = do
+ put_ bh (occNameFS a1)
+ put_ bh a2
+ get bh = do
+ a1 <- get bh
+ a2 <- get bh
+ occ <- return $! mkOccNameFS tcName a1
+ return (IfTyCon occ a2)
+
data IfaceClsInst
= IfaceClsInst { ifInstCls :: IfExtName, -- See comments with
ifInstTys :: [Maybe IfaceTyCon], -- the defn of ClsInst
@@ -951,6 +1003,9 @@ ifaceDeclImplicitBndrs (IfaceData {ifName = _tc_occ,
has_wrapper = ifConWrapper con_decl -- This is the reason for
-- having the ifConWrapper field!
+ifaceDeclImplicitBndrs IfaceDataKind { ifTyCons = cons }
+ = map ifTyConOcc cons
+
ifaceDeclImplicitBndrs (IfaceClass {ifCtxt = sc_ctxt, ifName = cls_tc_occ,
ifSigs = sigs, ifATs = ats })
= -- (possibly) newtype coercion
@@ -1020,6 +1075,15 @@ pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, ifRoles = roles,
= hang (ptext (sLit "type family") <+> pprIfaceDeclHead [] tycon tyvars roles)
4 (dcolon <+> ppr kind)
+pprIfaceDecl IfaceDataKind {ifName = kcon, ifKVars = kvars,
+ ifTyCons = tycons }
+ -- XXX what should the roles argument be here?
+ = hang (ptext (sLit "data kind") <+> pprIfaceDeclHead [] kcon kvars []) 4 $
+ if null tycons
+ then empty
+ else equals <+> sep (punctuate (ptext (sLit " |")) (map pprIfaceTyConDecl tycons))
+
+
-- this case handles both abstract and instantiated closed family tycons
pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, ifRoles = roles,
ifSynRhs = _closedSynFamilyTyCon, ifSynKind = kind })
@@ -1037,8 +1101,11 @@ pprIfaceDecl (IfaceData {ifName = tycon, ifCType = cType,
, pp_condecls tycon condecls
, pprAxiom mbAxiom])
where
- pp_prom | is_prom = ptext (sLit "Promotable")
- | otherwise = ptext (sLit "Not promotable")
+ pp_prom = case is_prom of
+ NeverPromote -> ptext (sLit "Never promotable")
+ NotPromotable -> ptext (sLit "Not promotable")
+ Promotable () -> ptext (sLit "Promotable")
+
pp_nd = case condecls of
IfAbstractTyCon dis -> ptext (sLit "abstract") <> parens (ppr dis)
IfDataFamTyCon -> ptext (sLit "data family")
@@ -1086,6 +1153,10 @@ pp_condecls tc (IfNewTyCon c) = equals <+> pprIfaceConDecl tc c
pp_condecls tc (IfDataTyCon cs) = equals <+> sep (punctuate (ptext (sLit " |"))
(map (pprIfaceConDecl tc) cs))
+pprIfaceTyConDecl :: IfaceTyConDecl -> SDoc
+pprIfaceTyConDecl IfTyCon { ifTyConOcc = name, ifTyConArgKs = kinds }
+ = hsep (parenSymOcc name (ppr name) : map pprParendIfaceType kinds)
+
mkIfaceEqPred :: IfaceType -> IfaceType -> IfacePredType
-- IA0_NOTE: This is wrong, but only used for pretty-printing.
mkIfaceEqPred ty1 ty2 = IfaceTyConApp (IfaceTc eqTyConName) [ty1, ty2]
@@ -1306,6 +1377,9 @@ freeNamesIfDecl d@IfaceData{} =
maybe emptyNameSet unitNameSet (ifAxiom d) &&&
freeNamesIfContext (ifCtxt d) &&&
freeNamesIfConDecls (ifCons d)
+freeNamesIfDecl d@IfaceDataKind{} =
+ freeNamesIfTvBndrs (ifKVars d) &&&
+ fnList freeNamesIfTyConDecl (ifTyCons d)
freeNamesIfDecl d@IfaceSyn{} =
freeNamesIfTvBndrs (ifTyVars d) &&&
freeNamesIfSynRhs (ifSynRhs d) &&&
@@ -1355,6 +1429,10 @@ freeNamesIfConDecls (IfDataTyCon c) = fnList freeNamesIfConDecl c
freeNamesIfConDecls (IfNewTyCon c) = freeNamesIfConDecl c
freeNamesIfConDecls _ = emptyNameSet
+freeNamesIfTyConDecl :: IfaceTyConDecl -> NameSet
+freeNamesIfTyConDecl c =
+ fnList freeNamesIfKind (ifTyConArgKs c)
+
freeNamesIfConDecl :: IfaceConDecl -> NameSet
freeNamesIfConDecl c =
freeNamesIfTvBndrs (ifConUnivTvs c) &&&
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index 44f99d520e..6764c916eb 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -1499,6 +1499,12 @@ tyConToIfaceDecl env tycon
ifSynRhs = to_ifsyn_rhs syn_rhs,
ifSynKind = tidyToIfaceType env1 (synTyConResKind tycon) }
+ | DataKindTyCon cons <- algTyConRhs tycon
+ = IfaceDataKind { ifName = getOccName tycon
+ , ifRec = boolToRecFlag (isRecursiveTyCon tycon)
+ , ifKVars = toIfaceTvBndrs tyvars
+ , ifTyCons = map ifaceTyConDecl cons }
+
| isAlgTyCon tycon
= IfaceData { ifName = getOccName tycon,
ifCType = tyConCType tycon,
@@ -1508,7 +1514,7 @@ tyConToIfaceDecl env tycon
ifCons = ifaceConDecls (algTyConRhs tycon),
ifRec = boolToRecFlag (isRecursiveTyCon tycon),
ifGadtSyntax = isGadtSyntaxTyCon tycon,
- ifPromotable = isJust (promotableTyCon_maybe tycon),
+ ifPromotable = fmap (\_ -> ()) (promotableTyConInfo tycon),
ifAxiom = fmap coAxiomName (tyConFamilyCoercion_maybe tycon) }
| isForeignTyCon tycon
@@ -1534,6 +1540,7 @@ tyConToIfaceDecl env tycon
-- Furthermore, tyThingToIfaceDecl is also used
-- in TcRnDriver for GHCi, when browsing a module, in which case the
-- AbstractTyCon case is perfectly sensible.
+ ifaceConDecls DataKindTyCon{} = pprPanic "ifaceConDecls" (ptext (sLit "unexpected 'data kind' rhs"))
ifaceConDecl data_con
= IfCon { ifConOcc = getOccName (dataConName data_con),
@@ -1557,6 +1564,12 @@ tyConToIfaceDecl env tycon
to_eq_spec spec = [ (getOccName (tidyTyVar env2 tv), tidyToIfaceType env2 ty)
| (tv,ty) <- spec]
+ ifaceTyConDecl ty_con
+ = IfTyCon { ifTyConOcc = getOccName (tyConName ty_con),
+ ifTyConArgKs = map (tidyToIfaceType emptyTidyEnv) args }
+ where
+ (args,_) = splitFunTys (tyConKind ty_con)
+
toIfaceBang :: TidyEnv -> HsBang -> IfaceBang
toIfaceBang _ HsNoBang = IfNoBang
toIfaceBang _ (HsUnpack Nothing) = IfUnpack
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index 2d2e867390..d6b6a55abe 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -434,6 +434,30 @@ tc_iface_decl _ ignore_prags (IfaceId {ifName = occ_name, ifType = iface_type,
; info <- tcIdInfo ignore_prags name ty info
; return (AnId (mkGlobalId details name ty info)) }
+tc_iface_decl _ _ IfaceDataKind {ifName = occ_name,
+ ifRec = is_rec,
+ ifKVars = kvs,
+ ifTyCons = cons}
+ = bindIfaceTyVars_AT kvs $ \ kvs' ->
+ do kc_name <- lookupIfaceTop occ_name
+ kcon <- fixM $ \ kcon ->
+ do let kind = mkTyConApp kcon (mkTyVarTys kvs')
+ cons <- mapM (tcIfaceTyConDecl kind kcon) cons
+ let sKind = mkFunTys (map Var.tyVarKind kvs') superKind
+ return $ mkAlgTyCon
+ kc_name
+ sKind
+ kvs'
+ []
+ Nothing
+ []
+ (DataKindTyCon cons)
+ NoParentTyCon
+ is_rec
+ False
+ NotPromotable
+ return (ATyCon kcon)
+
tc_iface_decl parent _ (IfaceData {ifName = occ_name,
ifCType = cType,
ifTyVars = tv_bndrs,
@@ -643,6 +667,16 @@ tcIfaceDataCons tycon_name tycon _ if_cons
tc_strict (IfUnpackCo if_co) = do { co <- tcIfaceCo if_co
; return (HsUnpack (Just co)) }
+tcIfaceTyConDecl :: Kind -> KCon -> IfaceTyConDecl -> IfL TyCon
+tcIfaceTyConDecl kind kcon IfTyCon { ifTyConOcc = occ_name, ifTyConArgKs = args }
+ = do name <- lookupIfaceTop occ_name
+ -- See the comment in tc_con_decl of tcIfaceDataCons for why forkM
+ kinds <- forkM pp_name (mapM tcIfaceKind args)
+ return (mkDataKindTyCon kcon name (mkFunTys kinds kind))
+ where
+ pp_name = ptext (sLit "Type constructor") <+> ppr occ_name
+
+
tcIfaceEqSpec :: [(OccName, IfaceType)] -> IfL [(TyVar, Type)]
tcIfaceEqSpec spec
= mapM do_item spec
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index 33dbba2c21..0808d7229e 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -1376,9 +1376,12 @@ implicitTyConThings tc
-- for each data constructor in order,
-- the contructor, worker, and (possibly) wrapper
- concatMap (extras_plus . ADataCon) (tyConDataCons tc)
+ concatMap (extras_plus . ADataCon) (tyConDataCons tc) ++
-- NB. record selectors are *not* implicit, they have fully-fledged
-- bindings that pass through the compilation pipeline as normal.
+
+ -- type constructors, if this is a 'data kind' declaration.
+ map ATyCon (kConTypeCons tc)
where
class_stuff = case tyConClass_maybe tc of
Nothing -> []
@@ -1414,9 +1417,13 @@ isImplicitTyThing (ACoAxiom ax) = isImplicitCoAxiom ax
-- might have a parent.
tyThingParent_maybe :: TyThing -> Maybe TyThing
tyThingParent_maybe (ADataCon dc) = Just (ATyCon (dataConTyCon dc))
-tyThingParent_maybe (ATyCon tc) = case tyConAssoc_maybe tc of
- Just cls -> Just (ATyCon (classTyCon cls))
- Nothing -> Nothing
+tyThingParent_maybe (ATyCon tc)
+ | Just cls <- tyConAssoc_maybe tc
+ = Just (ATyCon (classTyCon cls))
+ | Just s <- tyConDataKind_maybe tc
+ = Just (ATyCon s)
+ | otherwise
+ = Nothing
tyThingParent_maybe (AnId id) = case idDetails id of
RecSelId { sel_tycon = tc } -> Just (ATyCon tc)
ClassOpId cls -> Just (ATyCon (classTyCon cls))
diff --git a/compiler/main/PprTyThing.hs b/compiler/main/PprTyThing.hs
index b95c69902a..dddfe10de1 100644
--- a/compiler/main/PprTyThing.hs
+++ b/compiler/main/PprTyThing.hs
@@ -40,6 +40,7 @@ import VarEnv( emptyTidyEnv )
import StaticFlags( opt_PprStyle_Debug )
import Outputable
import FastString
+import Data.Maybe (isJust)
-- -----------------------------------------------------------------------------
-- Pretty-printing entities that we get from the GHC API
@@ -116,7 +117,7 @@ pprTyConHdr pefas tyCon
| Just cls <- tyConClass_maybe tyCon
= pprClassHdr pefas cls
| otherwise
- = ptext keyword <+> opt_family <+> opt_stupid <+> ppr_bndr tyCon <+> pprTvBndrs vars
+ = ptext keyword <+> opt_modifier <+> opt_stupid <+> ppr_bndr tyCon <+> pprTvBndrs vars
where
vars | GHC.isPrimTyCon tyCon ||
GHC.isFunTyCon tyCon = take (GHC.tyConArity tyCon) GHC.alphaTyVars
@@ -126,8 +127,10 @@ pprTyConHdr pefas tyCon
| GHC.isNewTyCon tyCon = sLit "newtype"
| otherwise = sLit "data"
- opt_family
+ opt_modifier
| GHC.isFamilyTyCon tyCon = ptext (sLit "family")
+ | isJust (kConTypeCons_maybe tyCon) = ptext (sLit "kind")
+ | NeverPromote <- promotableTyConInfo tyCon = ptext (sLit "type")
| otherwise = empty
opt_stupid -- The "stupid theta" part of the declaration
@@ -187,14 +190,33 @@ pprTyCon pefas ss tyCon
-- e.g. type T = forall a. a->a
| Just cls <- GHC.tyConClass_maybe tyCon
= pprClass pefas ss cls
+ | Just s <- tyConDataKind_maybe tyCon
+ = pprTyCon pefas ss s
+ | Just tys <- kConTypeCons_maybe tyCon
+ = pprDataKind pefas ss tyCon tys
| otherwise
= pprAlgTyCon pefas ss tyCon
-
where
closed_family_header
= pprTyConHdr pefas tyCon <+> dcolon <+>
pprTypeForUser pefas (GHC.synTyConResKind tyCon) <+> ptext (sLit "where")
+pprDataKind :: PrintExplicitForalls -> ShowSub -> TyCon -> [TyCon] -> SDoc
+pprDataKind pefas ss kcon tys =
+ hang (pprTyConHdr pefas kcon)
+ 2 (add_bars (ppr_trim (map show_con tys)))
+ where
+ ok_con tyc = showSub ss tyc
+ show_con tyc
+ | ok_con tyc = Just (pprTyConDecl tyc)
+ | otherwise = Nothing
+
+pprTyConDecl :: TyCon -> SDoc
+pprTyConDecl tyc = ppr_bndr tyc <+> sep (map GHC.pprParendType fs)
+ where
+ (_vars, kind) = GHC.splitForAllTys (tyConKind tyc)
+ (fs, _res) = tcSplitFunTys kind
+
pprAlgTyCon :: PrintExplicitForalls -> ShowSub -> TyCon -> SDoc
pprAlgTyCon pefas ss tyCon
| gadt = pprTyConHdr pefas tyCon <+> ptext (sLit "where") $$
diff --git a/compiler/parser/HaddockUtils.hs b/compiler/parser/HaddockUtils.hs
index bf22cd77c1..0beaf6c7ef 100644
--- a/compiler/parser/HaddockUtils.hs
+++ b/compiler/parser/HaddockUtils.hs
@@ -28,3 +28,16 @@ addConDocs (x:xs) doc = x : addConDocs xs doc
addConDocFirst :: [LConDecl a] -> Maybe LHsDocString -> [LConDecl a]
addConDocFirst [] _ = []
addConDocFirst (x:xs) doc = addConDoc x doc : xs
+
+addTyConDoc :: LTyConDecl a -> Maybe LHsDocString -> LTyConDecl a
+addTyConDoc decl Nothing = decl
+addTyConDoc (L p c) doc = L p ( c { tycon_doc = tycon_doc c `mplus` doc } )
+
+addTyConDocs :: [LTyConDecl a] -> Maybe LHsDocString -> [LTyConDecl a]
+addTyConDocs [] _ = []
+addTyConDocs [x] doc = [addTyConDoc x doc]
+addTyConDocs (x:xs) doc = x : addTyConDocs xs doc
+
+addTyConDocFirst :: [LTyConDecl a] -> Maybe LHsDocString -> [LTyConDecl a]
+addTyConDocFirst [] _ = []
+addTyConDocFirst (x:xs) doc = addTyConDoc x doc : xs
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x
index 12389e7f17..f7288b3f50 100644
--- a/compiler/parser/Lexer.x
+++ b/compiler/parser/Lexer.x
@@ -56,7 +56,7 @@ module Lexer (
getLexState, popLexState, pushLexState,
extension, bangPatEnabled, datatypeContextsEnabled,
traditionalRecordSyntaxEnabled,
- typeLiteralsEnabled,
+ dataKindsEnabled,
explicitForallEnabled,
inRulePrag,
explicitNamespacesEnabled, sccProfilingOn, hpcEnabled,
@@ -478,6 +478,7 @@ data Token
| ITgroup
| ITby
| ITusing
+ | ITkind
| ITnominal
| ITrepresentational
| ITphantom
@@ -656,6 +657,7 @@ reservedWordsFM = listToUFM $
( "group", ITgroup, bit transformComprehensionsBit),
( "by", ITby, bit transformComprehensionsBit),
( "using", ITusing, bit transformComprehensionsBit),
+ ( "kind", ITkind, bit dataKindsBit),
( "foreign", ITforeign, bit ffiBit),
( "export", ITexport, bit ffiBit),
@@ -1894,8 +1896,8 @@ safeHaskellBit :: Int
safeHaskellBit = 26
traditionalRecordSyntaxBit :: Int
traditionalRecordSyntaxBit = 27
-typeLiteralsBit :: Int
-typeLiteralsBit = 28
+dataKindsBit :: Int
+dataKindsBit = 28
explicitNamespacesBit :: Int
explicitNamespacesBit = 29
lambdaCaseBit :: Int
@@ -1950,8 +1952,8 @@ sccProfilingOn :: Int -> Bool
sccProfilingOn flags = testBit flags sccProfilingOnBit
traditionalRecordSyntaxEnabled :: Int -> Bool
traditionalRecordSyntaxEnabled flags = testBit flags traditionalRecordSyntaxBit
-typeLiteralsEnabled :: Int -> Bool
-typeLiteralsEnabled flags = testBit flags typeLiteralsBit
+dataKindsEnabled :: Int -> Bool
+dataKindsEnabled flags = testBit flags dataKindsBit
explicitNamespacesEnabled :: Int -> Bool
explicitNamespacesEnabled flags = testBit flags explicitNamespacesBit
@@ -2019,7 +2021,7 @@ mkPState flags buf loc =
.|. nondecreasingIndentationBit `setBitIf` xopt Opt_NondecreasingIndentation flags
.|. safeHaskellBit `setBitIf` safeImportsOn flags
.|. traditionalRecordSyntaxBit `setBitIf` xopt Opt_TraditionalRecordSyntax flags
- .|. typeLiteralsBit `setBitIf` xopt Opt_DataKinds flags
+ .|. dataKindsBit `setBitIf` xopt Opt_DataKinds flags
.|. explicitNamespacesBit `setBitIf` xopt Opt_ExplicitNamespaces flags
.|. lambdaCaseBit `setBitIf` xopt Opt_LambdaCase flags
.|. negativeLiteralsBit `setBitIf` xopt Opt_NegativeLiterals flags
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp
index b18d0d35c6..1ad7036e6b 100644
--- a/compiler/parser/Parser.y.pp
+++ b/compiler/parser/Parser.y.pp
@@ -257,6 +257,7 @@ incorrect.
'group' { L _ ITgroup } -- for list transform extension
'by' { L _ ITby } -- for list transform extension
'using' { L _ ITusing } -- for list transform extension
+ 'kind' { L _ ITkind }
'N' { L _ ITnominal } -- Nominal role
'R' { L _ ITrepresentational } -- Representational role
'P' { L _ ITphantom } -- Phantom role
@@ -637,20 +638,26 @@ ty_decl :: { LTyClDecl RdrName }
{% do { L loc decl <- mkFamDecl (comb4 $1 $3 $4 $5) (unLoc $5) $3 (unLoc $4)
; return (L loc (FamDecl decl)) } }
+ | 'data' 'kind' type kconstrs
+ {% mkTyDataKind (comb3 $1 $3 $4) $3 (unLoc $4) }
+
+ | 'data' 'kind' type
+ {% mkTyDataKind (comb2 $1 $3) $3 [] }
+
-- ordinary data type or newtype declaration
- | data_or_newtype capi_ctype tycl_hdr constrs deriving
- {% mkTyData (comb4 $1 $3 $4 $5) (unLoc $1) $2 $3
- Nothing (reverse (unLoc $4)) (unLoc $5) }
+ | data_or_newtype promotable capi_ctype tycl_hdr constrs deriving
+ {% mkTyData (comb4 $1 $4 $5 $6) (unLoc $1) $2 $3 $4
+ Nothing (reverse (unLoc $5)) (unLoc $6) }
-- We need the location on tycl_hdr in case
-- constrs and deriving are both empty
-- ordinary GADT declaration
- | data_or_newtype capi_ctype tycl_hdr opt_kind_sig
+ | data_or_newtype promotable capi_ctype tycl_hdr opt_kind_sig
gadt_constrlist
deriving
- {% mkTyData (comb4 $1 $3 $5 $6) (unLoc $1) $2 $3
- (unLoc $4) (unLoc $5) (unLoc $6) }
- -- We need the location on tycl_hdr in case
+ {% mkTyData (comb4 $1 $4 $6 $7) (unLoc $1) $2 $3 $4
+ (unLoc $5) (unLoc $6) (unLoc $7) }
+ -- We need the location on tycl_hdr in case
-- constrs and deriving are both empty
-- data/newtype family
@@ -658,6 +665,10 @@ ty_decl :: { LTyClDecl RdrName }
{% do { L loc decl <- mkFamDecl (comb3 $1 $2 $4) DataFamily $3 (unLoc $4)
; return (L loc (FamDecl decl)) } }
+promotable :: { Bool }
+ : 'type' { False } -- not promotable
+ | { True } -- promotable
+
inst_decl :: { LInstDecl RdrName }
: 'instance' inst_type where_inst
{ let (binds, sigs, _, ats, adts, _) = cvBindsAndSigs (unLoc $3) in
@@ -1289,10 +1300,10 @@ constr_stuff :: { Located (Located RdrName, HsConDeclDetails RdrName) }
-- C t1 t2
-- as a btype (treating C as a type constructor) and then convert C to be
-- a data constructor. Reason: it might continue like this:
--- C t1 t2 %: D Int
+-- C t1 t2 :% D Int
-- in which case C really would be a type constructor. We can't resolve this
-- ambiguity till we come across the constructor oprerator :% (or not, more usually)
- : btype {% splitCon $1 >>= return.LL }
+ : btype {% splitCon True $1 >>= return.LL }
| btype conop btype { LL ($2, InfixCon $1 $3) }
fielddecls :: { [ConDeclField RdrName] }
@@ -1322,6 +1333,34 @@ deriving :: { Located (Maybe [LHsType RdrName]) }
-- Glasgow extension: allow partial
-- applications in derivings
+kconstrs :: { Located [LTyConDecl RdrName] }
+ : maybe_docnext '=' kconstrs1
+ { L (comb2 $2 $3) (addTyConDocs (reverse (unLoc $3)) $1) }
+
+kconstrs1 :: { Located [LTyConDecl RdrName] }
+ : kconstrs1 maybe_docnext '|' maybe_docprev kconstr
+ { LL (addTyConDoc $5 $2 : addTyConDocFirst (unLoc $1) $4) }
+ | kconstr
+ { L1 [$1] }
+
+kconstr :: { LTyConDecl RdrName }
+ : maybe_docnext kconstr_stuff maybe_docprev
+ { let (con,details) = unLoc $2 in
+ addTyConDoc (L (getLoc $2) (mkTyConDecl con details)) ($1 `mplus` $3)
+ }
+
+kconstr_stuff :: { Located (Located RdrName, HsTyConDeclDetails RdrName) }
+ -- we reuse splitCon here because types and kinds are represented in
+ -- the same way, except that we don't change the constructor
+ -- namespace.
+ : bkind {% splitCon False $1 >>= \ (con,details) ->
+ toTyConDetails (getLoc $1) details >>= \ kdetails ->
+ return (LL (con,kdetails))
+ }
+ | bkind conop bkind { LL ($2, InfixCon $1 $3) }
+
+
+
-----------------------------------------------------------------------------
-- Value definitions
@@ -2012,6 +2051,7 @@ varid :: { Located RdrName }
| 'interruptible' { L1 $! mkUnqual varName (fsLit "interruptible") }
| 'forall' { L1 $! mkUnqual varName (fsLit "forall") }
| 'family' { L1 $! mkUnqual varName (fsLit "family") }
+ | 'kind' { L1 $! mkUnqual varName (fsLit "kind") }
qvarsym :: { Located RdrName }
: varsym { $1 }
diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs
index fb5f43f5e9..2310ca4815 100644
--- a/compiler/parser/RdrHsSyn.lhs
+++ b/compiler/parser/RdrHsSyn.lhs
@@ -10,10 +10,11 @@ module RdrHsSyn (
mkHsDo, mkHsSplice, mkTopSpliceDecl,
mkClassDecl,
mkTyData, mkFamInstData,
+ mkTyDataKind,
mkTySynonym, mkTyFamInstEqn,
mkTyFamInst,
mkFamDecl,
- splitCon, mkInlinePragma,
+ splitCon, mkInlinePragma, toTyConDetails,
mkRecConstrOrUpdate, -- HsExp -> [HsFieldUpdate] -> P HsExp
mkTyLit,
@@ -29,6 +30,7 @@ module RdrHsSyn (
mkExtName, -- RdrName -> CLabelString
mkGadtDecl, -- [Located RdrName] -> LHsType RdrName -> ConDecl RdrName
mkSimpleConDecl,
+ mkTyConDecl,
mkDeprecatedGadtRecordDecl,
-- Bunch of functions in the parser monad for
@@ -123,20 +125,60 @@ mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls
mkTyData :: SrcSpan
-> NewOrData
+ -> Bool
-> Maybe CType
-> Located (Maybe (LHsContext RdrName), LHsType RdrName)
-> Maybe (LHsKind RdrName)
-> [LConDecl RdrName]
-> Maybe [LHsType RdrName]
-> P (LTyClDecl RdrName)
-mkTyData loc new_or_data cType (L _ (mcxt, tycl_hdr)) ksig data_cons maybe_deriv
+mkTyData loc new_or_data promotable cType (L _ (mcxt, tycl_hdr)) ksig data_cons maybe_deriv
= do { (tc, tparams) <- checkTyClHdr tycl_hdr
; tyvars <- checkTyVars tycl_hdr tparams
- ; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv
+
+ -- promotion has been explicitly disabled, make sure that -XDataKinds
+ -- is present
+ ; when (not promotable) $ do
+ pstate <- getPState
+ let enabled = xopt Opt_DataKinds (dflags pstate)
+ unless enabled (parseErrorSDoc loc (text "Illegal `data type` declaration (use -XDataKinds to enable)"))
+ ; defn <- mkDataDefn new_or_data promotable cType mcxt ksig data_cons maybe_deriv
; return (L loc (DataDecl { tcdLName = tc, tcdTyVars = tyvars,
tcdDataDefn = defn,
tcdFVs = placeHolderNames })) }
+mkTyDataKind :: SrcSpan
+ -> LHsType RdrName
+ -> [LTyConDecl RdrName]
+ -> P (LTyClDecl RdrName)
+mkTyDataKind loc k_hdr ty_cons
+ = do { (kc, kparamTys) <- checkTyClHdr k_hdr
+ ; unless (null kparamTys) $ do
+ pstate <- getPState
+ let enabled = xopt Opt_PolyKinds (dflags pstate)
+ unless enabled (parseErrorSDoc loc (text "Illegal polymorphic `data kind` declaration (use -XPolyKinds to enable)"))
+ ; kparams <- checkTyVars k_hdr kparamTys
+ ; kvars <- checkKVars kparams
+ ; return $ L loc $ KindDecl
+ { tcdLName = kc
+ , tcdKVars = kvars
+ , tcdTypeCons = ty_cons
+ , tcdFvs = placeHolderNames
+ }
+ }
+
+ where
+
+ -- check that there are no sort signatures
+ checkKVars tparams
+ | not (null (hsq_kvs tparams)) = panic "mkTyDataKind" "unexpected sort variables"
+ | otherwise = mapM checkKVar (hsq_tvs tparams)
+
+ checkKVar bndr = case unLoc bndr of
+ HsTyVarBndr n Nothing _ -> return (L (getLoc bndr) n)
+ HsTyVarBndr _ (Just _) _ -> parseErrorSDoc (getLoc bndr) (text "kind parameters may not have sort signatures")
+
+
mkFamInstData :: SrcSpan
-> NewOrData
-> Maybe CType
@@ -147,21 +189,25 @@ mkFamInstData :: SrcSpan
-> P (LDataFamInstDecl RdrName)
mkFamInstData loc new_or_data cType (L _ (mcxt, tycl_hdr)) ksig data_cons maybe_deriv
= do { (tc, tparams) <- checkTyClHdr tycl_hdr
- ; defn <- mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv
+ -- promotable is always false here, as data families aren't currently
+ -- promotable
+ ; defn <- mkDataDefn new_or_data False cType mcxt ksig data_cons maybe_deriv
; return (L loc (DataFamInstDecl { dfid_tycon = tc, dfid_pats = mkHsWithBndrs tparams
, dfid_defn = defn, dfid_fvs = placeHolderNames })) }
mkDataDefn :: NewOrData
+ -> Bool
-> Maybe CType
-> Maybe (LHsContext RdrName)
-> Maybe (LHsKind RdrName)
-> [LConDecl RdrName]
-> Maybe [LHsType RdrName]
-> P (HsDataDefn RdrName)
-mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv
+mkDataDefn new_or_data promotable cType mcxt ksig data_cons maybe_deriv
= do { checkDatatypeContext mcxt
; let cxt = fromMaybe (noLoc []) mcxt
; return (HsDataDefn { dd_ND = new_or_data, dd_cType = cType
+ , dd_try_promote = promotable
, dd_ctxt = cxt
, dd_cons = data_cons
, dd_kindSig = ksig
@@ -217,7 +263,7 @@ mkTopSpliceDecl other_expr = SpliceD (SpliceDecl other_
mkTyLit :: Located (HsTyLit) -> P (LHsType RdrName)
mkTyLit l =
- do allowed <- extension typeLiteralsEnabled
+ do allowed <- extension dataKindsEnabled
if allowed
then return (HsTyLit `fmap` l)
else parseErrorSDoc (getLoc l)
@@ -345,17 +391,17 @@ has_args ((L _ (Match args _ _)) : _) = not (null args)
-- This function splits up the type application, adds any pending
-- arguments, and converts the type constructor back into a data constructor.
-splitCon :: LHsType RdrName
+splitCon :: Bool -> LHsType RdrName
-> P (Located RdrName, HsConDeclDetails RdrName)
-- This gets given a "type" that should look like
-- C Int Bool
-- or C { x::Int, y::Bool }
-- and returns the pieces
-splitCon ty
+splitCon changeNamespace ty
= split ty []
where
split (L _ (HsAppTy t u)) ts = split t (u : ts)
- split (L l (HsTyVar tc)) ts = do data_con <- tyConToDataCon l tc
+ split (L l (HsTyVar tc)) ts = do data_con <- tyConToDataCon changeNamespace l tc
return (data_con, mk_rest ts)
split (L l (HsTupleTy _ [])) [] = return (L l (getRdrName unitDataCon), PrefixCon [])
-- See Note [Unit tuples] in HsTypes
@@ -364,6 +410,12 @@ splitCon ty
mk_rest [L _ (HsRecTy flds)] = RecCon flds
mk_rest ts = PrefixCon ts
+toTyConDetails :: SrcSpan -> HsConDeclDetails RdrName -> P (HsTyConDeclDetails RdrName)
+toTyConDetails loc details = case details of
+ PrefixCon args -> return (PrefixCon args)
+ InfixCon l r -> return (InfixCon l r)
+ RecCon _ -> parseErrorSDoc loc (text "record notation is not allowd in a `data kind` declaration")
+
mkDeprecatedGadtRecordDecl :: SrcSpan
-> Located RdrName
-> [ConDeclField RdrName]
@@ -373,7 +425,7 @@ mkDeprecatedGadtRecordDecl :: SrcSpan
-- C { x,y ::Int } :: T a b
-- We give it a RecCon details right away
mkDeprecatedGadtRecordDecl loc (L con_loc con) flds res_ty
- = do { data_con <- tyConToDataCon con_loc con
+ = do { data_con <- tyConToDataCon True con_loc con
; return (L loc (ConDecl { con_old_rec = True
, con_name = data_con
, con_explicit = Implicit
@@ -397,6 +449,14 @@ mkSimpleConDecl name qvars cxt details
, con_res = ResTyH98
, con_doc = Nothing }
+mkTyConDecl :: Located RdrName -> HsTyConDeclDetails RdrName
+ -> TyConDecl RdrName
+mkTyConDecl name details
+ = TyConDecl { tycon_name = name
+ , tycon_details = details
+ , tycon_doc = Nothing
+ }
+
mkGadtDecl :: [Located RdrName]
-> LHsType RdrName -- Always a HsForAllTy
-> [ConDecl RdrName]
@@ -423,10 +483,10 @@ mkGadtDecl names (L _ (HsForAllTy imp qvars cxt tau))
, con_doc = Nothing }
mkGadtDecl _ other_ty = pprPanic "mkGadtDecl" (ppr other_ty)
-tyConToDataCon :: SrcSpan -> RdrName -> P (Located RdrName)
-tyConToDataCon loc tc
+tyConToDataCon :: Bool -> SrcSpan -> RdrName -> P (Located RdrName)
+tyConToDataCon changeNamespace loc tc
| isTcOcc (rdrNameOcc tc)
- = return (L loc (setRdrNameSpace tc srcDataName))
+ = return (L loc newName)
| otherwise
= parseErrorSDoc loc (msg $$ extra)
where
@@ -434,6 +494,12 @@ tyConToDataCon loc tc
extra | tc == forall_tv_RDR
= text "Perhaps you intended to use -XExistentialQuantification"
| otherwise = empty
+
+ -- for ordinary data declarations, we change the namespace of the data
+ -- constructor, but for data kind declarations, we leave them in the type
+ -- namespace
+ newName | changeNamespace = setRdrNameSpace tc srcDataName
+ | otherwise = tc
\end{code}
Note [Sorting out the result type]
diff --git a/compiler/prelude/TysWiredIn.lhs b/compiler/prelude/TysWiredIn.lhs
index b563b25cc4..5f48530145 100644
--- a/compiler/prelude/TysWiredIn.lhs
+++ b/compiler/prelude/TysWiredIn.lhs
@@ -249,7 +249,7 @@ pcTyCon is_enum is_rec is_prom name cType tyvars cons
[] -- No stupid theta
(DataTyCon cons is_enum)
is_rec
- is_prom
+ (if is_prom then Promotable () else NotPromotable)
False -- Not in GADT syntax
NoParentTyCon
@@ -365,9 +365,9 @@ mk_tuple sort arity = (tycon, tuple_con)
where
tycon = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con sort prom_tc
prom_tc = case sort of
- BoxedTuple -> Just (mkPromotedTyCon tycon (promoteKind tc_kind))
- UnboxedTuple -> Nothing
- ConstraintTuple -> Nothing
+ BoxedTuple -> Promotable (mkPromotedTyCon tycon (promoteKind tc_kind))
+ UnboxedTuple -> NotPromotable
+ ConstraintTuple -> NotPromotable
modu = mkTupleModule sort arity
tc_name = mkWiredInName modu (mkTupleOcc tcName sort arity) tc_uniq
@@ -435,7 +435,7 @@ eqTyCon = mkAlgTyCon eqTyConName
NoParentTyCon
NonRecursive
False
- Nothing -- No parent for constraint-kinded types
+ NotPromotable -- No parent for constraint-kinded types
where
kv = kKiVar
k = mkTyVarTy kv
diff --git a/compiler/rename/RnSource.lhs b/compiler/rename/RnSource.lhs
index e1236cac10..8361144f52 100644
--- a/compiler/rename/RnSource.lhs
+++ b/compiler/rename/RnSource.lhs
@@ -925,6 +925,22 @@ rnTyClDecl (DataDecl { tcdLName = tycon, tcdTyVars = tyvars, tcdDataDefn = defn
; return (DataDecl { tcdLName = tycon', tcdTyVars = tyvars'
, tcdDataDefn = defn', tcdFVs = fvs }, fvs) }
+rnTyClDecl KindDecl { tcdLName = kcon, tcdKVars = kvars, tcdTypeCons = tycons }
+ = do kcon' <- lookupLocatedTopBndrRn kcon
+ let doc = TyDataCtx kcon -- TODO is this right?
+ fixLoc o = L (getLoc o)
+
+ ((kvars', tycons'), fvs) <- bindHsTyVars doc Nothing (map unLoc kvars) (mkHsQTvs []) $ \ vars ->
+ do (tycons', fvss) <- mapAndUnzipM (rnTyConDecl doc . unLoc) tycons
+ return ((hsq_kvs vars, tycons'), plusFVs fvss)
+
+
+ return (KindDecl { tcdLName = kcon'
+ , tcdKVars = zipWith fixLoc kvars kvars'
+ , tcdTypeCons = zipWith fixLoc tycons tycons'
+ , tcdFvs = fvs }
+ , fvs)
+
rnTyClDecl (ClassDecl {tcdCtxt = context, tcdLName = lcls,
tcdTyVars = tyvars, tcdFDs = fds, tcdSigs = sigs,
tcdMeths = mbinds, tcdATs = ats, tcdATDefs = at_defs,
@@ -995,6 +1011,7 @@ rnTySyn doc rhs = rnLHsType doc rhs
rnDataDefn :: HsDocContext -> HsDataDefn RdrName -> RnM (HsDataDefn Name, FreeVars)
rnDataDefn doc (HsDataDefn { dd_ND = new_or_data, dd_cType = cType
+ , dd_try_promote = prom
, dd_ctxt = context, dd_cons = condecls
, dd_kindSig = sig, dd_derivs = derivs })
= do { checkTc (h98_style || null (unLoc context))
@@ -1018,6 +1035,7 @@ rnDataDefn doc (HsDataDefn { dd_ND = new_or_data, dd_cType = cType
; let all_fvs = fvs1 `plusFV` fvs3 `plusFV`
con_fvs `plusFV` sig_fvs
; return ( HsDataDefn { dd_ND = new_or_data, dd_cType = cType
+ , dd_try_promote = prom
, dd_ctxt = context', dd_kindSig = sig'
, dd_cons = condecls', dd_derivs = derivs' }
, all_fvs )
@@ -1103,6 +1121,10 @@ depAnalTyClDecls ds_w_fvs
, tcdDataDefn = HsDataDefn { dd_cons = cons } }
-> do L _ dc <- cons
return (unLoc (con_name dc), data_name)
+ KindDecl { tcdLName = L _ kind_name
+ , tcdTypeCons = cons }
+ -> do L _ tc <- cons
+ return (unLoc (tycon_name tc), kind_name)
_ -> []
\end{code}
@@ -1226,6 +1248,29 @@ rnConDeclDetails doc (RecCon fields)
-- since that is done by RnNames.extendGlobalRdrEnvRn
; return (RecCon new_fields, fvs) }
+
+rnTyConDecl :: HsDocContext -> TyConDecl RdrName
+ -> RnM (TyConDecl Name, FreeVars)
+rnTyConDecl doc TyConDecl { tycon_name = name, tycon_details = details
+ , tycon_doc = mb_doc }
+ = do name' <- lookupLocatedTopBndrRn name
+ (details', fvs) <- case details of
+
+ PrefixCon args -> do
+ (args', fvs) <- rnLHsKinds doc args
+ return (PrefixCon args', fvs)
+
+ InfixCon l r -> do
+ (l',lfvs) <- rnLHsKind doc l
+ (r',rfvs) <- rnLHsKind doc r
+ return (InfixCon l' r', lfvs `plusFV` rfvs)
+
+ RecCon{} -> panic "rnTyConDecl" "unexpected record constructor"
+
+ return (TyConDecl { tycon_name = name', tycon_details = details'
+ , tycon_doc = mb_doc }
+ , fvs)
+
-------------------------------------------------
deprecRecSyntax :: ConDecl RdrName -> SDoc
deprecRecSyntax decl
diff --git a/compiler/rename/RnTypes.lhs b/compiler/rename/RnTypes.lhs
index c13ea336e4..32ce4ad2b4 100644
--- a/compiler/rename/RnTypes.lhs
+++ b/compiler/rename/RnTypes.lhs
@@ -4,10 +4,17 @@
\section[RnSource]{Main pass of renamer}
\begin{code}
+{-# OPTIONS -fno-warn-tabs #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and
+-- detab the module (please do the detabbing in a separate patch). See
+-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
+-- for details
+
module RnTypes (
-- Type related stuff
rnHsType, rnLHsType, rnLHsTypes, rnContext,
- rnHsKind, rnLHsKind, rnLHsMaybeKind,
+ rnHsKind, rnLHsKind, rnLHsKinds, rnLHsMaybeKind,
rnHsSigType, rnLHsInstType, rnConDeclFields,
newTyVarNameRn,
@@ -308,6 +315,11 @@ rnTyVar is_type rdr_name
rnLHsTypes :: HsDocContext -> [LHsType RdrName]
-> RnM ([LHsType Name], FreeVars)
rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys
+
+
+rnLHsKinds :: HsDocContext -> [LHsKind RdrName]
+ -> RnM ([LHsKind Name], FreeVars)
+rnLHsKinds doc ks = mapFvRn (rnLHsKind doc) ks
\end{code}
diff --git a/compiler/typecheck/TcGenGenerics.lhs b/compiler/typecheck/TcGenGenerics.lhs
index 7e2b0147ea..150246fde8 100644
--- a/compiler/typecheck/TcGenGenerics.lhs
+++ b/compiler/typecheck/TcGenGenerics.lhs
@@ -91,7 +91,7 @@ genGenericMetaTyCons tc mod =
mkTyCon name = ASSERT( isExternalName name )
buildAlgTyCon name [] [] Nothing [] distinctAbstractTyConRhs
NonRecursive
- False -- Not promotable
+ NotPromotable
False -- Not GADT syntax
NoParentTyCon
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs
index b0e7d7a789..a8f60d2bad 100644
--- a/compiler/typecheck/TcHsType.lhs
+++ b/compiler/typecheck/TcHsType.lhs
@@ -1082,6 +1082,8 @@ kcStrategy (DataDecl { tcdDataDefn = HsDataDefn { dd_kindSig = m_ksig }})
| Just _ <- m_ksig = FullKindSignature
| otherwise = ParametricKinds
kcStrategy (ClassDecl {}) = ParametricKinds
+-- TODO: not sure if this is the right choice for 'data kind' decls
+kcStrategy (KindDecl {}) = ParametricKinds
-- if the ClosedTypeFamily has no equations, do the defaulting to *, etc.
kcStrategyFamDecl :: FamilyDecl Name -> KindCheckingStrategy
@@ -1754,6 +1756,13 @@ tc_kind_var_app name arg_kis
= do { thing <- tcLookup name
; case thing of
AGlobal (ATyCon tc)
+ | let (args,res) = splitFunTys (tyConKind tc)
+ , isSuperKind res
+ -> if length args == length arg_kis
+ then return (mkTyConApp tc arg_kis)
+ else tycon_err tc "is not fully applied"
+
+ | otherwise
-> do { data_kinds <- xoptM Opt_DataKinds
; unless data_kinds $ addErr (dataKindsErr name)
; case promotableTyCon_maybe tc of
@@ -1775,7 +1784,7 @@ tc_kind_var_app name arg_kis
-> return (mkAppTys (mkTyVarTy kind_var) arg_kis)
-- It is in scope, but not what we expected
- AThing _
+ AThing _
| isTyVarName name
-> failWithTc (ptext (sLit "Type variable") <+> quotes (ppr name)
<+> ptext (sLit "used in a kind"))
diff --git a/compiler/typecheck/TcInstDcls.lhs b/compiler/typecheck/TcInstDcls.lhs
index 9f89afe0af..b84037e7aa 100644
--- a/compiler/typecheck/TcInstDcls.lhs
+++ b/compiler/typecheck/TcInstDcls.lhs
@@ -698,8 +698,8 @@ tcDataFamInstDecl mb_clsinfo
parent = FamInstTyCon axiom fam_tc pats'
roles = map (const Nominal) tvs'
rep_tc = buildAlgTyCon rep_tc_name tvs' roles cType stupid_theta tc_rhs
- Recursive
- False -- No promotable to the kind level
+ Recursive
+ NotPromotable -- No promotable to the kind level
h98_syntax parent
-- We always assume that indexed types are recursive. Why?
-- (1) Due to their open nature, we can never be sure that a
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index f4e4dabd1b..99a3584ab2 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -118,6 +118,25 @@ tcTyAndClassDecls boot_details tyclds_s
-- remaining groups are typecheck in the extended global env
tcTyClGroup :: ModDetails -> TyClGroup Name -> TcM TcGblEnv
+tcTyClGroup boot_details decls
+ | all (isKindDecl . unLoc) decls
+ = do (kcons, _) <- fixM $ \ ~(_, conss) -> do
+ let rec_info = panic "tcTyClGroup" "rec_info"
+
+ kind_cons <- zipWithM (\ix d -> addLocM (mkKindCon rec_info (conss !! ix)) d) [0 ..] decls
+ let kind_env = [ (kind_name, panic "tcTyClGroup" "kind")
+ | L _ KindDecl { tcdLName = L _ kind_name } <- decls ]
+
+ final_conss <- tcExtendRecEnv (zipRecTyClss kind_env (map ATyCon kind_cons))
+ (mapM (addLocM (tcKindDecl rec_info)) decls)
+
+ return (kind_cons, final_conss)
+
+ let tycons = [ ATyCon x | x <- kcons ]
+ tcExtendGlobalEnv tycons (tcAddImplicits tycons)
+
+
+
-- Typecheck one strongly-connected component of type and class decls
tcTyClGroup boot_details tyclds
= do { -- Step 1: kind-check this group and returns the final
@@ -128,10 +147,16 @@ tcTyClGroup boot_details tyclds
; traceTc "tcTyAndCl generalized kinds" (ppr names_w_poly_kinds)
-- the checkNoErrs is necessary to fix #7175.
+
+ -- If any of the data declarations are explicitly not promotable,
+ -- the whole group is not promotable.
+ ; let dont_promote = or [ not (dd_try_promote dd)
+ | DataDecl { tcdDataDefn = dd } <- map unLoc tyclds ]
+
-- Step 2: type-check all groups together, returning
-- the final TyCons and Classes
; tyclss <- fixM $ \ rec_tyclss -> do
- { let rec_flags = calcRecFlags boot_details role_annots rec_tyclss
+ { let rec_flags = calcRecFlags dont_promote boot_details role_annots rec_tyclss
-- Populate environment with knot-tied ATyCon for TyCons
-- NB: if the decls mention any ill-staged data cons
@@ -402,6 +427,10 @@ getInitialKind decl@(DataDecl { tcdLName = L _ name
role_annots' = role_annots ++ replicate num_extra_tvs Nothing
; return ((main_pr : inner_prs), role_annots') }
+getInitialKind KindDecl {}
+ = failWithTc (ptext (sLit "`data kind` declarations can only be recursive")
+ <+> ptext (sLit "with other `data kind` declarations"))
+
getInitialKind (FamDecl { tcdFam = decl })
= do { pairs <- getFamDeclInitialKind decl
; return (pairs, []) }
@@ -493,6 +522,9 @@ kcTyClDecl (DataDecl { tcdLName = L _ name, tcdTyVars = hs_tvs, tcdDataDefn = de
kcTyClDecl decl@(SynDecl {}) = pprPanic "kcTyClDecl" (ppr decl)
+-- do we need to do any sort checking here?
+kcTyClDecl (KindDecl {}) = return ()
+
kcTyClDecl (ClassDecl { tcdLName = L _ name, tcdTyVars = hs_tvs
, tcdCtxt = ctxt, tcdSigs = sigs })
= kcTyClTyVars name hs_tvs $
@@ -620,6 +652,9 @@ tcTyClDecl1 _parent rec_info
tcTyClTyVars tc_name tvs $ \ tvs' kind ->
tcDataDefn rec_info tc_name tvs' kind defn
+tcTyClDecl1 _parent _rec_info KindDecl {}
+ = failWithTc (ptext (sLit "'data kind' declarations can not appear in a recursive group"))
+
tcTyClDecl1 _parent rec_info
(ClassDecl { tcdLName = L _ class_name, tcdTyVars = tvs
, tcdCtxt = ctxt, tcdMeths = meths
@@ -757,7 +792,7 @@ tcFamDecl1 parent
roles = map (const Nominal) final_tvs
tycon = buildAlgTyCon tc_name final_tvs roles Nothing []
DataFamilyTyCon Recursive
- False -- Not promotable to the kind level
+ NotPromotable
True -- GADT syntax
parent
; return [ATyCon tycon] }
@@ -776,12 +811,54 @@ tcTySynRhs rec_info tc_name tvs kind hs_ty
kind NoParentTyCon
; return [ATyCon tycon] }
+mkKindCon :: RecTyInfo -> [TyCon] -> TyClDecl Name -> TcM TyCon
+mkKindCon _rec_info tycons KindDecl { tcdLName = L _ kind_name
+ , tcdKVars = lknames } =
+ do let knames = map unLoc lknames
+ kvars <- mapM (\n -> newSigTyVar n superKind) knames
+ return $ mkAlgTyCon
+ kind_name
+ sKind
+ kvars
+ [] -- XXX roles here?
+ Nothing
+ []
+ (DataKindTyCon tycons)
+ NoParentTyCon
+ -- TODO, make the rec_info work
+ NonRecursive --(rti_is_rec rec_info kind_name)
+ False
+ NotPromotable
+ where
+ -- for now, we assume all kind variables have sort BOX.
+ sKind = mkFunTys (replicate arity superKind) superKind
+ arity = length lknames
+
+mkKindCon _ _ _ =
+ panic "mkKindCon" "non 'data kind' declaration"
+
+tcKindDecl :: RecTyInfo -> TyClDecl Name -> TcM [TyCon]
+tcKindDecl rec_info KindDecl { tcdLName = L _ kind_name, tcdKVars = lknames
+ , tcdTypeCons = cons }
+ = do traceTc "tcKindDecl" (ppr kind_name)
+
+ ~(ATyCon kcon) <- tcLookupGlobal kind_name
+ let kvars = tyConTyVars kcon
+ knames = map unLoc lknames
+ kind = mkTyConApp kcon (mkTyVarTys kvars)
+ tcExtendTyVarEnv2 (knames `zip` kvars)
+ (mapM (addLocM (tcTyConDecl kvars kind)) cons)
+
+tcKindDecl _ _
+ = panic "tcKindDecl" "unexpected non-KindDecl constructor"
+
tcDataDefn :: RecTyInfo -> Name
-> [TyVar] -> Kind
-> HsDataDefn Name -> TcM [TyThing]
-- NB: not used for newtype/data instances (whether associated or not)
tcDataDefn rec_info tc_name tvs kind
(HsDataDefn { dd_ND = new_or_data, dd_cType = cType
+ , dd_try_promote = try_promote
, dd_ctxt = ctxt, dd_kindSig = mb_ksig
, dd_cons = cons })
= do { extra_tvs <- tcDataKindSig kind
@@ -812,9 +889,13 @@ tcDataDefn rec_info tc_name tvs kind
DataType -> return (mkDataTyConRhs data_cons)
NewType -> ASSERT( not (null data_cons) )
mkNewTyConRhs tc_name tycon (head data_cons)
+ ; let prom_info
+ | not try_promote = NeverPromote
+ | rti_promotable rec_info = Promotable ()
+ | otherwise = NotPromotable
; return (buildAlgTyCon tc_name final_tvs roles cType stupid_theta tc_rhs
(rti_is_rec rec_info tc_name)
- (rti_promotable rec_info)
+ prom_info
(not h98_syntax) NoParentTyCon) }
; return [ATyCon tycon] }
\end{code}
@@ -1303,6 +1384,19 @@ rejigConRes tmpl_tvs res_tmpl dc_tvs (ResTyGADT res_ty)
new_tmpl = updateTyVarKind (substTy subst) tmpl
| otherwise = pprPanic "tcResultType" (ppr res_ty)
ex_tvs = dc_tvs `minusList` univ_tvs
+
+
+tcTyConDecl :: [TyVar] -> Kind -> TyConDecl Name -> TcM TyCon
+tcTyConDecl kvars kind TyConDecl { tycon_name = name, tycon_details = details }
+ = do ks <- case details of
+ PrefixCon args -> mapM tcLHsKind args
+ InfixCon l r -> mapM tcLHsKind [l,r]
+ RecCon {} -> panic "tcTyConDecl" "unexpected record constructor"
+ let (kcon,_) = splitTyConApp kind
+ con_kind = mkPiKinds kvars (mkFunTys ks kind)
+ return (mkDataKindTyCon kcon (unLoc name) con_kind)
+
+
\end{code}
Note [Substitution in template variables kinds]
diff --git a/compiler/typecheck/TcTyDecls.lhs b/compiler/typecheck/TcTyDecls.lhs
index 5091cab802..077b4a91ba 100644
--- a/compiler/typecheck/TcTyDecls.lhs
+++ b/compiler/typecheck/TcTyDecls.lhs
@@ -360,11 +360,11 @@ data RecTyInfo = RTI { rti_promotable :: Bool
, rti_roles :: Name -> [Role]
, rti_is_rec :: Name -> RecFlag }
-calcRecFlags :: ModDetails -> RoleAnnots -> [TyThing] -> RecTyInfo
+calcRecFlags :: Bool -> ModDetails -> RoleAnnots -> [TyThing] -> RecTyInfo
-- The 'boot_names' are the things declared in M.hi-boot, if M is the current module.
-- Any type constructors in boot_names are automatically considered loop breakers
-calcRecFlags boot_details mrole_env tyclss
- = RTI { rti_promotable = is_promotable
+calcRecFlags prevent_promotion boot_details mrole_env tyclss
+ = RTI { rti_promotable = not prevent_promotion && is_promotable
, rti_roles = roles
, rti_is_rec = is_rec }
where
@@ -497,6 +497,7 @@ isPromotableTyCon rec_tycons tc
NewTyCon { data_con = c } -> ok_con c
AbstractTyCon {} -> False
DataFamilyTyCon {} -> False
+ DataKindTyCon {} -> False
where
ok_kind kind = all isLiftedTypeKind args && isLiftedTypeKind res
diff --git a/compiler/types/TyCon.lhs b/compiler/types/TyCon.lhs
index 47e64301b0..8ccbcc9869 100644
--- a/compiler/types/TyCon.lhs
+++ b/compiler/types/TyCon.lhs
@@ -14,6 +14,8 @@ module TyCon(
AlgTyConRhs(..), visibleDataCons,
TyConParent(..), isNoParent,
SynTyConRhs(..), Role(..),
+ PromotionInfo(..),
+ PromotionFlavor,
-- ** Constructing TyCons
mkAlgTyCon,
@@ -27,6 +29,7 @@ module TyCon(
mkForeignTyCon,
mkPromotedDataCon,
mkPromotedTyCon,
+ mkDataKindTyCon,
-- ** Predicates on TyCons
isAlgTyCon,
@@ -38,8 +41,10 @@ module TyCon(
isDecomposableTyCon,
isForeignTyCon,
isPromotedDataCon, isPromotedTyCon,
- isPromotedDataCon_maybe, isPromotedTyCon_maybe,
+ isPromotedTyCon_maybe,
promotableTyCon_maybe, promoteTyCon,
+ promotedDataConParent,
+ promotableTyConInfo,
isInjectiveTyCon,
isDataTyCon, isProductTyCon, isDataProductTyCon_maybe,
@@ -74,6 +79,7 @@ module TyCon(
algTyConRhs,
newTyConRhs, newTyConEtadRhs, unwrapNewTyCon_maybe,
tupleTyConBoxity, tupleTyConSort, tupleTyConArity,
+ tyConDataKind_maybe, isTyConDataKind,
-- ** Manipulating TyCons
tcExpandTyCon_maybe, coreExpandTyCon_maybe,
@@ -86,6 +92,10 @@ module TyCon(
tyConPrimRep,
primRepSizeW, primElemRepSizeB,
+ -- * Kind Constructors
+ KCon,
+ kConTypeCons, kConTypeCons_maybe,
+
-- * Recursion breaking
RecTcChecker, initRecTc, checkRecTc
) where
@@ -93,7 +103,7 @@ module TyCon(
#include "HsVersions.h"
import {-# SOURCE #-} TypeRep ( Kind, Type, PredType )
-import {-# SOURCE #-} DataCon ( DataCon, isVanillaDataCon )
+import {-# SOURCE #-} DataCon ( DataCon, isVanillaDataCon, dataConTyCon )
import Var
import Class
@@ -375,7 +385,7 @@ data TyCon
-- or family instances, respectively.
-- See also 'synTcParent'
- tcPromoted :: Maybe TyCon -- ^ Promoted TyCon, if any
+ tcPromoted :: PromotionFlavor -- ^ Promoted TyCon, if any
}
-- | Represents the infinite family of tuple type constructors,
@@ -388,7 +398,7 @@ data TyCon
tyConTupleSort :: TupleSort,
tyConTyVars :: [TyVar],
dataCon :: DataCon, -- ^ Corresponding tuple data constructor
- tcPromoted :: Maybe TyCon -- Nothing for unboxed tuples
+ tcPromoted :: PromotionFlavor -- Nothing for unboxed tuples
}
-- | Represents type synonyms
@@ -432,14 +442,17 @@ data TyCon
-- holds the name of the imported thing
}
- -- | Represents promoted data constructor.
+ -- | Represents promoted data constructor or type constructors introduced by a
+ -- 'data kind' declaration.
| PromotedDataCon { -- See Note [Promoted data constructors]
- tyConUnique :: Unique, -- ^ Same Unique as the data constructor
- tyConName :: Name, -- ^ Same Name as the data constructor
+ tyConUnique :: Unique, -- ^ For promoted data cons, same Unique as the data constructor
+ tyConName :: Name, -- ^ For promoted data cons, same Name as the data constructor
tyConArity :: Arity,
tc_roles :: [Role], -- ^ Roles: N for kind vars, R for type vars
tc_kind :: Kind, -- ^ Translated type of the data constructor
- dataCon :: DataCon -- ^ Corresponding data constructor
+ parentTyCon :: TyCon -- ^ Corresponding parent LHS constructor.
+ -- Type constructor for the promoted case, kind
+ -- constructor for the 'data kind' case.
}
-- | Represents promoted type constructor.
@@ -453,9 +466,27 @@ data TyCon
deriving Typeable
+-- | Kind constructor (a TyCon that returns kind super kind).
+type KCon = TyCon
+
-- | Names of the fields in an algebraic record type
type FieldLabel = Name
+type PromotionFlavor = PromotionInfo TyCon
+
+-- | How promotion should operate for an AlgTyCon.
+data PromotionInfo con
+ = NeverPromote -- ^ Promotion is explicitly disabled by 'data type' syntax
+ | NotPromotable -- ^ Promotion is not possible
+ | Promotable con -- ^ Promotion is possible, use this con
+ deriving (Typeable)
+
+instance Functor PromotionInfo where
+ fmap f p = case p of
+ Promotable a -> Promotable (f a)
+ NeverPromote -> NeverPromote
+ NotPromotable -> NotPromotable
+
-- | Represents right-hand-sides of 'TyCon's for algebraic types
data AlgTyConRhs
@@ -526,6 +557,14 @@ data AlgTyConRhs
-- again check Trac #1072.
}
+ -- | Constructors for the rhs of a 'data kind' declaration.
+ | DataKindTyCon {
+ data_kind_cons :: [TyCon] -- ^ Type constructors for the RHS of the
+ -- 'data kind' declaration.
+ --
+ -- INVARIANT: These will be all
+ -- @AbstractTyCon@, as defined above.
+ }
\end{code}
Note [AbstractTyCon and type equality]
@@ -542,6 +581,7 @@ visibleDataCons (AbstractTyCon {}) = []
visibleDataCons DataFamilyTyCon {} = []
visibleDataCons (DataTyCon{ data_cons = cs }) = cs
visibleDataCons (NewTyCon{ data_con = c }) = [c]
+visibleDataCons DataKindTyCon{} = []
-- ^ Both type classes as well as family instances imply implicit
-- type constructors. These implicit type constructors refer to their parent
@@ -919,9 +959,9 @@ mkAlgTyCon :: Name
-> TyConParent
-> RecFlag -- ^ Is the 'TyCon' recursive?
-> Bool -- ^ Was the 'TyCon' declared with GADT syntax?
- -> Maybe TyCon -- ^ Promoted version
+ -> PromotionFlavor -- ^ Promoted version
-> TyCon
-mkAlgTyCon name kind tyvars roles cType stupid rhs parent is_rec gadt_syn prom_tc
+mkAlgTyCon name kind tyvars roles cType stupid rhs parent is_rec gadt_syn prom_info
= AlgTyCon {
tyConName = name,
tyConUnique = nameUnique name,
@@ -935,7 +975,7 @@ mkAlgTyCon name kind tyvars roles cType stupid rhs parent is_rec gadt_syn prom_t
algTcParent = ASSERT2( okParent name parent, ppr name $$ ppr parent ) parent,
algTcRec = is_rec,
algTcGadtSyntax = gadt_syn,
- tcPromoted = prom_tc
+ tcPromoted = prom_info
}
-- | Simpler specialization of 'mkAlgTyCon' for classes
@@ -943,7 +983,7 @@ mkClassTyCon :: Name -> Kind -> [TyVar] -> [Role] -> AlgTyConRhs -> Class -> Rec
mkClassTyCon name kind tyvars roles rhs clas is_rec
= mkAlgTyCon name kind tyvars roles Nothing [] rhs (ClassTyCon clas)
is_rec False
- Nothing -- Class TyCons are not pormoted
+ NotPromotable -- Class TyCons are not pormoted
mkTupleTyCon :: Name
-> Kind -- ^ Kind of the resulting 'TyCon'
@@ -951,9 +991,9 @@ mkTupleTyCon :: Name
-> [TyVar] -- ^ 'TyVar's scoped over: see 'tyConTyVars'
-> DataCon
-> TupleSort -- ^ Whether the tuple is boxed or unboxed
- -> Maybe TyCon -- ^ Promoted version
+ -> PromotionFlavor -- ^ Promoted version
-> TyCon
-mkTupleTyCon name kind arity tyvars con sort prom_tc
+mkTupleTyCon name kind arity tyvars con sort prom_info
= TupleTyCon {
tyConUnique = nameUnique name,
tyConName = name,
@@ -962,7 +1002,7 @@ mkTupleTyCon name kind arity tyvars con sort prom_tc
tyConTupleSort = sort,
tyConTyVars = tyvars,
dataCon = con,
- tcPromoted = prom_tc
+ tcPromoted = prom_info
}
-- ^ Foreign-imported (.NET) type constructors are represented
@@ -1040,11 +1080,24 @@ mkPromotedDataCon con name unique kind roles
tyConArity = arity,
tc_roles = roles,
tc_kind = kind,
- dataCon = con
+ parentTyCon = dataConTyCon con
}
where
arity = length roles
+-- | Construct a type constructor for a type introduced by a 'data kind'
+-- declaration.
+mkDataKindTyCon :: TyCon -> Name -> Kind -> TyCon
+mkDataKindTyCon kc name kind
+ = PromotedDataCon {
+ tyConName = name,
+ tyConUnique = nameUnique name,
+ tyConArity = 0,
+ tc_roles = [], -- XXX is this correct?
+ tc_kind = kind,
+ parentTyCon = kc
+ }
+
-- | Create a promoted type constructor 'TyCon'
-- Somewhat dodgily, we give it the same Name
-- as the type constructor itself
@@ -1111,6 +1164,7 @@ isDataTyCon (AlgTyCon {algTcRhs = rhs})
NewTyCon {} -> False
DataFamilyTyCon {} -> False
AbstractTyCon {} -> False -- We don't know, so return False
+ DataKindTyCon {} -> False
isDataTyCon (TupleTyCon {tyConTupleSort = sort}) = isBoxed (tupleSortBoxity sort)
isDataTyCon _ = False
@@ -1135,6 +1189,7 @@ isDistinctAlgRhs (DataTyCon {}) = True
isDistinctAlgRhs (DataFamilyTyCon {}) = True
isDistinctAlgRhs (AbstractTyCon distinct) = distinct
isDistinctAlgRhs (NewTyCon {}) = False
+isDistinctAlgRhs (DataKindTyCon{}) = True
-- | Is this 'TyCon' that for a @newtype@
isNewTyCon :: TyCon -> Bool
@@ -1260,6 +1315,15 @@ tyConAssoc_maybe tc = case tyConParent tc of
AssocFamilyTyCon cls -> Just cls
_ -> Nothing
+-- | Is this TyCon defined as part of the RHS of a 'data kind' declaration?
+isTyConDataKind :: TyCon -> Bool
+isTyConDataKind tc = isJust (tyConDataKind_maybe tc)
+
+tyConDataKind_maybe :: TyCon -> Maybe TyCon
+tyConDataKind_maybe tc = case tc of
+ PromotedDataCon { parentTyCon = s@AlgTyCon { algTcRhs = DataKindTyCon {} } } -> Just s
+ _ -> Nothing
+
-- The unit tycon didn't used to be classed as a tuple tycon
-- but I thought that was silly so I've undone it
-- If it can't be for some reason, it should be a AlgTyCon
@@ -1303,10 +1367,15 @@ isRecursiveTyCon :: TyCon -> Bool
isRecursiveTyCon (AlgTyCon {algTcRec = Recursive}) = True
isRecursiveTyCon _ = False
+promotableTyConInfo :: TyCon -> PromotionFlavor
+promotableTyConInfo (AlgTyCon { tcPromoted = prom }) = prom
+promotableTyConInfo (TupleTyCon { tcPromoted = prom }) = prom
+promotableTyConInfo _ = NotPromotable
+
promotableTyCon_maybe :: TyCon -> Maybe TyCon
-promotableTyCon_maybe (AlgTyCon { tcPromoted = prom }) = prom
-promotableTyCon_maybe (TupleTyCon { tcPromoted = prom }) = prom
-promotableTyCon_maybe _ = Nothing
+promotableTyCon_maybe tc = case promotableTyConInfo tc of
+ Promotable tycon -> Just tycon
+ _ -> Nothing
promoteTyCon :: TyCon -> TyCon
promoteTyCon tc = case promotableTyCon_maybe tc of
@@ -1333,10 +1402,11 @@ isPromotedDataCon :: TyCon -> Bool
isPromotedDataCon (PromotedDataCon {}) = True
isPromotedDataCon _ = False
--- | Retrieves the promoted DataCon if this is a PromotedDataCon;
-isPromotedDataCon_maybe :: TyCon -> Maybe DataCon
-isPromotedDataCon_maybe (PromotedDataCon { dataCon = dc }) = Just dc
-isPromotedDataCon_maybe _ = Nothing
+-- | Returns the TyCon for the parent when this is a normal data type,
+-- and the TyCon for the kind definition if this is a 'data kind' definition.
+promotedDataConParent :: TyCon -> Maybe TyCon
+promotedDataConParent PromotedDataCon { parentTyCon = tc } = Just tc
+promotedDataConParent _ = Nothing
-- | Identifies implicit tycons that, in particular, do not go into interface
-- files (because they are implicitly reconstructed when the interface is
@@ -1425,6 +1495,14 @@ tyConDataCons_maybe (AlgTyCon {algTcRhs = NewTyCon { data_con = con }}) = Jus
tyConDataCons_maybe (TupleTyCon {dataCon = con}) = Just [con]
tyConDataCons_maybe _ = Nothing
+
+kConTypeCons :: KCon -> [TyCon]
+kConTypeCons kcon = kConTypeCons_maybe kcon `orElse` []
+
+kConTypeCons_maybe :: KCon -> Maybe [TyCon]
+kConTypeCons_maybe AlgTyCon { algTcRhs = DataKindTyCon cons } = Just cons
+kConTypeCons_maybe _ = Nothing
+
-- | Determine the number of value constructors a 'TyCon' has. Panics if the 'TyCon'
-- is not algebraic or a tuple
tyConFamilySize :: TyCon -> Int
@@ -1620,7 +1698,9 @@ instance Outputable TyCon where
ppr tc = pprPromotionQuote tc <> ppr (tyConName tc)
pprPromotionQuote :: TyCon -> SDoc
-pprPromotionQuote (PromotedDataCon {}) = char '\'' -- Quote promoted DataCons in types
+pprPromotionQuote con@(PromotedDataCon {})
+ | isTyConDataKind con = empty
+ | otherwise = char '\'' -- Quote promoted DataCons in types
pprPromotionQuote (PromotedTyCon {}) = ifPprDebug (char '\'')
pprPromotionQuote _ = empty -- However, we don't quote TyCons in kinds
-- e.g. type family T a :: Bool -> *
diff --git a/compiler/types/TypeRep.lhs b/compiler/types/TypeRep.lhs
index 2b127369d4..c64d7d1a34 100644
--- a/compiler/types/TypeRep.lhs
+++ b/compiler/types/TypeRep.lhs
@@ -63,7 +63,7 @@ module TypeRep (
#include "HsVersions.h"
-import {-# SOURCE #-} DataCon( DataCon, dataConTyCon, dataConName )
+import {-# SOURCE #-} DataCon( DataCon, dataConName )
import {-# SOURCE #-} Type( noParenPred, isPredTy ) -- Transitively pulls in a LOT of stuff, better to break the loop
-- friends:
@@ -681,8 +681,7 @@ pprTcApp p pp tc tys
= pprPromotionQuote tc <>
tupleParens (tupleTyConSort tc) (sep (punctuate comma (map (pp TopPrec) tys)))
- | Just dc <- isPromotedDataCon_maybe tc
- , let dc_tc = dataConTyCon dc
+ | Just dc_tc <- promotedDataConParent tc
, isTupleTyCon dc_tc
, let arity = tyConArity dc_tc -- E.g. 3 for (,,) k1 k2 k3 t1 t2 t3
ty_args = drop arity tys -- Drop the kind args
diff --git a/compiler/vectorise/Vectorise/Generic/PData.hs b/compiler/vectorise/Vectorise/Generic/PData.hs
index 37358c9bdf..8a54776879 100644
--- a/compiler/vectorise/Vectorise/Generic/PData.hs
+++ b/compiler/vectorise/Vectorise/Generic/PData.hs
@@ -57,7 +57,7 @@ buildDataFamInst name' fam_tc vect_tc rhs
[] -- no stupid theta
rhs
rec_flag -- FIXME: is this ok?
- False -- Not promotable
+ NotPromotable
False -- not GADT syntax
(FamInstTyCon ax fam_tc pat_tys)
; liftDs $ newFamInst (DataFamilyInst rep_tc) ax }
diff --git a/compiler/vectorise/Vectorise/Type/TyConDecl.hs b/compiler/vectorise/Vectorise/Type/TyConDecl.hs
index 935ea32c69..ee8e29fd2e 100644
--- a/compiler/vectorise/Vectorise/Type/TyConDecl.hs
+++ b/compiler/vectorise/Vectorise/Type/TyConDecl.hs
@@ -106,7 +106,7 @@ vectTyConDecl tycon name'
[] -- no stupid theta
rhs' -- new constructor defs
rec_flag -- whether recursive
- False -- Not promotable
+ NotPromotable
gadt_flag -- whether in GADT syntax
NoParentTyCon
}
@@ -151,6 +151,9 @@ vectAlgTyConRhs tc (NewTyCon {})
cantVectorise dflags noNewtypeErr (ppr tc)
where
noNewtypeErr = "Vectorisation of newtypes not supported yet; please use a 'data' declaration"
+vectAlgTyConRhs tc DataKindTyCon{} =
+ do dflags <- getDynFlags
+ cantVectorise dflags "Can't vectorise 'data kind' declarations" (ppr tc)
-- |Vectorise a data constructor by vectorising its argument and return types..
--
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index c825da90c7..3246c5a3df 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -6152,6 +6152,81 @@ no way to quote a data constructor or type constructor whose second character
is a single quote.</para>
</sect2>
+<sect2 id="restricting-promotion">
+<title>Restricting Promotion</title>
+<para>
+By default, promotable types are always promoted. In some cases, the promoted
+kind is not necessary, so to avoid name collisions the programmer may disable
+datatype promotion explicitly, by using a <literal>data type</literal>
+declaration.
+</para>
+
+<para>
+For example, if we wanted to declare a type for the natural numbers that is not
+promoted, we could use the following declaration:
+<programlisting>
+data type Nat = Ze | Su Nat
+</programlisting>
+This declaration will introduce a type <literal>Nat</literal>, and two
+value-level data constructors, <literal>Ze</literal> and <literal>Su</literal>
+(i.e., as though -XDataKinds was disabled for this declaration)
+</para>
+</sect2>
+
+<sect2 id="kind-only-declarations">
+<title>Kind-only Declarations</title>
+<para>
+Sometimes we may want to define only a new kind, without needing to promote a
+type declaration. Typically, there are two reasons for this: (i) to avoid name
+clashes with existing types, and (ii) defining kinds that use primitive kinds
+such as <literal>*</literal> that are not also types. This is done by using a
+<literal>data kind</literal> declaration.
+</para>
+
+<para>
+For example, to declare only the kind of natural numbers, without the
+corresponding type and value-level constructors, we would use:
+<programlisting>
+data kind Nat = Ze | Su Nat
+</programlisting>
+This introduces a new kind <literal>Nat</literal> and two new type constructors
+<literal>Ze :: Nat</literal> and <literal>Su :: Nat -> Nat</literal>.
+</para>
+
+<para>
+As another example, consider the following declaration:
+<programlisting>
+data kind Area = Array Nat Area
+ | Stored *
+</programlisting>
+This introduces a new kind <literal>Area</literal> and two type constructors,
+<literal>Array :: Nat -> Area -> Area</literal>, and <literal>Stored :: * ->
+Area</literal>. Note that we could not declare this type by promotion, because
+both kinds <literal>Nat</literal> and <literal>*</literal> don't exist at the
+type-level.
+</para>
+
+<para>
+New kinds introduced with <literal>data kind</literal> may have kind parameters,
+although this requires that <literal>-XPolyKinds</literal> be enabled as the
+resulting type constructors have polymorphic kinds. For example, a kind-only
+declaration for lists would look like:
+<programlisting>
+data kind List a = Nil | Cons a (List a)
+</programlisting>
+This introduces a new kind <literal>List</literal> and two type constructors,
+<literal>Nil :: forall a. a -> List a</literal>, and <literal>Cons :: forall a.
+a -> List a -> List a</literal>.
+</para>
+
+<para>
+As kinds and types currently share a namespace, <literal>data kind</literal> and
+<literal>data type</literal> declarations <i>in the same module</i> can still
+conflict. However, if they are in separate modules, this can be controlled by
+use of the module system.
+</para>
+</sect2>
+
<sect2 id="promoted-lists-and-tuples">
<title>Promoted lists and tuples types</title>
<para>