[commit: ghc] ghc-kinds: fix kind substitution in templates in tcResultType (923e459)
Julien Cretin
julien at galois.com
Fri Sep 16 10:27:33 CEST 2011
Repository : ssh://darcs.haskell.org//srv/darcs/ghc
On branch : ghc-kinds
http://hackage.haskell.org/trac/ghc/changeset/923e459416821c23ad72934f5e55546ad2d2a1c1
>---------------------------------------------------------------
commit 923e459416821c23ad72934f5e55546ad2d2a1c1
Author: Julien Cretin <ghc at ia0.eu>
Date: Tue Sep 13 17:08:18 2011 +0200
fix kind substitution in templates in tcResultType
>---------------------------------------------------------------
compiler/coreSyn/CoreLint.lhs | 3 ++
compiler/typecheck/TcTyClsDecls.lhs | 43 ++++++++++++++++++++++++++++++++++-
compiler/types/Type.lhs | 2 +-
3 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/compiler/coreSyn/CoreLint.lhs b/compiler/coreSyn/CoreLint.lhs
index fc7121b..fa167bb 100644
--- a/compiler/coreSyn/CoreLint.lhs
+++ b/compiler/coreSyn/CoreLint.lhs
@@ -418,10 +418,13 @@ lintValApp arg fun_ty arg_ty
checkTyKind :: OutTyVar -> OutType -> LintM ()
-- Both args have had substitution applied
checkTyKind tyvar arg_ty
+ | isSuperKind tyvar_kind -- kind forall
+ = lintKind arg_ty
-- Arg type might be boxed for a function with an uncommitted
-- tyvar; notably this is used so that we can give
-- error :: forall a:*. String -> a
-- and then apply it to both boxed and unboxed types.
+ | otherwise -- type forall
= do { arg_kind <- lintType arg_ty
; unless (arg_kind `isSubKind` tyvar_kind)
(addErrL (mkKindErrMsg tyvar arg_ty)) }
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index 3e28c81..3790d43 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -871,7 +871,10 @@ tcResultType (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
= case tcGetTyVar_maybe ty of
Just tv | not (tv `elem` univs)
-> (tv:univs, eqs)
- _other -> (tmpl:univs, (tmpl,ty):eqs)
+ _other -> (new_tmpl:univs, (new_tmpl,ty):eqs)
+ where -- see Note [Substitution in template variables kinds]
+ new_kind = substTy subst (tyVarKind tmpl)
+ new_tmpl = setTyVarKind tmpl new_kind
| otherwise = pprPanic "tcResultType" (ppr res_ty)
ex_tvs = dc_tvs `minusList` univ_tvs
@@ -889,6 +892,44 @@ tcResultType (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
name = tyVarName tv
(env', occ') = tidyOccName env (getOccName name)
+{-
+Note [Substitution in template variables kinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+data List a = Nil | Cons a (List a)
+data SList s as where
+ SNil :: SList s Nil
+
+We call tcResultType with
+ tmpl_tvs = [(k :: BOX), (s :: k -> *), (as :: List k)]
+ res_tmpl = SList k s as)
+ res_ty = ResTyGADT (SList k1 (s1 :: k1 -> *) (Nil k1))
+
+We get subst:
+ k -> k1
+ s -> s1
+ as -> Nil k1
+
+Now we want to find out the universal variables and the equivalences
+between some of them and types (GADT).
+
+In this example, k and s are mapped to exactly variables which are not
+already present in the universal set, so we just add them without any
+coercion.
+
+But 'as' is mapped to 'Nil k1', so we add 'as' to the universal set,
+and add the equivalence with 'Nil k1' in 'eqs'.
+
+The problem is that with kind polymorphism, as's kind may now contain
+kind variables, and we have to apply the template substitution to it,
+which is why we create new_tmpl.
+
+The template substitution only maps kind variables to kind variables,
+since GADTs are not kind indexed.
+
+-}
+
+
consUseH98Syntax :: [LConDecl a] -> Bool
consUseH98Syntax (L _ (ConDecl { con_res = ResTyGADT _ }) : _) = False
consUseH98Syntax _ = True
diff --git a/compiler/types/Type.lhs b/compiler/types/Type.lhs
index 228e104..6cadc82 100644
--- a/compiler/types/Type.lhs
+++ b/compiler/types/Type.lhs
@@ -1404,7 +1404,7 @@ substTyVarBndr subst@(TvSubst in_scope tenv) old_var
old_ki = tyVarKind old_var
no_kind_change = isEmptyVarSet (tyVarsOfType old_ki) -- verify that kind is closed
- no_change = new_var == old_var
+ no_change = no_kind_change && (new_var == old_var)
-- no_change means that the new_var is identical in
-- all respects to the old_var (same unique, same kind)
-- See Note [Extending the TvSubst]
More information about the Cvs-ghc
mailing list