diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2021-01-27 11:35:45 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-01-30 14:13:00 -0500 |
commit | 69cab37ae89db16cfd0b734d7fc657e56402a255 (patch) | |
tree | 2984338f89d488e35e19bf469968bbdabd625d83 | |
parent | 73fa75f5a96d515e22069233e894eac3c53a3d6d (diff) | |
download | haskell-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.hs | 31 | ||||
-rw-r--r-- | testsuite/tests/polykinds/T19250.hs | 12 | ||||
-rw-r--r-- | testsuite/tests/polykinds/all.T | 1 |
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, ['']) |