summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2021-01-27 11:35:45 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-01-30 14:13:00 -0500
commit69cab37ae89db16cfd0b734d7fc657e56402a255 (patch)
tree2984338f89d488e35e19bf469968bbdabd625d83
parent73fa75f5a96d515e22069233e894eac3c53a3d6d (diff)
downloadhaskell-69cab37ae89db16cfd0b734d7fc657e56402a255.tar.gz
Zonk the returned kind in tcFamTyPats
The motivation is given in Note [tcFamTyPats: zonking the result kind]. Fixes #19250 -- the fix is easy.
-rw-r--r--compiler/GHC/Tc/Gen/HsType.hs31
-rw-r--r--testsuite/tests/polykinds/T19250.hs12
-rw-r--r--testsuite/tests/polykinds/all.T1
3 files changed, 44 insertions, 0 deletions
diff --git a/compiler/GHC/Tc/Gen/HsType.hs b/compiler/GHC/Tc/Gen/HsType.hs
index 0a188d9020..39b18e063c 100644
--- a/compiler/GHC/Tc/Gen/HsType.hs
+++ b/compiler/GHC/Tc/Gen/HsType.hs
@@ -680,6 +680,9 @@ tcFamTyPats fam_tc hs_pats
; let fun_ty = mkTyConApp fam_tc []
; (fam_app, res_kind) <- tcInferTyApps mode lhs_fun fun_ty hs_pats
+ -- Hack alert: see Note [tcFamTyPats: zonking the result kind]
+ ; res_kind <- zonkTcType res_kind
+
; traceTc "End tcFamTyPats }" $
vcat [ ppr fam_tc, text "res_kind:" <+> ppr res_kind ]
@@ -689,6 +692,34 @@ tcFamTyPats fam_tc hs_pats
fam_arity = tyConArity fam_tc
lhs_fun = noLoc (HsTyVar noExtField NotPromoted (noLoc fam_name))
+{- Note [tcFamTyPats: zonking the result kind]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider (#19250)
+ F :: forall k. k -> k
+ type instance F (x :: Constraint) = ()
+
+The tricky point is this:
+ is that () an empty type tuple (() :: Type), or
+ an empty constraint tuple (() :: Constraint)?
+We work this out in a hacky way, by looking at the expected kind:
+see Note [Inferring tuple kinds].
+
+In this case, we kind-check the RHS using the kind gotten from the LHS:
+see the call to tcCheckLHsType in tcTyFamInstEqnGuts in GHC.Tc.Tycl.
+
+But we want the kind from the LHS to be /zonked/, so that when
+kind-checking the RHS (tcCheckLHsType) we can "see" what we learned
+from kind-checking the LHS (tcFamTyPats). In our example above, the
+type of the LHS is just `kappa` (by instantiating the forall k), but
+then we learn (from x::Constraint) that kappa ~ Constraint. We want
+that info when kind-checking the RHS.
+
+Easy solution: just zonk that return kind. Of course this won't help
+if there is lots of type-family reduction to do, but it works fine in
+common cases.
+-}
+
+
{-
************************************************************************
* *
diff --git a/testsuite/tests/polykinds/T19250.hs b/testsuite/tests/polykinds/T19250.hs
new file mode 100644
index 0000000000..6781e4bd39
--- /dev/null
+++ b/testsuite/tests/polykinds/T19250.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE TypeOperators, TypeFamilies, ConstraintKinds, PolyKinds, DataKinds, EmptyDataDecls #-}
+
+module T19250 where
+
+import Data.Kind
+
+type Exp a = a -> Type
+
+type family Eval (e :: Exp a) :: a
+
+data Collapse :: [Constraint] -> Exp Constraint
+type instance Eval (Collapse '[]) = ()
diff --git a/testsuite/tests/polykinds/all.T b/testsuite/tests/polykinds/all.T
index c82f275f65..1be9bb11b5 100644
--- a/testsuite/tests/polykinds/all.T
+++ b/testsuite/tests/polykinds/all.T
@@ -234,3 +234,4 @@ test('T18855', normal, compile, [''])
test('T19092', normal, compile, [''])
test('T19093', normal, compile, [''])
test('T19094', normal, compile, [''])
+test('T19250', normal, compile, [''])