summaryrefslogtreecommitdiff
path: root/compiler/rename/RnSource.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2017-11-28 11:33:37 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2017-12-07 14:40:35 +0000
commitfa29df02a1b0b926afb2525a258172dcbf0ea460 (patch)
tree594244e6f84a99a36acfd962eeb62b4a35f42726 /compiler/rename/RnSource.hs
parent5f332e1dab000e1f79c127d441f618280d14d2bd (diff)
downloadhaskell-fa29df02a1b0b926afb2525a258172dcbf0ea460.tar.gz
Refactor ConDecl: Trac #14529
This patch refactors HsDecls.ConDecl. Specifically * ConDeclGADT was horrible, with all the information hidden inside con_res_ty. Now it's kept separate, as it should be. * ConDeclH98: use [LHsTyVarBndr] instead of LHsQTyVars for the existentials. There is no implicit binding here. * Add a field con_forall to both ConDeclGADT and ConDeclH98 which says if there is an explicit user-written forall. * Field renamings in ConDecl con_cxt to con_mb_cxt con_details to con_args There is an accompanying submodule update to Haddock. Also the following change turned out to remove a lot of clutter: * add a smart constructor for HsAppsTy, namely mkHsAppsTy, and use it consistently. This avoids a lot of painful pattern matching for the common singleton case. Two api-annotation tests (T10278, and T10399) are broken, hence marking them as expect_broken(14529). Alan is going to fix them, probably by changing the con_forall field to con_forall :: Maybe SrcSpan instead of Bool
Diffstat (limited to 'compiler/rename/RnSource.hs')
-rw-r--r--compiler/rename/RnSource.hs116
1 files changed, 77 insertions, 39 deletions
diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs
index c0347c4d6b..897e660515 100644
--- a/compiler/rename/RnSource.hs
+++ b/compiler/rename/RnSource.hs
@@ -52,7 +52,6 @@ import Avail
import Outputable
import Bag
import BasicTypes ( DerivStrategy, RuleName, pprRuleName )
-import Maybes ( orElse )
import FastString
import SrcLoc
import DynFlags
@@ -1536,6 +1535,7 @@ rnTyClDecl (DataDecl { tcdLName = tycon, tcdTyVars = tyvars,
; typeintype <- xoptM LangExt.TypeInType
; let cusk = hsTvbAllKinded tyvars' &&
(not typeintype || no_rhs_kvs)
+ ; traceRn "rndata" (ppr tycon <+> ppr cusk <+> ppr no_rhs_kvs)
; return (DataDecl { tcdLName = tycon', tcdTyVars = tyvars'
, tcdFixity = fixity
, tcdDataDefn = defn', tcdDataCusk = cusk
@@ -1872,52 +1872,90 @@ rnConDecls :: [LConDecl GhcPs] -> RnM ([LConDecl GhcRn], FreeVars)
rnConDecls = mapFvRn (wrapLocFstM rnConDecl)
rnConDecl :: ConDecl GhcPs -> RnM (ConDecl GhcRn, FreeVars)
-rnConDecl decl@(ConDeclH98 { con_name = name, con_qvars = qtvs
- , con_cxt = mcxt, con_details = details
+rnConDecl decl@(ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs
+ , con_mb_cxt = mcxt, con_args = args
, con_doc = mb_doc })
- = do { _ <- addLocM checkConName name
- ; new_name <- lookupLocatedTopBndrRn name
- ; mb_doc' <- rnMbLHsDoc mb_doc
-
- ; let doc = ConDeclCtx [new_name]
- qtvs' = qtvs `orElse` mkHsQTvs []
- body_kvs = [] -- Consider data T a = forall (b::k). MkT (...)
- -- The 'k' will already be in scope from the
- -- bindHsQTyVars for the entire DataDecl
- -- So there can be no new body_kvs here
- ; bindHsQTyVars doc (Just $ inHsDocContext doc) Nothing body_kvs qtvs' $
- \new_tyvars _ -> do
- { (new_context, fvs1) <- case mcxt of
- Nothing -> return (Nothing,emptyFVs)
- Just lcxt -> do { (lctx',fvs) <- rnContext doc lcxt
- ; return (Just lctx',fvs) }
- ; (new_details, fvs2) <- rnConDeclDetails (unLoc new_name) doc details
- ; let (new_details',fvs3) = (new_details,emptyFVs)
+ = do { _ <- addLocM checkConName name
+ ; new_name <- lookupLocatedTopBndrRn name
+ ; mb_doc' <- rnMbLHsDoc mb_doc
+
+ -- We bind no implicit binders here; this is just like
+ -- a nested HsForAllTy. E.g. consider
+ -- data T a = forall (b::k). MkT (...)
+ -- The 'k' will already be in scope from the bindHsQTyVars
+ -- for the data decl itself. So we'll get
+ -- data T {k} a = ...
+ -- And indeed we may later discover (a::k). But that's the
+ -- scoping we get. So no implicit binders at the existential forall
+
+ ; let ctxt = ConDeclCtx [new_name]
+ ; bindLHsTyVarBndrs ctxt (Just (inHsDocContext ctxt))
+ Nothing ex_tvs $ \ new_ex_tvs ->
+ do { (new_context, fvs1) <- rnMbContext ctxt mcxt
+ ; (new_args, fvs2) <- rnConDeclDetails (unLoc new_name) ctxt args
+ ; let all_fvs = fvs1 `plusFV` fvs2
; traceRn "rnConDecl" (ppr name <+> vcat
- [ text "qtvs:" <+> ppr qtvs
- , text "qtvs':" <+> ppr qtvs' ])
- ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3
- new_tyvars' = case qtvs of
- Nothing -> Nothing
- Just _ -> Just new_tyvars
- ; return (decl { con_name = new_name, con_qvars = new_tyvars'
- , con_cxt = new_context, con_details = new_details'
+ [ text "ex_tvs:" <+> ppr ex_tvs
+ , text "new_ex_dqtvs':" <+> ppr new_ex_tvs ])
+
+ ; return (decl { con_name = new_name, con_ex_tvs = new_ex_tvs
+ , con_mb_cxt = new_context, con_args = new_args
, con_doc = mb_doc' },
all_fvs) }}
-rnConDecl decl@(ConDeclGADT { con_names = names, con_type = ty
+rnConDecl decl@(ConDeclGADT { con_names = names
+ , con_forall = explicit_forall
+ , con_qvars = qtvs
+ , con_mb_cxt = mcxt
+ , con_args = args
+ , con_res_ty = res_ty
, con_doc = mb_doc })
= do { mapM_ (addLocM checkConName) names
- ; new_names <- mapM lookupLocatedTopBndrRn names
- ; let doc = ConDeclCtx new_names
- ; mb_doc' <- rnMbLHsDoc mb_doc
-
- ; (ty', fvs) <- rnHsSigType doc ty
- ; traceRn "rnConDecl" (ppr names <+> vcat
- [ text "fvs:" <+> ppr fvs ])
- ; return (decl { con_names = new_names, con_type = ty'
+ ; new_names <- mapM lookupLocatedTopBndrRn names
+ ; mb_doc' <- rnMbLHsDoc mb_doc
+
+ ; let explicit_tkvs = hsQTvExplicit qtvs
+ theta = hsConDeclTheta mcxt
+ arg_tys = hsConDeclArgTys args
+ ; free_tkvs <- extractHsTysRdrTyVarsDups (res_ty : theta ++ arg_tys)
+ ; free_tkvs <- extractHsTvBndrs explicit_tkvs free_tkvs
+
+ ; let ctxt = ConDeclCtx new_names
+ mb_ctxt = Just (inHsDocContext ctxt)
+
+ ; traceRn "rnConDecl" (ppr names $$ ppr free_tkvs $$ ppr explicit_forall )
+ ; rnImplicitBndrs (not explicit_forall) ctxt free_tkvs $ \ implicit_tkvs ->
+ bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs ->
+ do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt
+ ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args
+ ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty
+
+ ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3
+ (args', res_ty')
+ = case args of
+ InfixCon {} -> pprPanic "rnConDecl" (ppr names)
+ RecCon {} -> (new_args, new_res_ty)
+ PrefixCon as | (arg_tys, final_res_ty) <- splitHsFunType new_res_ty
+ -> ASSERT( null as )
+ -- See Note [GADT abstract syntax] in HsDecls
+ (PrefixCon arg_tys, final_res_ty)
+
+ new_qtvs = HsQTvs { hsq_implicit = implicit_tkvs
+ , hsq_explicit = explicit_tkvs
+ , hsq_dependent = emptyNameSet }
+
+ ; traceRn "rnConDecl2" (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs)
+ ; return (decl { con_names = new_names
+ , con_qvars = new_qtvs, con_mb_cxt = new_cxt
+ , con_args = args', con_res_ty = res_ty'
, con_doc = mb_doc' },
- fvs) }
+ all_fvs) } }
+
+rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs)
+ -> RnM (Maybe (LHsContext GhcRn), FreeVars)
+rnMbContext _ Nothing = return (Nothing, emptyFVs)
+rnMbContext doc (Just cxt) = do { (ctx',fvs) <- rnContext doc cxt
+ ; return (Just ctx',fvs) }
rnConDeclDetails
:: Name