summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorRichard Eisenberg <rae@cs.brynmawr.edu>2018-07-05 15:09:50 -0400
committerRichard Eisenberg <rae@cs.brynmawr.edu>2018-07-10 19:08:21 -0400
commit030211d21207dabb7a4bf21cc9af6fa5eb066db1 (patch)
treea2a168f516af6fbf354f5094548a9aa5fc648bac /compiler
parent042df603cbb5a77ec13ccfec2ce7bad2bb940aae (diff)
downloadhaskell-030211d21207dabb7a4bf21cc9af6fa5eb066db1.tar.gz
Kind-check CUSK associated types separately
Previously, we kind-checked associated types while while still figuring out the kind of a CUSK class. This caused trouble, as documented in Note [Don't process associated types in kcLHsQTyVars] in TcTyClsDecls. This commit moves this process after the initial kind of the class is determined. Fixes #15142. Test case: indexed-types/should_compile/T15142.hs
Diffstat (limited to 'compiler')
-rw-r--r--compiler/typecheck/TcHsType.hs12
-rw-r--r--compiler/typecheck/TcTyClsDecls.hs71
2 files changed, 51 insertions, 32 deletions
diff --git a/compiler/typecheck/TcHsType.hs b/compiler/typecheck/TcHsType.hs
index 0063e393bf..9c660ba06c 100644
--- a/compiler/typecheck/TcHsType.hs
+++ b/compiler/typecheck/TcHsType.hs
@@ -1591,14 +1591,14 @@ kcLHsQTyVars :: Name -- ^ of the thing being checked
-> TyConFlavour -- ^ What sort of 'TyCon' is being checked
-> Bool -- ^ True <=> the decl being checked has a CUSK
-> LHsQTyVars GhcRn
- -> TcM (Kind, r) -- ^ The result kind, possibly with other info
- -> TcM (TcTyCon, r) -- ^ A suitably-kinded TcTyCon
+ -> TcM Kind -- ^ The result kind
+ -> TcM TcTyCon -- ^ A suitably-kinded TcTyCon
kcLHsQTyVars name flav cusk
user_tyvars@(HsQTvs { hsq_ext = HsQTvsRn { hsq_implicit = kv_ns
, hsq_dependent = dep_names }
, hsq_explicit = hs_tvs }) thing_inside
| cusk
- = do { (scoped_kvs, (tc_tvs, (res_kind, stuff)))
+ = do { (scoped_kvs, (tc_tvs, res_kind))
<- solveEqualities $
tcImplicitQTKBndrs skol_info kv_ns $
kcLHsQTyVarBndrs cusk open_fam skol_info hs_tvs thing_inside
@@ -1645,10 +1645,10 @@ kcLHsQTyVars name flav cusk
, ppr tc_tvs, ppr (mkTyConKind final_binders res_kind)
, ppr qkvs, ppr final_binders ]
- ; return (tycon, stuff) }
+ ; return tycon }
| otherwise
- = do { (scoped_kvs, (tc_tvs, (res_kind, stuff)))
+ = do { (scoped_kvs, (tc_tvs, res_kind))
-- Why kcImplicitTKBndrs which uses newSigTyVar?
-- See Note [Kind generalisation and sigTvs]
<- kcImplicitTKBndrs kv_ns $
@@ -1664,7 +1664,7 @@ kcLHsQTyVars name flav cusk
; traceTc "kcLHsQTyVars: not-cusk" $
vcat [ ppr name, ppr kv_ns, ppr hs_tvs, ppr dep_names
, ppr tc_tvs, ppr (mkTyConKind tc_binders res_kind) ]
- ; return (tycon, stuff) }
+ ; return tycon }
where
open_fam = tcFlavourIsOpen flav
skol_info = TyConSkol flav name
diff --git a/compiler/typecheck/TcTyClsDecls.hs b/compiler/typecheck/TcTyClsDecls.hs
index f212fdd5bb..308fbb953e 100644
--- a/compiler/typecheck/TcTyClsDecls.hs
+++ b/compiler/typecheck/TcTyClsDecls.hs
@@ -460,6 +460,29 @@ to Note [Single function non-recursive binding special-case]:
Unfortunately this requires reworking a bit of the code in
'kcLTyClDecl' so I've decided to punt unless someone shouts about it.
+
+Note [Don't process associated types in kcLHsQTyVars]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Previously, we processed associated types in the thing_inside in kcLHsQTyVars,
+but this was wrong -- we want to do ATs sepearately.
+The consequence for not doing it this way is #15142:
+
+ class ListTuple (tuple :: Type) (as :: [(k, Type)]) where
+ type ListToTuple as :: Type
+
+We assign k a kind kappa[1]. When checking the tuple (k, Type), we try to unify
+kappa ~ Type, but this gets deferred because we bumped the TcLevel as we bring
+`tuple` into scope. Thus, when we check ListToTuple, kappa[1] still hasn't
+unified with Type. And then, when we generalize the kind of ListToTuple (which
+indeed has a CUSK, according to the rules), we skolemize the free metavariable
+kappa. Note that we wouldn't skolemize kappa when generalizing the kind of ListTuple,
+because the solveEqualities in kcLHsQTyVars is at TcLevel 1 and so kappa[1]
+will unify with Type.
+
+Bottom line: as associated types should have no effect on a CUSK enclosing class,
+we move processing them to a separate action, run after the outer kind has
+been generalized.
+
-}
kcTyClGroup :: [LTyClDecl GhcRn] -> TcM [TcTyCon]
@@ -603,22 +626,22 @@ getInitialKind :: TyClDecl GhcRn -> TcM [TcTyCon]
getInitialKind decl@(ClassDecl { tcdLName = L _ name, tcdTyVars = ktvs, tcdATs = ats })
= do { let cusk = hsDeclHasCusk decl
- ; (tycon, inner_tcs) <-
- kcLHsQTyVars name ClassFlavour cusk ktvs $
- do { inner_tcs <- getFamDeclInitialKinds (Just cusk) ats
- ; return (constraintKind, inner_tcs) }
+ ; tycon <- kcLHsQTyVars name ClassFlavour cusk ktvs $
+ return constraintKind
+ -- See Note [Don't process associated types in kcLHsQTyVars]
+ ; inner_tcs <- tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $
+ getFamDeclInitialKinds (Just cusk) ats
; return (tycon : inner_tcs) }
getInitialKind decl@(DataDecl { tcdLName = L _ name
, tcdTyVars = ktvs
, tcdDataDefn = HsDataDefn { dd_kindSig = m_sig
, dd_ND = new_or_data } })
- = do { (tycon, _) <-
+ = do { tycon <-
kcLHsQTyVars name (newOrDataToFlavour new_or_data) (hsDeclHasCusk decl) ktvs $
- do { res_k <- case m_sig of
- Just ksig -> tcLHsKindSig (DataKindCtxt name) ksig
- Nothing -> return liftedTypeKind
- ; return (res_k, ()) }
+ case m_sig of
+ Just ksig -> tcLHsKindSig (DataKindCtxt name) ksig
+ Nothing -> return liftedTypeKind
; return [tycon] }
getInitialKind (FamDecl { tcdFam = decl })
@@ -628,12 +651,10 @@ getInitialKind (FamDecl { tcdFam = decl })
getInitialKind decl@(SynDecl { tcdLName = L _ name
, tcdTyVars = ktvs
, tcdRhs = rhs })
- = do { (tycon, _) <- kcLHsQTyVars name TypeSynonymFlavour
- (hsDeclHasCusk decl) ktvs $
- do { res_k <- case kind_annotation rhs of
- Nothing -> newMetaKindVar
- Just ksig -> tcLHsKindSig (TySynKindCtxt name) ksig
- ; return (res_k, ()) }
+ = do { tycon <- kcLHsQTyVars name TypeSynonymFlavour (hsDeclHasCusk decl) ktvs $
+ case kind_annotation rhs of
+ Nothing -> newMetaKindVar
+ Just ksig -> tcLHsKindSig (TySynKindCtxt name) ksig
; return [tycon] }
where
-- Keep this synchronized with 'hsDeclHasCusk'.
@@ -659,17 +680,15 @@ getFamDeclInitialKind mb_cusk decl@(FamilyDecl { fdLName = L _ name
, fdTyVars = ktvs
, fdResultSig = L _ resultSig
, fdInfo = info })
- = do { (tycon, _) <-
- kcLHsQTyVars name flav cusk ktvs $
- do { res_k <- case resultSig of
- KindSig _ ki -> tcLHsKindSig ctxt ki
- TyVarSig _ (L _ (KindedTyVar _ _ ki)) -> tcLHsKindSig ctxt ki
- _ -- open type families have * return kind by default
- | tcFlavourIsOpen flav -> return liftedTypeKind
- -- closed type families have their return kind inferred
- -- by default
- | otherwise -> newMetaKindVar
- ; return (res_k, ()) }
+ = do { tycon <- kcLHsQTyVars name flav cusk ktvs $
+ case resultSig of
+ KindSig _ ki -> tcLHsKindSig ctxt ki
+ TyVarSig _ (L _ (KindedTyVar _ _ ki)) -> tcLHsKindSig ctxt ki
+ _ -- open type families have * return kind by default
+ | tcFlavourIsOpen flav -> return liftedTypeKind
+ -- closed type families have their return kind inferred
+ -- by default
+ | otherwise -> newMetaKindVar
; return tycon }
where
cusk = famDeclHasCusk mb_cusk decl