summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/typecheck/TcBinds.lhs3
-rw-r--r--compiler/typecheck/TcClassDcl.lhs49
-rw-r--r--compiler/typecheck/TcHsType.lhs50
-rw-r--r--compiler/typecheck/TcInstDcls.lhs106
-rw-r--r--compiler/typecheck/TcRnDriver.lhs66
-rw-r--r--compiler/typecheck/TcRnTypes.lhs31
-rw-r--r--compiler/typecheck/TcSplice.lhs3
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs204
-rw-r--r--docs/users_guide/flags.xml5
-rw-r--r--docs/users_guide/glasgow_exts.xml228
10 files changed, 400 insertions, 345 deletions
diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs
index e6e07576d2..530d867b20 100644
--- a/compiler/typecheck/TcBinds.lhs
+++ b/compiler/typecheck/TcBinds.lhs
@@ -1210,8 +1210,7 @@ decideGeneralisationPlan dflags type_env bndr_names lbinds sig_fn
ATcId { tct_closed = cl } -> isTopLevel cl -- This is the key line
ATyVar {} -> False -- In-scope type variables
AGlobal {} -> True -- are not closed!
- AThing {} -> pprPanic "is_closed_id" (ppr name)
- ANothing {} -> pprPanic "is_closed_id" (ppr name)
+ _ -> pprPanic "is_closed_id" (ppr name)
| otherwise
= WARN( isInternalName name, ppr name ) True
-- The free-var set for a top level binding mentions
diff --git a/compiler/typecheck/TcClassDcl.lhs b/compiler/typecheck/TcClassDcl.lhs
index b9711576c4..cde5eaa613 100644
--- a/compiler/typecheck/TcClassDcl.lhs
+++ b/compiler/typecheck/TcClassDcl.lhs
@@ -15,7 +15,6 @@ Typechecking class declarations
module TcClassDcl ( tcClassSigs, tcClassDecl2,
findMethodBind, instantiateMethod, tcInstanceMethodBody,
- mkGenericDefMethBind,
HsSigFun, mkHsSigFun, lookupHsSig, emptyHsSigs,
tcAddDeclCtxt, badMethodErr
) where
@@ -41,8 +40,6 @@ import NameEnv
import NameSet
import Var
import Outputable
-import DynFlags
-import ErrUtils
import SrcLoc
import Maybes
import BasicTypes
@@ -349,52 +346,6 @@ This makes the error messages right.
%************************************************************************
%* *
- Extracting generic instance declaration from class declarations
-%* *
-%************************************************************************
-
-@getGenericInstances@ extracts the generic instance declarations from a class
-declaration. For exmaple
-
- class C a where
- op :: a -> a
-
- op{ x+y } (Inl v) = ...
- op{ x+y } (Inr v) = ...
- op{ x*y } (v :*: w) = ...
- op{ 1 } Unit = ...
-
-gives rise to the instance declarations
-
- instance C (x+y) where
- op (Inl v) = ...
- op (Inr v) = ...
-
- instance C (x*y) where
- op (v :*: w) = ...
-
- instance C 1 where
- op Unit = ...
-
-\begin{code}
-mkGenericDefMethBind :: Class -> [Type] -> Id -> Name -> TcM (LHsBind Name)
-mkGenericDefMethBind clas inst_tys sel_id dm_name
- = -- A generic default method
- -- If the method is defined generically, we only have to call the
- -- dm_name.
- do { dflags <- getDynFlags
- ; liftIO (dumpIfSet_dyn dflags Opt_D_dump_deriv "Filling in method body"
- (vcat [ppr clas <+> ppr inst_tys,
- nest 2 (ppr sel_id <+> equals <+> ppr rhs)]))
-
- ; return (noLoc $ mkTopFunBind (noLoc (idName sel_id))
- [mkSimpleMatch [] rhs]) }
- where
- rhs = nlHsVar dm_name
-\end{code}
-
-%************************************************************************
-%* *
Error messages
%* *
%************************************************************************
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs
index a3808822f6..7f4eed87ce 100644
--- a/compiler/typecheck/TcHsType.lhs
+++ b/compiler/typecheck/TcHsType.lhs
@@ -19,18 +19,18 @@ module TcHsType (
-- Type checking type and class decls
kcTyClTyVars, tcTyClTyVars,
- tcHsConArgType, tcDataKindSig,
+ tcHsArgType, tcHsConArgType, tcDataKindSig,
tcClassSigType,
-- Kind-checking types
-- No kind generalisation, no checkValidType
- tcHsTyVarBndrs,
+ kcHsTyVarBndrs, tcHsTyVarBndrs,
tcHsLiftedType,
tcLHsType, tcCheckLHsType,
tcHsContext, tcInferApps, tcHsArgTys,
ExpKind(..), ekConstraint, expArgKind, checkExpectedKind,
- kindGeneralize,
+ bindScopedKindVars, kindGeneralize,
-- Sort-checking kinds
tcLHsKind,
@@ -577,12 +577,16 @@ tcTyVar name -- Could be a tyvar, a tycon, or a datacon
ty = dataConUserType dc
tc = buildPromotedDataCon dc
- ANothing -> failWithTc (ptext (sLit "Promoted kind") <+>
- quotes (ppr name) <+>
- ptext (sLit "used in a mutually recursive group"))
+ AFamDataCon -> bad_promote (ptext (sLit "it comes from a data family instance"))
+ ARecDataCon -> bad_promote (ptext (sLit "it is defined and used in the same recursive group"))
_ -> wrongThingErr "type" thing name }
where
+ bad_promote reason
+ = failWithTc (hang (ptext (sLit "You can't use data constructor") <+> quotes (ppr name)
+ <+> ptext (sLit "here"))
+ 2 (parens reason))
+
get_loopy_tc name
= do { env <- getGblEnv
; case lookupNameEnv (tcg_type_env env) name of
@@ -783,19 +787,42 @@ then we'd also need
since we only have BOX for a super kind)
\begin{code}
-bindScopedKindVars :: [Name] -> TcM a -> TcM a
+bindScopedKindVars :: [Name] -> ([KindVar] -> TcM a) -> TcM a
-- Given some tyvar binders like [a (b :: k -> *) (c :: k)]
-- bind each scoped kind variable (k in this case) to a fresh
-- kind skolem variable
-bindScopedKindVars kvs thing_inside
- = tcExtendTyVarEnv (map mkKindSigVar kvs) thing_inside
+bindScopedKindVars kv_ns thing_inside
+ = tcExtendTyVarEnv kvs (thing_inside kvs)
+ where
+ kvs = map mkKindSigVar kv_ns
+
+kcHsTyVarBndrs :: Bool -- Default UserTyVar to *
+ -> LHsTyVarBndrs Name
+ -> ([TcKind] -> TcM r)
+ -> TcM r
+kcHsTyVarBndrs default_to_star (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
+ = bindScopedKindVars kvs $ \ _ ->
+ do { nks <- mapM (kc_hs_tv . unLoc) hs_tvs
+ ; tcExtendKindEnv nks (thing_inside (map snd nks)) }
+ where
+ kc_hs_tv :: HsTyVarBndr Name -> TcM (Name, TcKind)
+ kc_hs_tv (UserTyVar n)
+ = do { mb_thing <- tcLookupLcl_maybe n
+ ; kind <- case mb_thing of
+ Just (AThing k) -> return k
+ _ | default_to_star -> return liftedTypeKind
+ | otherwise -> newMetaKindVar
+ ; return (n, kind) }
+ kc_hs_tv (KindedTyVar n k)
+ = do { kind <- tcLHsKind k
+ ; return (n, kind) }
tcHsTyVarBndrs :: LHsTyVarBndrs Name
-> ([TyVar] -> TcM r)
-> TcM r
-- Bind the type variables to skolems, each with a meta-kind variable kind
tcHsTyVarBndrs (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
- = bindScopedKindVars kvs $
+ = bindScopedKindVars kvs $ \ _ ->
do { tvs <- mapM tcHsTyVarBndr hs_tvs
; traceTc "tcHsTyVarBndrs" (ppr hs_tvs $$ ppr tvs)
; tcExtendTyVarEnv tvs (thing_inside tvs) }
@@ -904,7 +931,7 @@ kcTyClTyVars :: Name -> LHsTyVarBndrs Name -> (TcKind -> TcM a) -> TcM a
-- Used for the type variables of a type or class decl,
-- when doing the initial kind-check.
kcTyClTyVars name (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
- = bindScopedKindVars kvs $
+ = bindScopedKindVars kvs $ \ _ ->
do { tc_kind <- kcLookupKind name
; let (arg_ks, res_k) = splitKindFunTysN (length hs_tvs) tc_kind
-- There should be enough arrows, because
@@ -1354,7 +1381,6 @@ tc_kind_var_app name arg_kis
= do { (_errs, mb_thing) <- tryTc (tcLookup name)
; case mb_thing of
Just (AGlobal (ATyCon tc))
- | isAlgTyCon tc || isTupleTyCon tc
-> do { data_kinds <- xoptM Opt_DataKinds
; unless data_kinds $ addErr (dataKindsErr name)
; case isPromotableTyCon tc of
diff --git a/compiler/typecheck/TcInstDcls.lhs b/compiler/typecheck/TcInstDcls.lhs
index bc217bb041..920a702059 100644
--- a/compiler/typecheck/TcInstDcls.lhs
+++ b/compiler/typecheck/TcInstDcls.lhs
@@ -19,8 +19,12 @@ module TcInstDcls ( tcInstDecls1, tcInstDecls2 ) where
import HsSyn
import TcBinds
-import TcTyClsDecls
-import TcClassDcl
+import TcTyClsDecls( tcAddImplicits, tcAddFamInstCtxt, tcSynFamInstDecl,
+ wrongKindOfFamily, tcFamTyPats, kcTyDefn, dataDeclChecks,
+ tcConDecls, checkValidTyCon, badATErr, wrongATArgErr )
+import TcClassDcl( tcClassDecl2,
+ HsSigFun, lookupHsSig, mkHsSigFun, emptyHsSigs,
+ findMethodBind, instantiateMethod, tcInstanceMethodBody )
import TcPat ( addInlinePrags )
import TcRnMonad
import TcMType
@@ -51,15 +55,14 @@ import PrelNames ( typeableClassNames )
import Bag
import BasicTypes
import DynFlags
+import ErrUtils
import FastString
import Id
import MkId
import Name
import NameSet
-import NameEnv
import Outputable
import SrcLoc
-import Digraph( SCC(..) )
import Util
import Control.Monad
@@ -373,8 +376,12 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
-- round)
-- Do class and family instance declarations
- ; (gbl_env, local_infos) <- tcLocalInstDecls (calcInstDeclCycles inst_decls)
- ; setGblEnv gbl_env $
+ ; stuff <- mapAndRecoverM tcLocalInstDecl inst_decls
+ ; let (local_infos_s, fam_insts_s) = unzip stuff
+ local_infos = concat local_infos_s
+ fam_insts = concat fam_insts_s
+ ; addClsInsts local_infos $
+ addFamInsts fam_insts $
do { -- Compute instances from "deriving" clauses;
-- This stuff computes a context for the derived instance
@@ -389,7 +396,8 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
; th_stage <- getStage -- See Note [Deriving inside TH brackets ]
; (gbl_env, deriv_inst_info, deriv_binds)
<- if isBrackStage th_stage
- then return (gbl_env, emptyBag, emptyValBindsOut)
+ then do { gbl_env <- getGblEnv
+ ; return (gbl_env, emptyBag, emptyValBindsOut) }
else tcDeriving tycl_decls inst_decls deriv_decls
@@ -414,20 +422,6 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
typInstErr = ptext $ sLit $ "Can't create hand written instances of Typeable in Safe"
++ " Haskell! Can only derive them"
-tcLocalInstDecls :: [SCC (LInstDecl Name)] -> TcM (TcGblEnv, [InstInfo Name])
-tcLocalInstDecls []
- = do { gbl_env <- getGblEnv
- ; return (gbl_env, []) }
-tcLocalInstDecls (AcyclicSCC inst_decl : sccs)
- = do { (inst_infos, fam_insts) <- recoverM (return ([], [])) $
- tcLocalInstDecl inst_decl
- ; (gbl_env, more_infos) <- addClsInsts inst_infos $
- addFamInsts fam_insts $
- tcLocalInstDecls sccs
- ; return (gbl_env, inst_infos ++ more_infos) }
-tcLocalInstDecls (CyclicSCC inst_decls : _)
- = do { cyclicDeclErr inst_decls; failM }
-
addClsInsts :: [InstInfo Name] -> TcM a -> TcM a
addClsInsts infos thing_inside
= tcExtendLocalInstEnv (map iSpec infos) thing_inside
@@ -464,59 +458,6 @@ bindings.) This will become moot when we shift to the new TH plan, so
the brutal solution will do.
-Note [Instance declaration cycles]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-With -XDataKinds we can get this
- data instance Foo [a] = MkFoo (MkFoo a)
-where the constructor MkFoo is used in a type before it is
-defined. Here is a more complicated situation, involving an
-associated type and mutual recursion
-
- data instance T [a] = MkT (MkS a)
-
- instance C [a] where
- data S [a] = MkS (MkT a)
-
-When type checking ordinary data type decls we detect this staging
-problem in the kind-inference phase, but there *is* no kind inference
-phase here.
-
-So intead we extract the strongly connected components and look for
-cycles.
-
-
-\begin{code}
-calcInstDeclCycles :: [LInstDecl Name] -> [SCC (LInstDecl Name)]
--- see Note [Instance declaration cycles]
-calcInstDeclCycles decls
- = depAnal get_defs get_uses decls
- where
- -- get_defs extracts the *constructor* bindings of the declaration
- get_defs :: LInstDecl Name -> [Name]
- get_defs (L _ (FamInstD { lid_inst = fid })) = get_fi_defs fid
- get_defs (L _ (ClsInstD { cid_fam_insts = fids })) = concatMap (get_fi_defs . unLoc) fids
-
- get_fi_defs :: FamInstDecl Name -> [Name]
- get_fi_defs (FamInstDecl { fid_defn = TyData { td_cons = cons } })
- = map (unLoc . con_name . unLoc) cons
- get_fi_defs (FamInstDecl {}) = []
-
- -- get_uses extracts the *tycon or constructor* uses of the declaration
- get_uses :: LInstDecl Name -> [Name]
- get_uses (L _ (FamInstD { lid_inst = fid })) = nameSetToList (fid_fvs fid)
- get_uses (L _ (ClsInstD { cid_fam_insts = fids }))
- = nameSetToList (foldr (unionNameSets . fid_fvs . unLoc) emptyNameSet fids)
-
-cyclicDeclErr :: Outputable d => [Located d] -> TcRn ()
-cyclicDeclErr inst_decls
- = setSrcSpan (getLoc (head sorted_decls)) $
- addErr (sep [ptext (sLit "Cycle in type declarations: data constructor used (in a type) before it is defined"),
- nest 2 (vcat (map ppr_decl sorted_decls))])
- where
- sorted_decls = sortLocated inst_decls
- ppr_decl (L loc decl) = ppr loc <> colon <+> ppr decl
-\end{code}
-
\begin{code}
tcLocalInstDecl :: LInstDecl Name
-> TcM ([InstInfo Name], [FamInst])
@@ -878,7 +819,6 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
loc = getSrcSpan dfun_id
------------------------------
-----------------------
mkMethIds :: HsSigFun -> Class -> [TcTyVar] -> [EvVar]
-> [TcType] -> Id -> TcM (TcId, TcSigInfo)
mkMethIds sig_fn clas tyvars dfun_ev_vars inst_tys sel_id
@@ -1275,6 +1215,22 @@ tcInstanceMethods dfun_id clas tyvars dfun_ev_vars inst_tys
(_, local_meth_ty) = tcSplitPredFunTy_maybe sel_rho
`orElse` pprPanic "tcInstanceMethods" (ppr sel_id)
+------------------
+mkGenericDefMethBind :: Class -> [Type] -> Id -> Name -> TcM (LHsBind Name)
+mkGenericDefMethBind clas inst_tys sel_id dm_name
+ = -- A generic default method
+ -- If the method is defined generically, we only have to call the
+ -- dm_name.
+ do { dflags <- getDynFlags
+ ; liftIO (dumpIfSet_dyn dflags Opt_D_dump_deriv "Filling in method body"
+ (vcat [ppr clas <+> ppr inst_tys,
+ nest 2 (ppr sel_id <+> equals <+> ppr rhs)]))
+
+ ; return (noLoc $ mkTopFunBind (noLoc (idName sel_id))
+ [mkSimpleMatch [] rhs]) }
+ where
+ rhs = nlHsVar dm_name
+
----------------------
wrapId :: HsWrapper -> id -> HsExpr id
wrapId wrapper id = mkHsWrap wrapper (HsVar id)
diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs
index 95274f0814..d16d838286 100644
--- a/compiler/typecheck/TcRnDriver.lhs
+++ b/compiler/typecheck/TcRnDriver.lhs
@@ -551,17 +551,10 @@ tcRnHsBootDecls decls
; mapM_ (badBootDecl "rule") rule_decls
; mapM_ (badBootDecl "vect") vect_decls
- -- Typecheck type/class decls
+ -- Typecheck type/class/isntance decls
; traceTc "Tc2 (boot)" empty
- ; tcg_env <- tcTyAndClassDecls emptyModDetails tycl_decls
- ; setGblEnv tcg_env $ do {
-
- -- Typecheck instance decls
- -- Family instance declarations are rejected here
- ; traceTc "Tc3" empty
; (tcg_env, inst_infos, _deriv_binds)
- <- tcInstDecls1 (concat tycl_decls) inst_decls deriv_decls
-
+ <- tcTyClsInstDecls emptyModDetails tycl_decls inst_decls deriv_decls
; setGblEnv tcg_env $ do {
-- Typecheck value declarations
@@ -583,7 +576,7 @@ tcRnHsBootDecls decls
}
; setGlobalTypeEnv gbl_env type_env2
- }}}
+ }}
; traceTc "boot" (ppr lie); return gbl_env }
badBootDecl :: String -> Located decl -> TcM ()
@@ -897,14 +890,11 @@ tcTopSrcDecls boot_details
-- The latter come in via tycl_decls
traceTc "Tc2 (src)" empty ;
- tcg_env <- tcTyAndClassDecls boot_details tycl_decls ;
- setGblEnv tcg_env $ do {
-
-- Source-language instances, including derivings,
-- and import the supporting declarations
traceTc "Tc3" empty ;
(tcg_env, inst_infos, deriv_binds)
- <- tcInstDecls1 (concat tycl_decls) inst_decls deriv_decls;
+ <- tcTyClsInstDecls boot_details tycl_decls inst_decls deriv_decls ;
setGblEnv tcg_env $ do {
-- Foreign import declarations next.
@@ -964,9 +954,55 @@ tcTopSrcDecls boot_details
, tcg_fords = tcg_fords tcg_env ++ foe_decls ++ fi_decls } } ;
return (tcg_env', tcl_env)
- }}}}}}}
+ }}}}}}
+
+---------------------------
+tcTyClsInstDecls :: ModDetails
+ -> [TyClGroup Name]
+ -> [LInstDecl Name]
+ -> [LDerivDecl Name]
+ -> TcM (TcGblEnv, -- The full inst env
+ [InstInfo Name], -- Source-code instance decls to process;
+ -- contains all dfuns for this module
+ HsValBinds Name) -- Supporting bindings for derived instances
+
+tcTyClsInstDecls boot_details tycl_decls inst_decls deriv_decls
+ = tcExtendTcTyThingEnv [(con, AFamDataCon) | lid <- inst_decls
+ , con <- get_cons lid ] $
+ -- Note [AFamDataCon: not promoting data family constructors]
+ do { tcg_env <- tcTyAndClassDecls boot_details tycl_decls ;
+ ; setGblEnv tcg_env $
+ tcInstDecls1 (concat tycl_decls) inst_decls deriv_decls }
+ where
+ -- get_cons extracts the *constructor* bindings of the declaration
+ get_cons :: LInstDecl Name -> [Name]
+ get_cons (L _ (FamInstD { lid_inst = fid })) = get_fi_cons fid
+ get_cons (L _ (ClsInstD { cid_fam_insts = fids })) = concatMap (get_fi_cons . unLoc) fids
+
+ get_fi_cons :: FamInstDecl Name -> [Name]
+ get_fi_cons (FamInstDecl { fid_defn = TyData { td_cons = cons } })
+ = map (unLoc . con_name . unLoc) cons
+ get_fi_cons (FamInstDecl {}) = []
\end{code}
+Note [AFamDataCon: not promoting data family constructors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+ data family T a
+ data instance T Int = MkT
+ data Proxy (a :: k)
+ data S = MkS (Proxy 'MkT)
+
+Is it ok to use the promoted data family instance constructor 'MkT' in
+the data declaration for S? No, we don't allow this. It *might* make
+sense, but at least it would mean that we'd have to interleave
+typechecking instances and data types, whereas at present we do data
+types *then* instances.
+
+So to check for this we put in the TcLclEnv a binding for all the family
+constructors, bound to AFamDataCon, so that if we trip over 'MkT' when
+type checking 'S' we'll produce a decent error message.
+
%************************************************************************
%* *
diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index d17d3e6a10..8f1bc76222 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -578,27 +578,11 @@ data TcTyThing
-- Can be a mono-kind or a poly-kind; in TcTyClsDcls see
-- Note [Type checking recursive type and class declarations]
- | ANothing -- see Note [ANothing]
-
-{-
-Note [ANothing]
-~~~~~~~~~~~~~~~
-
-We don't want to allow promotion in a strongly connected component
-when kind checking.
-
-Consider:
- data T f = K (f (K Any))
-
-When kind checking the `data T' declaration the local env contains the
-mappings:
- T -> AThing <some initial kind>
- K -> ANothing
-
-ANothing is only used for DataCons, and only used during type checking
-in tcTyClGroup.
--}
+ | AFamDataCon -- Data constructor for a data family
+ -- See Note [AFamDataCon: not promoting data family constructors] in TcRnDriver
+ | ARecDataCon -- Data constructor in a reuursive loop
+ -- See Note [ARecDataCon: recusion and promoting data constructors] in TcTyClsDecls
instance Outputable TcTyThing where -- Debugging only
ppr (AGlobal g) = pprTyThing g
@@ -609,16 +593,19 @@ instance Outputable TcTyThing where -- Debugging only
<+> ppr (tct_level elt))
ppr (ATyVar tv _) = text "Type variable" <+> quotes (ppr tv)
ppr (AThing k) = text "AThing" <+> ppr k
- ppr ANothing = text "ANothing"
+ ppr AFamDataCon = text "AFamDataCon"
+ ppr ARecDataCon = text "ARecDataCon"
pprTcTyThingCategory :: TcTyThing -> SDoc
pprTcTyThingCategory (AGlobal thing) = pprTyThingCategory thing
pprTcTyThingCategory (ATyVar {}) = ptext (sLit "Type variable")
pprTcTyThingCategory (ATcId {}) = ptext (sLit "Local identifier")
pprTcTyThingCategory (AThing {}) = ptext (sLit "Kinded thing")
-pprTcTyThingCategory ANothing = ptext (sLit "Opaque thing")
+pprTcTyThingCategory AFamDataCon = ptext (sLit "Family data con")
+pprTcTyThingCategory ARecDataCon = ptext (sLit "Recursive data con")
\end{code}
+
Note [Bindings with closed types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
diff --git a/compiler/typecheck/TcSplice.lhs b/compiler/typecheck/TcSplice.lhs
index 968be0765e..1bdc0bf5a5 100644
--- a/compiler/typecheck/TcSplice.lhs
+++ b/compiler/typecheck/TcSplice.lhs
@@ -1188,8 +1188,7 @@ reifyThing (ATyVar tv tv1)
; ty2 <- reifyType ty1
; return (TH.TyVarI (reifyName tv) ty2) }
-reifyThing (AThing {}) = panic "reifyThing AThing"
-reifyThing ANothing = panic "reifyThing ANothing"
+reifyThing thing = pprPanic "reifyThing" (pprTcTyThingCategory thing)
------------------------------
reifyAxiom :: CoAxiom -> TcM TH.Info
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index 3db2423999..1cef0f734b 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -104,7 +104,7 @@ tcTyAndClassDecls :: ModDetails
tcTyAndClassDecls boot_details tyclds_s
= checkNoErrs $ -- The code recovers internally, but if anything gave rise to
-- an error we'd better stop now, to avoid a cascade
- fold_env tyclds_s -- type check each group in dependency order folding the global env
+ fold_env tyclds_s -- Type check each group in dependency order folding the global env
where
fold_env :: [TyClGroup Name] -> TcM TcGblEnv
fold_env [] = getGblEnv
@@ -268,8 +268,9 @@ kcTyClGroup decls
-- Step 1: Bind kind variables for non-synonyms
; let (syn_decls, non_syn_decls) = partition (isSynDecl . unLoc) decls
- ; initial_kinds <- concatMapM getInitialKinds non_syn_decls
+ ; initial_kinds <- getInitialKinds TopLevel non_syn_decls
+ ; traceTc "kcTyClGroup: initial kinds" (ppr initial_kinds)
; tcl_env <- tcExtendTcTyThingEnv initial_kinds $ do
do { -- Step 2: kind-check the synonyms, and extend envt
tcl_env <- kcSynDecls (calcSynCycles syn_decls)
@@ -288,6 +289,7 @@ kcTyClGroup decls
where
generalise :: TcTypeEnv -> Name -> TcM (Name, Kind)
+ -- For polymorphic things this is a no-op
generalise kind_env name
= do { traceTc "Generalise type of" (ppr name)
; let kc_kind = case lookupNameEnv kind_env name of
@@ -297,7 +299,10 @@ kcTyClGroup decls
; kc_kind' <- zonkTcKind kc_kind
; return (name, mkForAllTys kvs kc_kind') }
-getInitialKinds :: LTyClDecl Name -> TcM [(Name, TcTyThing)]
+getInitialKinds :: TopLevelFlag -> [LTyClDecl Name] -> TcM [(Name, TcTyThing)]
+getInitialKinds top_lvl = concatMapM (addLocM (getInitialKind top_lvl))
+
+getInitialKind :: TopLevelFlag -> TyClDecl Name -> TcM [(Name, TcTyThing)]
-- Allocate a fresh kind variable for each TyCon and Class
-- For each tycon, return (tc, AThing k)
-- where k is the kind of tc, derived from the LHS
@@ -311,35 +316,54 @@ getInitialKinds :: LTyClDecl Name -> TcM [(Name, TcTyThing)]
--
-- No family instances are passed to getInitialKinds
-getInitialKinds (L _ decl)
- = do { arg_kinds <- mapM (\_ -> newMetaKindVar) (get_tvs decl)
- ; res_kind <- get_res_kind decl
- ; let main_pair = (tcdName decl, AThing (mkArrowKinds arg_kinds res_kind))
- ; inner_pairs <- get_inner_kinds decl
- ; return (main_pair : inner_pairs) }
- where
- get_inner_kinds :: TyClDecl Name -> TcM [(Name,TcTyThing)]
- get_inner_kinds (TyDecl { tcdTyDefn = TyData { td_cons = cons } })
- = return [ (unLoc (con_name con), ANothing) | L _ con <- cons ]
- get_inner_kinds (ClassDecl { tcdATs = ats })
- = concatMapM getInitialKinds ats
- get_inner_kinds _
- = return []
-
- get_res_kind (ClassDecl {}) = return constraintKind
- get_res_kind (TyDecl { tcdTyDefn = TyData { td_kindSig = Nothing } })
- = return liftedTypeKind
- get_res_kind _ = newMetaKindVar
- -- Warning: you might be tempted to return * for all data decls
- -- but on GADT-style declarations we allow a kind signature
- -- data T :: *->* where { ... }
- -- with *no* tvs in the HsTyDefn
-
- get_tvs (TyFamily {tcdTyVars = tvs}) = hsQTvBndrs tvs
- get_tvs (ClassDecl {tcdTyVars = tvs}) = hsQTvBndrs tvs
- get_tvs (TyDecl {tcdTyVars = tvs}) = hsQTvBndrs tvs
- get_tvs (ForeignType {}) = []
+getInitialKind top_lvl (TyFamily { tcdLName = L _ name, tcdTyVars = ktvs, tcdKindSig = ksig })
+ | isTopLevel top_lvl
+ = kcHsTyVarBndrs True ktvs $ \ arg_kinds ->
+ do { res_k <- case ksig of
+ Just k -> tcLHsKind k
+ Nothing -> return liftedTypeKind
+ ; let body_kind = mkArrowKinds arg_kinds res_k
+ kvs = varSetElems (tyVarsOfType body_kind)
+ ; return [ (name, AThing (mkForAllTys kvs body_kind)) ] }
+
+ | otherwise
+ = kcHsTyVarBndrs False ktvs $ \ arg_kinds ->
+ do { res_k <- case ksig of
+ Just k -> tcLHsKind k
+ Nothing -> newMetaKindVar
+ ; return [ (name, AThing (mkArrowKinds arg_kinds res_k)) ] }
+
+getInitialKind _ (ClassDecl { tcdLName = L _ name, tcdTyVars = ktvs, tcdATs = ats })
+ = kcHsTyVarBndrs False ktvs $ \ arg_kinds ->
+ do { inner_prs <- getInitialKinds NotTopLevel ats
+ ; let main_pr = (name, AThing (mkArrowKinds arg_kinds constraintKind))
+ ; return (main_pr : inner_prs) }
+
+getInitialKind top_lvl decl@(TyDecl { tcdLName = L _ name, tcdTyVars = ktvs, tcdTyDefn = defn })
+ | TyData { td_kindSig = Just ksig, td_cons = cons } <- defn
+ = ASSERT( isTopLevel top_lvl )
+ kcHsTyVarBndrs True ktvs $ \ arg_kinds ->
+ do { res_k <- tcLHsKind ksig
+ ; let body_kind = mkArrowKinds arg_kinds res_k
+ kvs = varSetElems (tyVarsOfType body_kind)
+ main_pr = (name, AThing (mkForAllTys kvs body_kind))
+ inner_prs = [(unLoc (con_name con), ARecDataCon) | L _ con <- cons ]
+ -- See Note [ARecDataCon: Recusion and promoting data constructors]
+ ; return (main_pr : inner_prs) }
+ | TyData { td_cons = cons } <- defn
+ = kcHsTyVarBndrs False ktvs $ \ arg_kinds ->
+ do { let main_pr = (name, AThing (mkArrowKinds arg_kinds liftedTypeKind))
+ inner_prs = [(unLoc (con_name con), ARecDataCon) | L _ con <- cons ]
+ -- See Note [ARecDataCon: Recusion and promoting data constructors]
+ ; return (main_pr : inner_prs) }
+
+ | otherwise = pprPanic "getInitialKind" (ppr decl)
+
+getInitialKind _ (ForeignType { tcdLName = L _ name })
+ = return [(name, AThing liftedTypeKind)]
+
+
----------------
kcSynDecls :: [SCC (LTyClDecl Name)] -> TcM TcLclEnv -- Kind bindings
kcSynDecls [] = getLclEnv
@@ -347,7 +371,6 @@ kcSynDecls (group : groups)
= do { nk <- kcSynDecl1 group
; tcExtendKindEnv [nk] (kcSynDecls groups) }
-----------------
kcSynDecl1 :: SCC (LTyClDecl Name)
-> TcM (Name,TcKind) -- Kind bindings
kcSynDecl1 (AcyclicSCC (L _ decl)) = kcSynDecl decl
@@ -358,15 +381,14 @@ kcSynDecl1 (CyclicSCC decls) = do { recSynErr decls; failM }
kcSynDecl :: TyClDecl Name -> TcM (Name, TcKind)
kcSynDecl decl@(TyDecl { tcdTyVars = hs_tvs, tcdLName = L _ name
, tcdTyDefn = TySynonym { td_synRhs = rhs } })
- -- Vanilla type synonyoms only, not family instances
-- Returns a possibly-unzonked kind
= tcAddDeclCtxt decl $
- tcHsTyVarBndrs hs_tvs $ \ k_tvs ->
+ kcHsTyVarBndrs False hs_tvs $ \ ks ->
do { traceTc "kcd1" (ppr name <+> brackets (ppr hs_tvs)
- <+> brackets (ppr k_tvs))
+ <+> brackets (ppr ks))
; (_, rhs_kind) <- tcLHsType rhs
; traceTc "kcd2" (ppr name)
- ; let tc_kind = foldr (mkArrowKind . tyVarKind) rhs_kind k_tvs
+ ; let tc_kind = mkArrowKinds ks rhs_kind
; return (name, tc_kind) }
kcSynDecl decl = pprPanic "kcSynDecl" (ppr decl)
@@ -379,14 +401,21 @@ kcLTyClDecl (L loc decl)
kcTyClDecl :: TyClDecl Name -> TcM ()
-- This function is used solely for its side effect on kind variables
-kcTyClDecl (TyDecl { tcdLName = L _ name, tcdTyVars = hs_tvs, tcdTyDefn = defn })
- = kcTyClTyVars name hs_tvs $ \ res_k -> kcTyDefn defn res_k
+kcTyClDecl decl@(TyDecl { tcdLName = L _ name, tcdTyVars = hs_tvs, tcdTyDefn = defn })
+ | TyData { td_cons = cons, td_kindSig = Just _ } <- defn
+ = mapM_ (wrapLocM kcConDecl) cons -- Ignore the td_ctxt; heavily deprecated and inconvenient
+
+ | TyData { td_ctxt = ctxt, td_cons = cons } <- defn
+ = kcTyClTyVars name hs_tvs $ \ _res_k ->
+ do { _ <- tcHsContext ctxt
+ ; mapM_ (wrapLocM kcConDecl) cons }
+
+ | otherwise = pprPanic "kcTyClDecl" (ppr decl)
kcTyClDecl (ClassDecl { tcdLName = L _ name, tcdTyVars = hs_tvs
, tcdCtxt = ctxt, tcdSigs = sigs, tcdATs = ats})
- = kcTyClTyVars name hs_tvs $ \ res_k ->
+ = kcTyClTyVars name hs_tvs $ \ _res_k ->
do { _ <- tcHsContext ctxt
- ; _ <- unifyKind res_k constraintKind
; mapM_ (wrapLocM kcTyClDecl) ats
; mapM_ (wrapLocM kc_sig) sigs }
where
@@ -394,53 +423,37 @@ kcTyClDecl (ClassDecl { tcdLName = L _ name, tcdTyVars = hs_tvs
kc_sig (GenericSig _ op_ty) = discardResult (tcHsLiftedType op_ty)
kc_sig _ = return ()
-kcTyClDecl (ForeignType {}) = return ()
-
-kcTyClDecl (TyFamily { tcdLName = L _ name, tcdTyVars = hs_tvs
- , tcdKindSig = mb_kind})
- = kcTyClTyVars name hs_tvs $ \res_k -> kcResultKind mb_kind res_k
-
--------------------
--- Kind check a data declaration, assuming that we already extended the
--- kind environment with the type variables of the left-hand side (these
--- kinded type variables are also passed as the second parameter).
-kcTyDefn :: HsTyDefn Name -> Kind -> TcM ()
-kcTyDefn (TyData { td_ND = new_or_data, td_ctxt = ctxt
- , td_cons = cons, td_kindSig = mb_kind }) res_k
- = do { traceTc "kcTyDefn1" (ppr cons)
- ; _ <- tcHsContext ctxt
--- ; let h98_syntax = consUseH98Syntax cons
--- ; when h98_syntax $ mapM_ (wrapLocM (kcConDecl new_or_data)) cons
- ; mapM_ (wrapLocM (kcConDecl new_or_data)) cons
- ; traceTc "kcTyDefn2" (ppr cons)
- ; kcResultKind mb_kind res_k
- ; traceTc "kcTyDefn3" (ppr cons)
- }
-kcTyDefn (TySynonym { td_synRhs = rhs_ty }) res_k
- = discardResult (tcCheckLHsType rhs_ty res_k)
+kcTyClDecl (ForeignType {}) = return ()
+kcTyClDecl (TyFamily {}) = return ()
-------------------
-kcConDecl :: NewOrData -> ConDecl Name -> TcM ()
-kcConDecl new_or_data (ConDecl { con_name = name, con_qvars = ex_tvs
- , con_cxt = ex_ctxt, con_details = details, con_res = res })
+kcConDecl :: ConDecl Name -> TcM ()
+kcConDecl (ConDecl { con_name = name, con_qvars = ex_tvs
+ , con_cxt = ex_ctxt, con_details = details, con_res = res })
= addErrCtxt (dataConCtxt name) $
- tcHsTyVarBndrs ex_tvs $ \ _ ->
+ kcHsTyVarBndrs False ex_tvs $ \ _ ->
do { _ <- tcHsContext ex_ctxt
- ; mapM_ (tcHsConArgType new_or_data) (hsConDeclArgTys details)
+ ; mapM_ (tcHsArgType . getBangType) (hsConDeclArgTys details)
; _ <- tcConRes res
; return () }
-
-------------------
-kcResultKind :: Maybe (LHsKind Name) -> Kind -> TcM ()
-kcResultKind Nothing res_k
- = discardResult (unifyKind res_k liftedTypeKind)
- -- type family F a
- -- defaults to type family F a :: *
-kcResultKind (Just k ) res_k
- = do { k' <- tcLHsKind k
- ; discardResult (unifyKind k' res_k) }
\end{code}
+Note [ARecDataCon: Recusion and promoting data constructors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We don't want to allow promotion in a strongly connected component
+when kind checking.
+
+Consider:
+ data T f = K (f (K Any))
+
+When kind checking the `data T' declaration the local env contains the
+mappings:
+ T -> AThing <some initial kind>
+ K -> ARecDataCon
+
+ANothing is only used for DataCons, and only used during type checking
+in tcTyClGroup.
+
%************************************************************************
%* *
@@ -713,6 +726,27 @@ tcSynFamInstDecl fam_tc
tcSynFamInstDecl _ decl = pprPanic "tcSynFamInstDecl" (ppr decl)
+kcTyDefn :: HsTyDefn Name -> TcKind -> TcM ()
+-- Used for 'data instance' and 'type instance' only
+-- Ordinary 'data' and 'type' are handed by kcTyClDec and kcSynDecls resp
+kcTyDefn (TyData { td_ctxt = ctxt, td_cons = cons, td_kindSig = mb_kind }) res_k
+ = do { _ <- tcHsContext ctxt
+ ; mapM_ (wrapLocM kcConDecl) cons
+ ; kcResultKind mb_kind res_k }
+
+kcTyDefn (TySynonym { td_synRhs = rhs_ty }) res_k
+ = discardResult (tcCheckLHsType rhs_ty res_k)
+
+------------------
+kcResultKind :: Maybe (LHsKind Name) -> Kind -> TcM ()
+kcResultKind Nothing res_k
+ = discardResult (unifyKind res_k liftedTypeKind)
+ -- type family F a
+ -- defaults to type family F a :: *
+kcResultKind (Just k ) res_k
+ = do { k' <- tcLHsKind k
+ ; discardResult (unifyKind k' res_k) }
+
-------------------------
-- Kind check type patterns and kind annotate the embedded type variables.
-- type instance F [a] = rhs
@@ -1343,10 +1377,8 @@ checkValidDataCon tc con
; mapM_ check_bang (dataConStrictMarks con `zip` [1..])
- ; ASSERT2( not (any (isKindVar . fst) (dataConEqSpec con)),
- ppr con $$ ppr (dataConEqSpec con) )
- -- We don't support kind equalities, and shoud not be any
- return ()
+ ; checkTc (not (any (isKindVar . fst) (dataConEqSpec con)))
+ (badGadtKindCon con)
; traceTc "Done validity of data con" (ppr con <+> ppr (dataConRepType con))
}
@@ -1754,6 +1786,12 @@ badDataConTyCon data_con res_ty_tmpl actual_res_ty
ptext (sLit "returns type") <+> quotes (ppr actual_res_ty))
2 (ptext (sLit "instead of an instance of its parent type") <+> quotes (ppr res_ty_tmpl))
+badGadtKindCon :: DataCon -> SDoc
+badGadtKindCon data_con
+ = hang (ptext (sLit "Data constructor") <+> quotes (ppr data_con)
+ <+> ptext (sLit "cannot be GADT-like in its *kind* arguments"))
+ 2 (ppr data_con <+> dcolon <+> ppr (dataConUserType data_con))
+
badATErr :: Name -> Name -> SDoc
badATErr clas op
= hsep [ptext (sLit "Class"), quotes (ppr clas),
diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml
index b501961b4e..be67da9f3b 100644
--- a/docs/users_guide/flags.xml
+++ b/docs/users_guide/flags.xml
@@ -834,13 +834,14 @@
</row>
<row>
<entry><option>-XDataKinds</option></entry>
- <entry>Enable <link linkend="kind-polymorphism-and-promotion">datatype promotion</link>.</entry>
+ <entry>Enable <link linkend="promotion">datatype promotion</link>.</entry>
<entry>dynamic</entry>
<entry><option>-XNoDataKinds</option></entry>
</row>
<row>
<entry><option>-XPolyKinds</option></entry>
- <entry>Enable <link linkend="kind-polymorphism-and-promotion">kind polymorphism</link>.</entry>
+ <entry>Enable <link linkend="kind-polymorphism">kind polymorphism</link>.
+ Implies <option>-XKindSignatures</option>.</entry>
<entry>dynamic</entry>
<entry><option>-XNoPolyKinds</option></entry>
</row>
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 6681448c2c..b65891a108 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -5154,60 +5154,19 @@ instance Show v => Show (GMap () v) where ...
</sect1>
-<sect1 id="kind-polymorphism-and-promotion">
-<title>Kind polymorphism and promotion</title>
-
-<para>
-Standard Haskell has a rich type language. Types classify terms and serve to
-avoid many common programming mistakes. The kind language, however, is
-relatively simple, distinguishing only lifted types (kind <literal>*</literal>),
-type constructors (eg. kind <literal>* -> * -> *</literal>), and unlifted
-types (<xref linkend="glasgow-unboxed"/>). In particular when using advanced
-type system features, such as type families (<xref linkend="type-families"/>)
-or GADTs (<xref linkend="gadt"/>), this simple kind system is insufficient,
-and fails to prevent simple errors. Consider the example of type-level natural
-numbers, and length-indexed vectors:
-<programlisting>
-data Ze
-data Su n
-
-data Vec :: * -> * -> * where
- Nil :: Vec a Ze
- Cons :: a -> Vec a n -> Vec a (Su n)
-</programlisting>
-The kind of <literal>Vec</literal> is <literal>* -> * -> *</literal>. This means
-that eg. <literal>Vec Int Char</literal> is a well-kinded type, even though this
-is not what we intend when defining length-indexed vectors.
-</para>
-
-<para>
-With the flags <option>-XPolyKinds</option> and <option>-XDataKinds</option>,
-users get access to a richer kind language.
-<option>-XPolyKinds</option> enables kind polymorphism, while
-<option>-XDataKinds</option> enables user defined kinds through datatype
-promotion. With <option>-XDataKinds</option>, the example above can then be
-rewritten to:
-<programlisting>
-data Nat = Ze | Su Nat
-
-data Vec :: * -> Nat -> * where
- Nil :: Vec a Ze
- Cons :: a -> Vec a n -> Vec a (Su n)
-</programlisting>
-With the improved kind of <literal>Vec</literal>, things like
-<literal>Vec Int Char</literal> are now ill-kinded, and GHC will report an
-error.
-</para>
+<sect1 id="kind-polymorphism">
+<title>Kind polymorphism</title>
<para>
-In this section we show a few examples of how to make use of the new kind
-system. This extension is described in more detail in the paper
+This section describes <emphasis>kind polymorphism</emphasis>, and extension
+enabled by <option>-XPolyKinds</option>.
+It is described in more detail in the paper
<ulink url="http://dreixel.net/research/pdf/ghp.pdf">Giving Haskell a
Promotion</ulink>, which appeared at TLDI 2012.
</para>
-<sect2 id="kind-polymorphism">
-<title>Kind polymorphism</title>
+<sect2> <title>Overview of kind polymorphism</title>
+
<para>
Currently there is a lot of code duplication in the way Typeable is implemented
(<xref linkend="deriving-typeable"/>):
@@ -5240,34 +5199,148 @@ Note that the datatype <literal>Proxy</literal> has kind
<literal>Typeable</literal> class has kind
<literal>forall k. k -> Constraint</literal>.
</para>
+</sect2>
+
+<sect2> <title>Overview</title>
+
+<para>
+Generally speaking, with <option>-XPolyKinds</option>, GHC will infer a polymorphic
+kind for un-decorated whenever possible. For example:
+<programlisting>
+data T m a = MkT (m a)
+-- GHC infers kind T :: forall k. (k -> *) -> k -> *
+</programlisting>
+Just as in the world of terms, you can restrict polymorphism using a signature
+(<option>-XPolyKinds</option> implies <option>-XKindSignatures</option>):
+<programlisting>
+data T m (a :: *) = MkT (m a)
+-- GHC now infers kind T :: (* -> *) -> * -> *
+</programlisting>
+There is no "forall" for kind variables. Instead, you can simply mention a kind
+variable in a kind signature, thus:
+<programlisting>
+data T (m :: k -> *) a = MkT (m a)
+-- GHC now infers kind T :: forall k. (k -> *) -> k -> *
+</programlisting>
+</para>
+</sect2>
+
+<sect2> <title>Polymorphic kind recursion and complete kind signatures</title>
+
+<para>
+Just as in type inference, kind inference for recursive types can only use <emphasis>monomorphic</emphasis> recursion.
+Consider this (contrived) example:
+<programlisting>
+data T m a = MkT (m a) (T Maybe (m a))
+-- GHC infers kind T :: (* -> *) -> * -> *
+</programlisting>
+The recursive use of <literal>T</literal> forced the second argument to have kind <literal>*</literal>.
+However, just as in type inference, you can achieve polymorphic recursion by giving a
+<emphasis>complete kind signature</emphasis> for <literal>T</literal>. The way to give
+a complete kind signature for a data type is to use a GADT-style declaration with an
+explicit kind signature thus:
+<programlisting>
+data T :: (k -> *) -> k -> * where
+ MkT :: m a -> T Maybe (m a) -> T m a
+</programlisting>
+The complete user-supplied kind signature specifies the polymorphic kind for <literal>T</literal>,
+and this signature is used for all the calls to <literal>T</literal> including the recursive ones.
+In particular, the recursive use of <literal>T</literal> is at kind <literal>*</literal>.
+</para>
<para>
-There are some restrictions in the current implementation:
+What exactly is considered to be a "complete user-supplied kind signature" for a type constructor?
+These are the forms:
<itemizedlist>
- <listitem><para>You cannot (yet) explicitly abstract over kinds, or mention
- kind variables. So the following are all rejected:
+<listitem><para>
+A GADT-style data type declaration, with an explicit "<literal>::</literal>" in the header.
+For example:
<programlisting>
-data D1 (t :: k)
+data T1 :: (k -> *) -> k -> * where ... -- Yes T1 :: forall k. (k->*) -> k -> *
+data T2 (a :: k -> *) :: k -> * where ... -- Yes T2 :: forall k. (k->*) -> k -> *
+data T3 (a :: k -> *) (b :: k) :: * where ... -- Yes T3 :: forall k. (k->*) -> k -> *
+data T4 a (b :: k) :: * where ... -- YES T4 :: forall k. * -> k -> *
-data D2 :: k -> *
+data T5 a b where ... -- NO kind is inferred
+data T4 (a :: k -> *) (b :: k) where ... -- NO kind is inferred
+</programlisting>
+It makes no difference where you put the "<literal>::</literal>" but it must be there.
+You cannot give a complete kind signature using a Haskell-98-style data type declaration;
+you must use GADT syntax.
+</para></listitem>
-data D3 (k :: BOX)
-</programlisting></para>
- </listitem>
- <listitem><para>The return kind of a type family is always defaulted to
- <literal>*</literal>. So the following is rejected:
+<listitem><para>
+A type or data family declaration <emphasis>always</emphasis> have a
+complete user-specified kind signature; no "<literal>::</literal>" is required:
<programlisting>
-type family F a
-type instance F Int = Maybe
-</programlisting></para>
- </listitem>
+data family D1 a -- D1 :: * -> *
+data family D2 (a :: k) -- D2 :: forall k. k -> *
+data family D3 (a :: k) :: * -- D3 :: forall k. k -> *
+type family S1 a :: k -> * -- S1 :: forall k. * -> k -> *
+</programlisting>
+</para></listitem>
</itemizedlist>
+In a complete user-specified kind signature, any un-decorated type variable to the
+left of the "<literal>::</literal>" is considered to have kind "<literal>*</literal>".
+If you want kind polymorphism, specify a kind variable.
</para>
</sect2>
+</sect1>
-<sect2 id="promotion">
+<sect1 id="promotion">
<title>Datatype promotion</title>
+
+<para>
+This section describes <emphasis>data type promotion</emphasis>, an extension
+to the kind system that complements kind polymorphism. It is enabled by <option>-XDataKinds</option>,
+and described in more detail in the paper
+<ulink url="http://dreixel.net/research/pdf/ghp.pdf">Giving Haskell a
+Promotion</ulink>, which appeared at TLDI 2012.
+</para>
+
+<sect2> <title>Motivation</title>
+
+<para>
+Standard Haskell has a rich type language. Types classify terms and serve to
+avoid many common programming mistakes. The kind language, however, is
+relatively simple, distinguishing only lifted types (kind <literal>*</literal>),
+type constructors (eg. kind <literal>* -> * -> *</literal>), and unlifted
+types (<xref linkend="glasgow-unboxed"/>). In particular when using advanced
+type system features, such as type families (<xref linkend="type-families"/>)
+or GADTs (<xref linkend="gadt"/>), this simple kind system is insufficient,
+and fails to prevent simple errors. Consider the example of type-level natural
+numbers, and length-indexed vectors:
+<programlisting>
+data Ze
+data Su n
+
+data Vec :: * -> * -> * where
+ Nil :: Vec a Ze
+ Cons :: a -> Vec a n -> Vec a (Su n)
+</programlisting>
+The kind of <literal>Vec</literal> is <literal>* -> * -> *</literal>. This means
+that eg. <literal>Vec Int Char</literal> is a well-kinded type, even though this
+is not what we intend when defining length-indexed vectors.
+</para>
+
+<para>
+With <option>-XDataKinds</option>, the example above can then be
+rewritten to:
+<programlisting>
+data Nat = Ze | Su Nat
+
+data Vec :: * -> Nat -> * where
+ Nil :: Vec a Ze
+ Cons :: a -> Vec a n -> Vec a (Su n)
+</programlisting>
+With the improved kind of <literal>Vec</literal>, things like
+<literal>Vec Int Char</literal> are now ill-kinded, and GHC will report an
+error.
+</para>
+</sect2>
+
+<sect2><title>Overview</title>
<para>
With <option>-XDataKinds</option>, GHC automatically promotes every suitable
datatype to be a kind, and its (value) constructors to be type constructors.
@@ -5315,10 +5388,13 @@ The following restrictions apply to promotion:
<listitem><para>We do not promote datatypes whose constructors are kind
polymorphic, involve constraints, or use existential quantification.
</para></listitem>
+ <listitem><para>We do not promote data family instances (<xref linkend="data-families"/>).
+ </para></listitem>
</itemizedlist>
</para>
+</sect2>
-<sect3 id="promotion-syntax">
+<sect2 id="promotion-syntax">
<title>Distinguishing between types and constructors</title>
<para>
Since constructors and types share the same namespace, with promotion you can
@@ -5343,9 +5419,9 @@ ambiguous, we do not allow quotes in kind names.
<para>Just as in the case of Template Haskell (<xref linkend="th-syntax"/>), there is
no way to quote a data constructor or type constructor whose second character
is a single quote.</para>
-</sect3>
+</sect2>
-<sect3 id="promoted-lists-and-tuples">
+<sect2 id="promoted-lists-and-tuples">
<title>Promoted lists and tuples types</title>
<para>
Haskell's list and tuple types are natively promoted to kinds, and enjoy the
@@ -5360,9 +5436,9 @@ data Tuple :: (*,*) -> * where
</programlisting>
Note that this requires <option>-XTypeOperators</option>.
</para>
-</sect3>
+</sect2>
-<sect3 id="promoted-literals">
+<sect2 id="promoted-literals">
<title>Promoted Literals</title>
<para>
Numeric and string literals are prmoted to the type level, giving convenient
@@ -5404,25 +5480,11 @@ instance Has Point "y" Int where from (Point _ y) _ = y
example = from (Point 1 2) (Get :: Label "x")
</programlisting>
</para>
-</sect3>
-
-
-
-</sect2>
-
-<sect2 id="kind-polymorphism-limitations">
-<title>Shortcomings of the current implementation</title>
-<para>
-For the release on GHC 7.4 we focused on getting the new kind-polymorphic core
-to work with all existing programs (which do not make use of kind polymorphism).
-Many things already work properly with <option>-XPolyKinds</option>, but we
-expect that some things will not work. If you run into trouble, please
-<link linkend="bug-reporting">report a bug</link>!
-</para>
</sect2>
</sect1>
+
<sect1 id="equality-constraints">
<title>Equality constraints</title>
<para>