summaryrefslogtreecommitdiff
path: root/compiler/rename
diff options
context:
space:
mode:
authorJohn Leo <leo@halfaya.org>2017-01-10 13:36:17 -0500
committerBen Gamari <ben@smart-cactus.org>2017-01-10 13:37:18 -0500
commit8a76d32e4fbdafe787a0f5b2a492c0d0ea1ed980 (patch)
tree399009e76308ac36dbb715d0e985db6060090c49 /compiler/rename
parent226c5352bb63ab53b11a23484c8ec8f20a57d538 (diff)
downloadhaskell-8a76d32e4fbdafe787a0f5b2a492c0d0ea1ed980.tar.gz
Check that type variable does not reference itself in its kind signature
This fixes #11592. Test Plan: validate Reviewers: simonpj, austin, bgamari, goldfire Reviewed By: goldfire Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2914 GHC Trac Issues: #11592
Diffstat (limited to 'compiler/rename')
-rw-r--r--compiler/rename/RnTypes.hs22
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler/rename/RnTypes.hs b/compiler/rename/RnTypes.hs
index f3fcf88ade..ec00511d62 100644
--- a/compiler/rename/RnTypes.hs
+++ b/compiler/rename/RnTypes.hs
@@ -918,19 +918,19 @@ bindLHsTyVarBndr :: HsDocContext
bindLHsTyVarBndr doc mb_assoc kv_names tv_names hs_tv_bndr thing_inside
= case hs_tv_bndr of
L loc (UserTyVar lrdr@(L lv rdr)) ->
- do { check_dup loc rdr
+ do { check_dup loc rdr []
; nm <- newTyVarNameRn mb_assoc lrdr
; bindLocalNamesFV [nm] $
thing_inside [] emptyNameSet (L loc (UserTyVar (L lv nm))) }
L loc (KindedTyVar lrdr@(L lv rdr) kind) ->
- do { check_dup lv rdr
+ do { free_kvs <- freeKiTyVarsAllVars <$> extractHsTyRdrTyVars kind
+ ; check_dup lv rdr (map unLoc free_kvs)
-- check for -XKindSignatures
; sig_ok <- xoptM LangExt.KindSignatures
; unless sig_ok (badKindSigErr doc kind)
-- deal with kind vars in the user-written kind
- ; free_kvs <- freeKiTyVarsAllVars <$> extractHsTyRdrTyVars kind
; bindImplicitKvs doc mb_assoc free_kvs tv_names $
\ new_kv_nms other_kv_nms ->
do { (kind', fvs1) <- rnLHsKind doc kind
@@ -943,9 +943,15 @@ bindLHsTyVarBndr doc mb_assoc kv_names tv_names hs_tv_bndr thing_inside
-- make sure that the RdrName isn't in the sets of
-- names. We can't just check that it's not in scope at all
-- because we might be inside an associated class.
- check_dup :: SrcSpan -> RdrName -> RnM ()
- check_dup loc rdr
- = do { m_name <- lookupLocalOccRn_maybe rdr
+ check_dup :: SrcSpan -> RdrName -> [RdrName] -> RnM ()
+ check_dup loc rdr kindFreeVars
+ = do { -- Disallow use of a type variable name in its
+ -- kind signature (#11592).
+ when (rdr `elem` kindFreeVars) $
+ addErrAt loc (vcat [ ki_ty_self_err rdr
+ , pprHsDocContext doc ])
+
+ ; m_name <- lookupLocalOccRn_maybe rdr
; whenIsJust m_name $ \name ->
do { when (name `elemNameSet` kv_names) $
addErrAt loc (vcat [ ki_ty_err_msg name
@@ -957,6 +963,10 @@ bindLHsTyVarBndr doc mb_assoc kv_names tv_names hs_tv_bndr thing_inside
text "used as a kind variable before being bound" $$
text "as a type variable. Perhaps reorder your variables?"
+ ki_ty_self_err n = text "Variable" <+> quotes (ppr n) <+>
+ text "is used in the kind signature of its" $$
+ text "declaration as a type variable."
+
bindImplicitKvs :: HsDocContext
-> Maybe a