[commit: ghc] master: Apply the kind subst to the (kinds of the) quanitifed tyvars in deriveTyData (ffed708)
git at git.haskell.org
git at git.haskell.org
Sun Mar 23 18:49:41 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/ffed708c30f2d1d4b4c5cd08d9c19aeb0bb623ec/ghc
>---------------------------------------------------------------
commit ffed708c30f2d1d4b4c5cd08d9c19aeb0bb623ec
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Sat Mar 22 23:11:10 2014 +0000
Apply the kind subst to the (kinds of the) quanitifed tyvars in deriveTyData
I've elaboated Note [Unify kinds in deriving] to explain
what is going on here.
The change fixes Trac #8893.
>---------------------------------------------------------------
ffed708c30f2d1d4b4c5cd08d9c19aeb0bb623ec
compiler/typecheck/TcDeriv.lhs | 56 ++++++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 13 deletions(-)
diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs
index a89adda..4cec134 100644
--- a/compiler/typecheck/TcDeriv.lhs
+++ b/compiler/typecheck/TcDeriv.lhs
@@ -685,13 +685,19 @@ deriveTyData tvs tc tc_args (L loc deriv_pred)
tc_args_to_keep = take n_args_to_keep tc_args
inst_ty_kind = typeKind (mkTyConApp tc tc_args_to_keep)
dropped_tvs = tyVarsOfTypes args_to_drop
- mb_match = tcUnifyTy inst_ty_kind cls_arg_kind
- Just subst = mb_match -- See Note [Unify kinds in deriving]
- -- We are assuming the tycon tyvars and the class tyvars are distinct
- final_tc_args = substTys subst tc_args_to_keep
- final_cls_tys = substTys subst cls_tys
- univ_tvs = mkVarSet deriv_tvs `unionVarSet` tyVarsOfTypes final_tc_args
+ -- Match up the kinds, and apply the resulting kind substitution
+ -- to the types. See Note [Unify kinds in deriving]
+ -- We are assuming the tycon tyvars and the class tyvars are distinct
+ mb_match = tcUnifyTy inst_ty_kind cls_arg_kind
+ Just kind_subst = mb_match
+ (univ_kvs, univ_tvs) = partition isKindVar $ varSetElems $
+ mkVarSet deriv_tvs `unionVarSet`
+ tyVarsOfTypes tc_args_to_keep
+ univ_kvs' = filter (`notElemTvSubst` kind_subst) univ_kvs
+ (subst', univ_tvs') = mapAccumL substTyVarBndr kind_subst univ_tvs
+ final_tc_args = substTys subst' tc_args_to_keep
+ final_cls_tys = substTys subst' cls_tys
; traceTc "derivTyData1" (vcat [ pprTvBndrs tvs, ppr tc, ppr tc_args, ppr deriv_pred
, pprTvBndrs (varSetElems $ tyVarsOfTypes tc_args)
@@ -705,9 +711,9 @@ deriveTyData tvs tc tc_args (L loc deriv_pred)
; traceTc "derivTyData2" (vcat [ ppr univ_tvs ])
- ; checkTc (allDistinctTyVars args_to_drop && -- (a) and (b)
- univ_tvs `disjointVarSet` dropped_tvs) -- (c)
- (derivingEtaErr cls cls_tys (mkTyConApp tc final_tc_args))
+ ; checkTc (allDistinctTyVars args_to_drop && -- (a) and (b)
+ not (any (`elemVarSet` dropped_tvs) univ_tvs)) -- (c)
+ (derivingEtaErr cls final_cls_tys (mkTyConApp tc final_tc_args))
-- Check that
-- (a) The args to drop are all type variables; eg reject:
-- data instance T a Int = .... deriving( Monad )
@@ -719,7 +725,7 @@ deriveTyData tvs tc tc_args (L loc deriv_pred)
-- newtype T a s = ... deriving( ST s )
-- newtype K a a = ... deriving( Monad )
- ; mkEqnHelp (varSetElemsKvsFirst univ_tvs)
+ ; mkEqnHelp (univ_kvs' ++ univ_tvs')
cls final_cls_tys tc final_tc_args Nothing } }
derivePolyKindedTypeable :: Class -> [Type]
@@ -775,10 +781,34 @@ So we need to
kind arguments.
In the two examples,
- * we unify ( T k (a:k) ) ~ (* -> *) to find k:=*.
- * we unify ( Either ~ (k -> k -> k) ) to find k:=*.
+ * we unify kind-of( T k (a:k) ) ~ kind-of( Functor )
+ i.e. (k -> *) ~ (* -> *) to find k:=*.
+ yielding k:=*
+
+ * we unify kind-of( Either ) ~ kind-of( Category )
+ i.e. (* -> * -> *) ~ (k -> k -> k)
+ yielding k:=*
+
+Now we get a kind substition. We then need to:
+
+ 1. Remove the substituted-out kind variables from the quantifed kind vars
+
+ 2. Apply the substitution to the kinds of quantified *type* vars
+ (and extend the substitution to reflect this change)
+
+ 3. Apply that extended substitution to the non-dropped args (types and
+ kinds) of the type and class
+
+Forgetting step (2) caused Trac #8893:
+ data V a = V [a] deriving Functor
+ data P (x::k->*) (a:k) = P (x a) deriving Functor
+ data C (x::k->*) (a:k) = C (V (P x a)) deriving Functor
+
+When deriving Functor for P, we unify k to *, but we then want
+an instance $df :: forall (x:*->*). Functor x => Functor (P * (x:*->*))
+and similarly for C. Notice the modifed kind of x, both at binding
+and occurrence sites.
-Tricky stuff.
\begin{code}
mkEqnHelp :: [TyVar]
More information about the ghc-commits
mailing list