diff options
author | John Leo <leo@halfaya.org> | 2017-01-10 13:36:17 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-01-10 13:37:18 -0500 |
commit | 8a76d32e4fbdafe787a0f5b2a492c0d0ea1ed980 (patch) | |
tree | 399009e76308ac36dbb715d0e985db6060090c49 /compiler/rename | |
parent | 226c5352bb63ab53b11a23484c8ec8f20a57d538 (diff) | |
download | haskell-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.hs | 22 |
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 |