Repository : ssh://darcs.haskell.org//srv/darcs/ghc On branch : ghc-kinds
http://hackage.haskell.org/trac/ghc/changeset/d51c28d02777dee753552a16ba355493877fdb05 >--------------------------------------------------------------- commit d51c28d02777dee753552a16ba355493877fdb05 Author: Julien Cretin <g...@ia0.eu> Date: Wed Sep 14 20:02:30 2011 +0200 kind coercions >--------------------------------------------------------------- compiler/basicTypes/Var.lhs | 5 ++- compiler/coreSyn/CoreLint.lhs | 64 ++++++++++++++++++++++++++++++++------- compiler/typecheck/TcMType.lhs | 10 +++--- compiler/types/Kind.lhs | 7 ++++ 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/compiler/basicTypes/Var.lhs b/compiler/basicTypes/Var.lhs index 232c4d3..b026728 100644 --- a/compiler/basicTypes/Var.lhs +++ b/compiler/basicTypes/Var.lhs @@ -59,7 +59,7 @@ module Var ( tyVarName, tyVarKind, tcTyVarDetails, setTcTyVarDetails, -- ** Modifying 'TyVar's - setTyVarName, setTyVarUnique, setTyVarKind + setTyVarName, setTyVarUnique, setTyVarKind, updateTyVarKind ) where @@ -268,6 +268,9 @@ setTyVarName = setVarName setTyVarKind :: TyVar -> Kind -> TyVar setTyVarKind tv k = tv {varType = k} + +updateTyVarKind :: (Kind -> Kind) -> TyVar -> TyVar +updateTyVarKind update tv = tv {varType = update (tyVarKind tv)} \end{code} \begin{code} diff --git a/compiler/coreSyn/CoreLint.lhs b/compiler/coreSyn/CoreLint.lhs index e44b9b1..5e2fede 100644 --- a/compiler/coreSyn/CoreLint.lhs +++ b/compiler/coreSyn/CoreLint.lhs @@ -356,6 +356,27 @@ lintCoreExpr (Coercion co) ; return (mkCoercionType ty1 ty2) } \end{code} +Note [Kind instantiation in coercions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider the following coercion axiom: + ax_co [(k_ag :: BOX), (f_aa :: k_ag -> Constraint)] :: T k_ag f_aa ~ f_aa + +Consider the following instantiation: + ax_co <(* -> * :: BOX)> <Monad> + +We need to split the co_ax_tvs into kind and type variables in order +to find out the coercion kind instantiations. Those can only be Refl +since we don't have kind coercions. This is just a way to represent +kind instantiation. + +We use the number of kind variables to know how to split the coercions +instantiations between kind coercions and type coercions. We lint the +kind coercions and produce the following substitution which is to be +applied in the type variables: + k_ag |-> * -> * + + %************************************************************************ %* * \subsection[lintCoreArgs]{lintCoreArgs} @@ -447,6 +468,16 @@ checkTyCoKind tv co checkTyCoKinds :: [TyVar] -> [OutCoercion] -> LintM [(OutType, OutType)] checkTyCoKinds = zipWithM checkTyCoKind +checkKiCoKind :: KindVar -> OutCoercion -> LintM Kind +-- see lintCoercion (AxiomInstCo {}) and Note [Kind instantiation in coercions] +checkKiCoKind kv co + = do { ki <- lintKindCoercion co + ; unless (isSuperKind (tyVarKind kv)) (addErrL (mkTyCoAppErrMsg kv co)) + ; return ki } + +checkKiCoKinds :: [KindVar] -> [OutCoercion] -> LintM [Kind] +checkKiCoKinds = zipWithM checkKiCoKind + checkDeadIdOcc :: Id -> LintM () -- Occurrences of an Id should never be dead.... -- except when we are checking a case pattern @@ -634,6 +665,8 @@ lintKind (FunTy k1 k2) = lintKind k1 >> lintKind k2 lintKind kind@(TyConApp tc kis) + | isSuperKind kind = panic "lintKind called with BOX" + | isSuperKind tc_kind -- handles *, #, Constraint, etc. , null kis = return () @@ -660,6 +693,13 @@ lintTyBndrKind tv = else lintKind ki ------------------- +lintKindCoercion :: Coercion -> LintM Kind +lintKindCoercion (Refl k) + = do { k' <- applySubstTy k + ; lintKind k' + ; return k' } +lintKindCoercion _ = panic "lintKindCoercion" + lintCoercion :: OutCoercion -> LintM (OutType, OutType) -- Check the kind of a coercion term, returning the kind lintCoercion (Refl ty) @@ -675,13 +715,6 @@ lintCoercion co@(TyConAppCo tc cos) ; (ss,ts) <- mapAndUnzipM lintCoercion cotys ; check_co_app co ki (kis ++ ss) ; return (mkTyConApp tc (kis ++ ss), mkTyConApp tc (kis ++ ts)) } - where - lintKindCoercion :: Coercion -> LintM Kind - lintKindCoercion (Refl k) = do - k' <- applySubstTy k - lintKind k' - return k' - lintKindCoercion _ = panic "lintCoercion lintKindCoercion" lintCoercion co@(AppCo co1 co2) = do { (s1,t1) <- lintCoercion co1 @@ -690,7 +723,8 @@ lintCoercion co@(AppCo co1 co2) ; return (mkAppTy s1 s2, mkAppTy t1 t2) } lintCoercion (ForAllCo v co) - = do { lintKind (tyVarKind v) + = do { let kind = tyVarKind v + ; unless (isSuperKind kind) (lintKind kind) ; (s,t) <- addInScopeVar v (lintCoercion co) ; return (ForAllTy v s, ForAllTy v t) } @@ -702,13 +736,19 @@ lintCoercion (CoVarCo cv) = do { checkTyCoVarInScope cv ; return (coVarKind cv) } -lintCoercion (AxiomInstCo (CoAxiom { co_ax_tvs = tvs +lintCoercion (AxiomInstCo (CoAxiom { co_ax_tvs = ktvs , co_ax_lhs = lhs , co_ax_rhs = rhs }) cos) - = do { (tys1, tys2) <- liftM unzip (checkTyCoKinds tvs cos) - ; return (substTyWith tvs tys1 lhs, - substTyWith tvs tys2 rhs) } + = do { kis <- checkKiCoKinds kvs kcos + ; let tvs' = map (updateTyVarKind (Type.substTy subst)) tvs + subst = zipOpenTvSubst kvs kis + ; (tys1, tys2) <- liftM unzip (checkTyCoKinds tvs' tcos) + ; return (substTyWith ktvs (kis ++ tys1) lhs, + substTyWith ktvs (kis ++ tys2) rhs) } + where -- see Note [Kind instantiation in coercions] + (kvs, tvs) = splitKiTyVars ktvs + (kcos, tcos) = splitAt (length kvs) cos lintCoercion (UnsafeCo ty1 ty2) = do { ty1' <- lintInTy ty1 diff --git a/compiler/typecheck/TcMType.lhs b/compiler/typecheck/TcMType.lhs index 8bd7ed6..81ff7e0 100644 --- a/compiler/typecheck/TcMType.lhs +++ b/compiler/typecheck/TcMType.lhs @@ -70,7 +70,7 @@ module TcMType ( import TypeRep import TcType import Type -import Kind( isSuperKind ) +import Kind import Class import TyCon import Var @@ -206,7 +206,7 @@ tcSuperSkolTyVars :: [TyVar] -> [TcTyVar] tcSuperSkolTyVars tyvars = kvs' ++ tvs' where - (kvs, tvs) = span (isSuperKind . tyVarKind) tyvars + (kvs, tvs) = splitKiTyVars tyvars kvs' = [ mkTcTyVar (tyVarName kv) (tyVarKind kv) superSkolemTv | kv <- kvs ] tvs' = [ mkTcTyVar (tyVarName tv) (substTy subst (tyVarKind tv)) superSkolemTv @@ -234,14 +234,14 @@ tcInstSkolTyVars tyvars = do { kvs' <- mapM (tcInstSkolTyVar False (mkTopTvSubst [])) kvs ; tvs' <- mapM (tcInstSkolTyVar False (zipTopTvSubst kvs (map mkTyVarTy kvs'))) tvs ; return (kvs' ++ tvs') } - where (kvs, tvs) = span (isSuperKind . tyVarKind) tyvars + where (kvs, tvs) = splitKiTyVars tyvars tcInstSuperSkolTyVars :: [TyVar] -> TcM [TcTyVar] tcInstSuperSkolTyVars tyvars = do { kvs' <- mapM (tcInstSkolTyVar True (mkTopTvSubst [])) kvs ; tvs' <- mapM (tcInstSkolTyVar True (zipTopTvSubst kvs (map mkTyVarTy kvs'))) tvs ; return (kvs' ++ tvs') } - where (kvs, tvs) = span (isSuperKind . tyVarKind) tyvars + where (kvs, tvs) = splitKiTyVars tyvars tcInstSkolType :: TcType -> TcM ([TcTyVar], TcThetaType, TcType) -- Instantiate a type with fresh skolem constants @@ -259,7 +259,7 @@ tcInstSigTyVars tyvars = do { kvs' <- mapM (tcInstSigTyVar (mkTopTvSubst [])) kvs ; tvs' <- mapM (tcInstSigTyVar (zipTopTvSubst kvs (map mkTyVarTy kvs'))) tvs ; return (kvs' ++ tvs') } - where (kvs, tvs) = span (isSuperKind . tyVarKind) tyvars + where (kvs, tvs) = splitKiTyVars tyvars tcInstSigTyVar :: TvSubst -> TyVar -> TcM TcTyVar tcInstSigTyVar subst tyvar diff --git a/compiler/types/Kind.lhs b/compiler/types/Kind.lhs index 2ca79ac..ed99492 100644 --- a/compiler/types/Kind.lhs +++ b/compiler/types/Kind.lhs @@ -34,6 +34,9 @@ module Kind ( isSubArgTypeKind, isSubOpenTypeKind, isSubKind, defaultKind, isSubKindCon, isSubOpenTypeKindCon, + -- ** Functions on variables + splitKiTyVars, + -- ** Promotion related functions promoteType, isPromotableType, isPromotableKind @@ -229,6 +232,10 @@ defaultKind k | isSubArgTypeKind k = liftedTypeKind | otherwise = k +splitKiTyVars :: [TyVar] -> ([KindVar], [TyVar]) +-- Assumes we get [k1, k2, a, b, c], returns ([k1, k2], [a, b, c]) +splitKiTyVars = span (isSuperKind . tyVarKind) + -- About promoting a type to a kind _______________________________________________ Cvs-ghc mailing list Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc