free variables.
\begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
module RnExpr (
rnLExpr, rnExpr, rnStmts
) where
#include "HsVersions.h"
+#ifdef GHCI
+import {-# SOURCE #-} TcSplice( runQuasiQuoteExpr )
+#endif /* GHCI */
+
import RnSource ( rnSrcDecls, rnSplice, checkTH )
import RnBinds ( rnLocalBindsAndThen, rnValBindsLHS, rnValBindsRHS,
rnMatchGroup, makeMiniFixityEnv)
import HsSyn
import TcRnMonad
+import TcEnv ( thRnBrack )
import RnEnv
-import HscTypes ( availNames )
-import RnNames ( getLocalDeclBinders, extendRdrEnvRn )
import RnTypes ( rnHsTypeFVs,
mkOpFormRn, mkOpAppRn, mkNegAppRn, checkSectionPrec)
-import RnPat (rnOverLit, rnPatsAndThen_LocalRightwards, rnBindPat,
- localRecNameMaker, rnLit,
- rnHsRecFields_Con, rnHsRecFields_Update, checkTupSize)
-import RdrName ( mkRdrUnqual )
+import RnPat
import DynFlags ( DynFlag(..) )
import BasicTypes ( FixityDirection(..) )
-import SrcLoc ( SrcSpan )
-import PrelNames ( thFAKE, hasKey, assertIdKey, assertErrorName,
+import PrelNames ( hasKey, assertIdKey, assertErrorName,
loopAName, choiceAName, appAName, arrAName, composeAName, firstAName,
negateName, thenMName, bindMName, failMName, groupWithName )
-import Name ( Name, nameOccName, nameModule, nameIsLocalOrFrom )
+import Name
import NameSet
-import UniqFM
-import RdrName ( RdrName, extendLocalRdrEnv, lookupLocalRdrEnv, hideSomeUnquals )
+import RdrName
import LoadIface ( loadInterfaceForName )
-import UniqFM ( isNullUFM )
-import UniqSet ( emptyUniqSet )
+import UniqSet
import List ( nub )
import Util ( isSingleton )
import ListSetOps ( removeDups )
import Maybes ( expectJust )
import Outputable
-import SrcLoc ( Located(..), unLoc, getLoc, noLoc )
+import SrcLoc
import FastString
import List ( unzip4 )
+import Control.Monad
\end{code}
+\begin{code}
+-- XXX
+thenM :: Monad a => a b -> (b -> a c) -> a c
+thenM = (>>=)
+
+thenM_ :: Monad a => a b -> a c -> a c
+thenM_ = (>>)
+
+returnM :: Monad m => a -> m a
+returnM = return
+
+mappM :: (Monad m) => (a -> m b) -> [a] -> m [b]
+mappM = mapM
+
+checkM :: Monad m => Bool -> m () -> m ()
+checkM = unless
+\end{code}
+
%************************************************************************
%* *
\subsubsection{Expressions}
let
acc' = acc `plusFV` fvExpr
in
- (grubby_seqNameSet acc' rnExprs') exprs acc' `thenM` \ (exprs', fvExprs) ->
+ acc' `seq` rnExprs' exprs acc' `thenM` \ (exprs', fvExprs) ->
returnM (expr':exprs', fvExprs)
-
--- Grubby little function to do "seq" on namesets; replace by proper seq when GHC can do seq
-grubby_seqNameSet ns result | isNullUFM ns = result
- | otherwise = result
\end{code}
Variables. We look up the variable and return the resulting name.
rnExpr :: HsExpr RdrName -> RnM (HsExpr Name, FreeVars)
+finishHsVar :: Name -> RnM (HsExpr Name, FreeVars)
+-- Separated from rnExpr because it's also used
+-- when renaming infix expressions
+-- See Note [Adding the implicit parameter to 'assert']
+finishHsVar name
+ = do { ignore_asserts <- doptM Opt_IgnoreAsserts
+ ; if ignore_asserts || not (name `hasKey` assertIdKey)
+ then return (HsVar name, unitFV name)
+ else do { e <- mkAssertErrorExpr
+ ; return (e, unitFV name) } }
+
rnExpr (HsVar v)
- = do name <- lookupOccRn v
- ignore_asserts <- doptM Opt_IgnoreAsserts
- finish_var ignore_asserts name
- where
- finish_var ignore_asserts name
- | ignore_asserts || not (name `hasKey` assertIdKey)
- = return (HsVar name, unitFV name)
- | otherwise
- = do { (e, fvs) <- mkAssertErrorExpr
- ; return (e, fvs `addOneFV` name) }
+ = do name <- lookupOccRn v
+ finishHsVar name
rnExpr (HsIPVar v)
= newIPNameRn v `thenM` \ name ->
rnLExpr arg `thenM` \ (arg',fvArg) ->
returnM (HsApp fun' arg', fvFun `plusFV` fvArg)
-rnExpr (OpApp e1 op _ e2)
- = rnLExpr e1 `thenM` \ (e1', fv_e1) ->
- rnLExpr e2 `thenM` \ (e2', fv_e2) ->
- rnLExpr op `thenM` \ (op'@(L _ (HsVar op_name)), fv_op) ->
-
+rnExpr (OpApp e1 (L op_loc (HsVar op_rdr)) _ e2)
+ = do { (e1', fv_e1) <- rnLExpr e1
+ ; (e2', fv_e2) <- rnLExpr e2
+ ; op_name <- setSrcSpan op_loc (lookupOccRn op_rdr)
+ ; (op', fv_op) <- finishHsVar op_name
+ -- NB: op' is usually just a variable, but might be
+ -- an applicatoin (assert "Foo.hs:47")
-- Deal with fixity
-- When renaming code synthesised from "deriving" declarations
-- we used to avoid fixity stuff, but we can't easily tell any
-- more, so I've removed the test. Adding HsPars in TcGenDeriv
-- should prevent bad things happening.
- lookupFixityRn op_name `thenM` \ fixity ->
- mkOpAppRn e1' op' fixity e2' `thenM` \ final_e ->
-
- returnM (final_e,
- fv_e1 `plusFV` fv_op `plusFV` fv_e2)
+ ; fixity <- lookupFixityRn op_name
+ ; final_e <- mkOpAppRn e1' (L op_loc op') fixity e2'
+ ; return (final_e, fv_e1 `plusFV` fv_op `plusFV` fv_e2) }
rnExpr (NegApp e _)
= rnLExpr e `thenM` \ (e', fv_e) ->
mkNegAppRn e' neg_name `thenM` \ final_e ->
returnM (final_e, fv_e `plusFV` fv_neg)
-rnExpr (HsPar e)
- = rnLExpr e `thenM` \ (e', fvs_e) ->
- returnM (HsPar e', fvs_e)
-
+------------------------------------------
-- Template Haskell extensions
-- Don't ifdef-GHCI them because we want to fail gracefully
-- (not with an rnExpr crash) in a stage-1 compiler.
rnBracket br_body `thenM` \ (body', fvs_e) ->
returnM (HsBracket body', fvs_e)
-rnExpr e@(HsSpliceE splice)
+rnExpr (HsSpliceE splice)
= rnSplice splice `thenM` \ (splice', fvs) ->
returnM (HsSpliceE splice', fvs)
-rnExpr section@(SectionL expr op)
- = rnLExpr expr `thenM` \ (expr', fvs_expr) ->
- rnLExpr op `thenM` \ (op', fvs_op) ->
- checkSectionPrec InfixL section op' expr' `thenM_`
- returnM (SectionL expr' op', fvs_op `plusFV` fvs_expr)
+#ifndef GHCI
+rnExpr e@(HsQuasiQuoteE _) = pprPanic "Cant do quasiquotation without GHCi" (ppr e)
+#else
+rnExpr (HsQuasiQuoteE qq)
+ = rnQuasiQuote qq `thenM` \ (qq', fvs_qq) ->
+ runQuasiQuoteExpr qq' `thenM` \ (L _ expr') ->
+ rnExpr expr' `thenM` \ (expr'', fvs_expr) ->
+ returnM (expr'', fvs_qq `plusFV` fvs_expr)
+#endif /* GHCI */
-rnExpr section@(SectionR op expr)
- = rnLExpr op `thenM` \ (op', fvs_op) ->
- rnLExpr expr `thenM` \ (expr', fvs_expr) ->
- checkSectionPrec InfixR section op' expr' `thenM_`
- returnM (SectionR op' expr', fvs_op `plusFV` fvs_expr)
+---------------------------------------------
+-- Sections
+-- See Note [Parsing sections] in Parser.y.pp
+rnExpr (HsPar (L loc (section@(SectionL {}))))
+ = do { (section', fvs) <- rnSection section
+ ; return (HsPar (L loc section'), fvs) }
+
+rnExpr (HsPar (L loc (section@(SectionR {}))))
+ = do { (section', fvs) <- rnSection section
+ ; return (HsPar (L loc section'), fvs) }
+
+rnExpr (HsPar e)
+ = do { (e', fvs_e) <- rnLExpr e
+ ; return (HsPar e', fvs_e) }
+
+rnExpr expr@(SectionL {})
+ = do { addErr (sectionErr expr); rnSection expr }
+rnExpr expr@(SectionR {})
+ = do { addErr (sectionErr expr); rnSection expr }
+---------------------------------------------
rnExpr (HsCoreAnn ann expr)
= rnLExpr expr `thenM` \ (expr', fvs_expr) ->
returnM (HsCoreAnn ann expr', fvs_expr)
rnLExpr expr `thenM` \ (expr',fvExpr) ->
returnM (HsLet binds' expr', fvExpr)
-rnExpr e@(HsDo do_or_lc stmts body _)
+rnExpr (HsDo do_or_lc stmts body _)
= do { ((stmts', body'), fvs) <- rnStmts do_or_lc stmts $
rnLExpr body
; return (HsDo do_or_lc stmts' body' placeHolderType, fvs) }
= rnExprs exps `thenM` \ (exps', fvs) ->
returnM (ExplicitPArr placeHolderType exps', fvs)
-rnExpr e@(ExplicitTuple exps boxity)
+rnExpr (ExplicitTuple exps boxity)
= checkTupSize (length exps) `thenM_`
rnExprs exps `thenM` \ (exps', fvs) ->
returnM (ExplicitTuple exps' boxity, fvs)
\begin{code}
rnExpr e@EWildPat = patSynErr e
rnExpr e@(EAsPat {}) = patSynErr e
+rnExpr e@(EViewPat {}) = patSynErr e
rnExpr e@(ELazyPat {}) = patSynErr e
\end{code}
rnExpr other = pprPanic "rnExpr: unexpected expression" (ppr other)
-- HsWrap
-\end{code}
+----------------------
+-- See Note [Parsing sections] in Parser.y.pp
+rnSection :: HsExpr RdrName -> RnM (HsExpr Name, FreeVars)
+rnSection section@(SectionR op expr)
+ = do { (op', fvs_op) <- rnLExpr op
+ ; (expr', fvs_expr) <- rnLExpr expr
+ ; checkSectionPrec InfixR section op' expr'
+ ; return (SectionR op' expr', fvs_op `plusFV` fvs_expr) }
+
+rnSection section@(SectionL expr op)
+ = do { (expr', fvs_expr) <- rnLExpr expr
+ ; (op', fvs_op) <- rnLExpr op
+ ; checkSectionPrec InfixL section op' expr'
+ ; return (SectionL expr' op', fvs_op `plusFV` fvs_expr) }
+
+rnSection other = pprPanic "rnSection" (ppr other)
+\end{code}
%************************************************************************
%* *
%************************************************************************
\begin{code}
+rnCmdArgs :: [LHsCmdTop RdrName] -> RnM ([LHsCmdTop Name], FreeVars)
rnCmdArgs [] = returnM ([], emptyFVs)
rnCmdArgs (arg:args)
= rnCmdTop arg `thenM` \ (arg',fvArg) ->
rnCmdArgs args `thenM` \ (args',fvArgs) ->
returnM (arg':args', fvArg `plusFV` fvArgs)
-
+rnCmdTop :: LHsCmdTop RdrName -> RnM (LHsCmdTop Name, FreeVars)
rnCmdTop = wrapLocFstM rnCmdTop'
where
rnCmdTop' (HsCmdTop cmd _ _ _)
convertOpFormsCmd (HsPar c) = HsPar (convertOpFormsLCmd c)
--- gaw 2004
convertOpFormsCmd (HsCase exp matches)
= HsCase exp (convertOpFormsMatch matches)
-- caught by the type checker)
convertOpFormsCmd c = c
+convertOpFormsStmt :: StmtLR id id -> StmtLR id id
convertOpFormsStmt (BindStmt pat cmd _ _)
= BindStmt pat (convertOpFormsLCmd cmd) noSyntaxExpr noSyntaxExpr
convertOpFormsStmt (ExprStmt cmd _ _)
= RecStmt (map (fmap convertOpFormsStmt) stmts) lvs rvs es binds
convertOpFormsStmt stmt = stmt
+convertOpFormsMatch :: MatchGroup id -> MatchGroup id
convertOpFormsMatch (MatchGroup ms ty)
= MatchGroup (map (fmap convert) ms) ty
where convert (Match pat mty grhss)
= Match pat mty (convertOpFormsGRHSs grhss)
+convertOpFormsGRHSs :: GRHSs id -> GRHSs id
convertOpFormsGRHSs (GRHSs grhss binds)
= GRHSs (map convertOpFormsGRHS grhss) binds
+convertOpFormsGRHS :: Located (GRHS id) -> Located (GRHS id)
convertOpFormsGRHS = fmap convert
where
convert (GRHS stmts cmd) = GRHS stmts (convertOpFormsLCmd cmd)
methodNamesCmd :: HsCmd Name -> CmdNeeds
-methodNamesCmd cmd@(HsArrApp _arrow _arg _ HsFirstOrderApp _rtl)
+methodNamesCmd (HsArrApp _arrow _arg _ HsFirstOrderApp _rtl)
= emptyFVs
-methodNamesCmd cmd@(HsArrApp _arrow _arg _ HsHigherOrderApp _rtl)
+methodNamesCmd (HsArrApp _arrow _arg _ HsHigherOrderApp _rtl)
= unitFV appAName
-methodNamesCmd cmd@(HsArrForm {}) = emptyFVs
+methodNamesCmd (HsArrForm {}) = emptyFVs
methodNamesCmd (HsPar c) = methodNamesLCmd c
-methodNamesCmd (HsIf p c1 c2)
+methodNamesCmd (HsIf _ c1 c2)
= methodNamesLCmd c1 `plusFV` methodNamesLCmd c2 `addOneFV` choiceAName
-methodNamesCmd (HsLet b c) = methodNamesLCmd c
+methodNamesCmd (HsLet _ c) = methodNamesLCmd c
-methodNamesCmd (HsDo sc stmts body ty)
+methodNamesCmd (HsDo _ stmts body _)
= methodNamesStmts stmts `plusFV` methodNamesLCmd body
-methodNamesCmd (HsApp c e) = methodNamesLCmd c
+methodNamesCmd (HsApp c _) = methodNamesLCmd c
methodNamesCmd (HsLam match) = methodNamesMatch match
-methodNamesCmd (HsCase scrut matches)
+methodNamesCmd (HsCase _ matches)
= methodNamesMatch matches `addOneFV` choiceAName
-methodNamesCmd other = emptyFVs
+methodNamesCmd _ = emptyFVs
-- Other forms can't occur in commands, but it's not convenient
-- to error here so we just do what's convenient.
-- The type checker will complain later
---------------------------------------------------
+methodNamesMatch :: MatchGroup Name -> FreeVars
methodNamesMatch (MatchGroup ms _)
= plusFVs (map do_one ms)
where
- do_one (L _ (Match pats sig_ty grhss)) = methodNamesGRHSs grhss
+ do_one (L _ (Match _ _ grhss)) = methodNamesGRHSs grhss
-------------------------------------------------
-- gaw 2004
-methodNamesGRHSs (GRHSs grhss binds) = plusFVs (map methodNamesGRHS grhss)
+methodNamesGRHSs :: GRHSs Name -> FreeVars
+methodNamesGRHSs (GRHSs grhss _) = plusFVs (map methodNamesGRHS grhss)
-------------------------------------------------
-methodNamesGRHS (L _ (GRHS stmts rhs)) = methodNamesLCmd rhs
+
+methodNamesGRHS :: Located (GRHS Name) -> CmdNeeds
+methodNamesGRHS (L _ (GRHS _ rhs)) = methodNamesLCmd rhs
---------------------------------------------------
+methodNamesStmts :: [Located (StmtLR Name Name)] -> FreeVars
methodNamesStmts stmts = plusFVs (map methodNamesLStmt stmts)
---------------------------------------------------
+methodNamesLStmt :: Located (StmtLR Name Name) -> FreeVars
methodNamesLStmt = methodNamesStmt . unLoc
+methodNamesStmt :: StmtLR Name Name -> FreeVars
methodNamesStmt (ExprStmt cmd _ _) = methodNamesLCmd cmd
-methodNamesStmt (BindStmt pat cmd _ _) = methodNamesLCmd cmd
+methodNamesStmt (BindStmt _ cmd _ _) = methodNamesLCmd cmd
methodNamesStmt (RecStmt stmts _ _ _ _)
= methodNamesStmts stmts `addOneFV` loopAName
-methodNamesStmt (LetStmt b) = emptyFVs
-methodNamesStmt (ParStmt ss) = emptyFVs
+methodNamesStmt (LetStmt _) = emptyFVs
+methodNamesStmt (ParStmt _) = emptyFVs
methodNamesStmt (TransformStmt _ _ _) = emptyFVs
methodNamesStmt (GroupStmt _ _) = emptyFVs
-- ParStmt, TransformStmt and GroupStmt can't occur in commands, but it's not convenient to error
%************************************************************************
\begin{code}
+rnArithSeq :: ArithSeqInfo RdrName -> RnM (ArithSeqInfo Name, FreeVars)
rnArithSeq (From expr)
= rnLExpr expr `thenM` \ (expr', fvExpr) ->
returnM (From expr', fvExpr)
%************************************************************************
\begin{code}
+rnBracket :: HsBracket RdrName -> RnM (HsBracket Name, FreeVars)
rnBracket (VarBr n) = do { name <- lookupOccRn n
; this_mod <- getModule
; checkM (nameIsLocalOrFrom this_mod name) $ -- Reason: deprecation checking asumes the
; return () } -- only way that is going to happen
; returnM (VarBr name, unitFV name) }
where
- msg = ptext SLIT("Need interface for Template Haskell quoted Name")
+ msg = ptext (sLit "Need interface for Template Haskell quoted Name")
rnBracket (ExpBr e) = do { (e', fvs) <- rnLExpr e
; return (ExpBr e', fvs) }
-rnBracket (PatBr p) = do { addErr (ptext SLIT("Tempate Haskell pattern brackets are not supported yet"));
- failM }
-
+rnBracket (PatBr _) = failWith (ptext (sLit "Tempate Haskell pattern brackets are not supported yet"))
rnBracket (TypBr t) = do { (t', fvs) <- rnHsTypeFVs doc t
; return (TypBr t', fvs) }
where
- doc = ptext SLIT("In a Template-Haskell quoted type")
+ doc = ptext (sLit "In a Template-Haskell quoted type")
rnBracket (DecBr group)
= do { gbl_env <- getGblEnv
- ; let new_gbl_env = gbl_env { -- Set the module to thFAKE. The top-level names from the bracketed
- -- declarations will go into the name cache, and we don't want them to
- -- confuse the Names for the current module.
- -- By using a pretend module, thFAKE, we keep them safely out of the way.
- tcg_mod = thFAKE,
-
- -- The emptyDUs is so that we just collect uses for this group alone
- -- in the call to rnSrcDecls below
- tcg_dus = emptyDUs }
- ; setGblEnv new_gbl_env $ do {
-
- -- In this situation we want to *shadow* top-level bindings.
- -- foo = 1
- -- bar = [d| foo = 1 |]
- -- If we don't shadow, we'll get an ambiguity complaint when we do
- -- a lookupTopBndrRn (which uses lookupGreLocalRn) on the binder of the 'foo'
- --
- -- Furthermore, arguably if the splice does define foo, that should hide
- -- any foo's further out
- --
- -- The shadowing is acheived by calling rnSrcDecls with True as the shadowing flag
- ; (tcg_env, group') <- rnSrcDecls True group
+ ; let new_gbl_env = gbl_env { tcg_dus = emptyDUs }
+ -- The emptyDUs is so that we just collect uses for this
+ -- group alone in the call to rnSrcDecls below
+ ; (tcg_env, group') <- setGblEnv new_gbl_env $
+ setStage thRnBrack $
+ rnSrcDecls group
-- Discard the tcg_env; it contains only extra info about fixity
- ; return (DecBr group', allUses (tcg_dus tcg_env)) } }
+ ; return (DecBr group', allUses (tcg_dus tcg_env)) }
\end{code}
%************************************************************************
-- Used for cases *other* than recursive mdo
-- Implements nested scopes
-rnNormalStmts ctxt [] thing_inside
+rnNormalStmts _ [] thing_inside
= do { (thing, fvs) <- thing_inside
; return (([],thing), fvs) }
-> RnM (thing, FreeVars)
-> RnM ((Stmt Name, thing), FreeVars)
-rnStmt ctxt (ExprStmt expr _ _) thing_inside
+rnStmt _ (ExprStmt expr _ _) thing_inside
= do { (expr', fv_expr) <- rnLExpr expr
; (then_op, fvs1) <- lookupSyntaxName thenMName
; (thing, fvs2) <- thing_inside
-- fv_expr shouldn't really be filtered by the rnPatsAndThen
-- but it does not matter because the names are unique
-rnStmt ctxt (LetStmt binds) thing_inside = do
- checkErr (ok ctxt binds) (badIpBinds (ptext SLIT("a parallel list comprehension:")) binds)
- rnLocalBindsAndThen binds $ \binds' -> do
- (thing, fvs) <- thing_inside
- return ((LetStmt binds', thing), fvs)
- where
- -- We do not allow implicit-parameter bindings in a parallel
- -- list comprehension. I'm not sure what it might mean.
- ok (ParStmtCtxt _) (HsIPBinds _) = False
- ok _ _ = True
+rnStmt ctxt (LetStmt binds) thing_inside
+ = do { checkLetStmt ctxt binds
+ ; rnLocalBindsAndThen binds $ \binds' -> do
+ { (thing, fvs) <- thing_inside
+ ; return ((LetStmt binds', thing), fvs) } }
rnStmt ctxt (RecStmt rec_stmts _ _ _ _) thing_inside
- =
- rn_rec_stmts_and_then rec_stmts $ \ segs ->
- thing_inside `thenM` \ (thing, fvs) ->
- let
- segs_w_fwd_refs = addFwdRefs segs
- (ds, us, fs, rec_stmts') = unzip4 segs_w_fwd_refs
- later_vars = nameSetToList (plusFVs ds `intersectNameSet` fvs)
- fwd_vars = nameSetToList (plusFVs fs)
- uses = plusFVs us
- rec_stmt = RecStmt rec_stmts' later_vars fwd_vars [] emptyLHsBinds
- in
- returnM ((rec_stmt, thing), uses `plusFV` fvs)
- where
- doc = text "In a recursive do statement"
+ = do { checkRecStmt ctxt
+ ; rn_rec_stmts_and_then rec_stmts $ \ segs -> do
+ { (thing, fvs) <- thing_inside
+ ; let
+ segs_w_fwd_refs = addFwdRefs segs
+ (ds, us, fs, rec_stmts') = unzip4 segs_w_fwd_refs
+ later_vars = nameSetToList (plusFVs ds `intersectNameSet` fvs)
+ fwd_vars = nameSetToList (plusFVs fs)
+ uses = plusFVs us
+ rec_stmt = RecStmt rec_stmts' later_vars fwd_vars [] emptyLHsBinds
+ ; return ((rec_stmt, thing), uses `plusFV` fvs) } }
+
+rnStmt ctxt (ParStmt segs) thing_inside
+ = do { checkParStmt ctxt
+ ; ((segs', thing), fvs) <- rnParallelStmts (ParStmtCtxt ctxt) segs thing_inside
+ ; return ((ParStmt segs', thing), fvs) }
rnStmt ctxt (TransformStmt (stmts, _) usingExpr maybeByExpr) thing_inside = do
- checkIsTransformableListComp ctxt
+ checkTransformStmt ctxt
(usingExpr', fv_usingExpr) <- rnLExpr usingExpr
((stmts', binders, (maybeByExpr', thing)), fvs) <-
- rnNormalStmtsAndFindUsedBinders (TransformStmtCtxt ctxt) stmts $ \unshadowed_bndrs -> do
+ rnNormalStmtsAndFindUsedBinders (TransformStmtCtxt ctxt) stmts $ \_unshadowed_bndrs -> do
(maybeByExpr', fv_maybeByExpr) <- rnMaybeLExpr maybeByExpr
(thing, fv_thing) <- thing_inside
return (Just expr', fv_expr)
rnStmt ctxt (GroupStmt (stmts, _) groupByClause) thing_inside = do
- checkIsTransformableListComp ctxt
+ checkTransformStmt ctxt
-- We must rename the using expression in the context before the transform is begun
groupByClauseAction <-
traceRn (text "rnStmt: implicitly rebound these used binders:" <+> ppr usedBinderMap)
return ((GroupStmt (stmts', usedBinderMap) groupByClause', thing), fvs)
-rnStmt ctxt (ParStmt segs) thing_inside
- = do { parallel_list_comp <- doptM Opt_ParallelListComp
- ; checkM parallel_list_comp parStmtErr
- ; ((segs', thing), fvs) <- rnParallelStmts (ParStmtCtxt ctxt) segs thing_inside
- ; return ((ParStmt segs', thing), fvs) }
-
-
rnNormalStmtsAndFindUsedBinders :: HsStmtContext Name
-> [LStmt RdrName]
-> ([Name] -> RnM (thing, FreeVars))
-- Flatten the tuple returned by the above call a bit!
return ((stmts', used_bndrs, inner_thing), fvs)
-
+rnParallelStmts :: HsStmtContext Name -> [([LStmt RdrName], [RdrName])]
+ -> RnM (thing, FreeVars)
+ -> RnM (([([LStmt Name], [Name])], thing), FreeVars)
rnParallelStmts ctxt segs thing_inside = do
orig_lcl_env <- getLocalRdrEnv
go orig_lcl_env [] segs
return (((seg':segs'), thing), delListFromNameSet fvs bndrs)
cmpByOcc n1 n2 = nameOccName n1 `compare` nameOccName n2
- dupErr vs = addErr (ptext SLIT("Duplicate binding in parallel list comprehension for:")
+ dupErr vs = addErr (ptext (sLit "Duplicate binding in parallel list comprehension for:")
<+> quotes (ppr (head vs)))
-
-
-checkIsTransformableListComp :: HsStmtContext Name -> RnM ()
-checkIsTransformableListComp ctxt = do
- -- Ensure we are really within a list comprehension because otherwise the
- -- desugarer will break when we come to operate on a parallel array
- checkM (notParallelArray ctxt) transformStmtOutsideListCompErr
-
- -- Ensure the user has turned the correct flag on
- transform_list_comp <- doptM Opt_TransformListComp
- checkM transform_list_comp transformStmtErr
- where
- notParallelArray PArrComp = False
- notParallelArray _ = True
-
\end{code}
(stmts', fvs) = segsToStmts grouped_segs fvs_later
; return ((stmts', thing), fvs) }
- where
- doc = text "In a recursive mdo-expression"
---------------------------------------------
-- the FreeVars of the Segments
-> ([Segment (LStmt Name)] -> RnM (a, FreeVars))
-> RnM (a, FreeVars)
-rn_rec_stmts_and_then s cont = do
- -- (A) make the mini fixity env for all of the stmts
- fix_env <- makeMiniFixityEnv (collectRecStmtsFixities s)
+rn_rec_stmts_and_then s cont
+ = do { -- (A) Make the mini fixity env for all of the stmts
+ fix_env <- makeMiniFixityEnv (collectRecStmtsFixities s)
- -- (B) do the LHSes
- new_lhs_and_fv <- rn_rec_stmts_lhs fix_env s
+ -- (B) Do the LHSes
+ ; new_lhs_and_fv <- rn_rec_stmts_lhs fix_env s
- -- bring them and their fixities into scope
- let bound_names = map unLoc $ collectLStmtsBinders (map fst new_lhs_and_fv)
- bindLocalNamesFV_WithFixities bound_names fix_env $
- warnUnusedLocalBinds bound_names $ do
-
- -- (C) do the right-hand-sides and thing-inside
- segs <- rn_rec_stmts bound_names new_lhs_and_fv
- cont segs
+ -- ...bring them and their fixities into scope
+ ; let bound_names = map unLoc $ collectLStmtsBinders (map fst new_lhs_and_fv)
+ ; bindLocalNamesFV_WithFixities bound_names fix_env $ do
+ -- (C) do the right-hand-sides and thing-inside
+ { segs <- rn_rec_stmts bound_names new_lhs_and_fv
+ ; (res, fvs) <- cont segs
+ ; warnUnusedLocalBinds bound_names fvs
+ ; return (res, fvs) }}
-- get all the fixity decls in any Let stmt
+collectRecStmtsFixities :: [LStmtLR RdrName RdrName] -> [LFixitySig RdrName]
collectRecStmtsFixities l =
foldr (\ s -> \acc -> case s of
- (L loc (LetStmt (HsValBinds (ValBindsIn _ sigs)))) ->
+ (L _ (LetStmt (HsValBinds (ValBindsIn _ sigs)))) ->
foldr (\ sig -> \ acc -> case sig of
(L loc (FixSig s)) -> (L loc s) : acc
_ -> acc) acc sigs
-- left-hand sides
-rn_rec_stmt_lhs :: UniqFM (Located Fixity) -- mini fixity env for the names we're about to bind
- -- these fixities need to be brought into scope with the names
+rn_rec_stmt_lhs :: MiniFixityEnv
-> LStmt RdrName
-- rename LHS, and return its FVs
-- Warning: we will only need the FreeVars below in the case of a BindStmt,
-- so we don't bother to compute it accurately in the other cases
-> RnM [(LStmtLR Name RdrName, FreeVars)]
-rn_rec_stmt_lhs fix_env (L loc (ExprStmt expr a b)) = return [(L loc (ExprStmt expr a b),
+rn_rec_stmt_lhs _ (L loc (ExprStmt expr a b)) = return [(L loc (ExprStmt expr a b),
-- this is actually correct
emptyFVs)]
return [(L loc (BindStmt pat' expr a b),
fv_pat)]
-rn_rec_stmt_lhs fix_env (L loc (LetStmt binds@(HsIPBinds _)))
- = do { addErr (badIpBinds (ptext SLIT("an mdo expression")) binds)
- ; failM }
+rn_rec_stmt_lhs _ (L _ (LetStmt binds@(HsIPBinds _)))
+ = failWith (badIpBinds (ptext (sLit "an mdo expression")) binds)
rn_rec_stmt_lhs fix_env (L loc (LetStmt (HsValBinds binds)))
= do binds' <- rnValBindsLHS fix_env binds
emptyFVs
)]
-rn_rec_stmt_lhs fix_env (L loc (RecStmt stmts _ _ _ _)) -- Flatten Rec inside Rec
+rn_rec_stmt_lhs fix_env (L _ (RecStmt stmts _ _ _ _)) -- Flatten Rec inside Rec
= rn_rec_stmts_lhs fix_env stmts
rn_rec_stmt_lhs _ stmt@(L _ (ParStmt _)) -- Syntactically illegal in mdo
rn_rec_stmt_lhs _ stmt@(L _ (GroupStmt _ _)) -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt" (ppr stmt)
-
-rn_rec_stmts_lhs :: UniqFM (Located Fixity) -- mini fixity env for the names we're about to bind
- -- these fixities need to be brought into scope with the names
+
+rn_rec_stmt_lhs _ (L _ (LetStmt EmptyLocalBinds))
+ = panic "rn_rec_stmt LetStmt EmptyLocalBinds"
+
+rn_rec_stmts_lhs :: MiniFixityEnv
-> [LStmt RdrName]
-> RnM [(LStmtLR Name RdrName, FreeVars)]
rn_rec_stmts_lhs fix_env stmts =
-- First do error checking: we need to check for dups here because we
-- don't bind all of the variables from the Stmt at once
-- with bindLocatedLocals.
- checkDupNames doc boundNames
+ checkDupRdrNames doc boundNames
mappM (rn_rec_stmt_lhs fix_env) stmts `thenM` \ ls -> returnM (concat ls)
-- Rename a Stmt that is inside a RecStmt (or mdo)
-- Assumes all binders are already in scope
-- Turns each stmt into a singleton Stmt
-rn_rec_stmt all_bndrs (L loc (ExprStmt expr _ _)) _
+rn_rec_stmt _ (L loc (ExprStmt expr _ _)) _
= rnLExpr expr `thenM` \ (expr', fvs) ->
lookupSyntaxName thenMName `thenM` \ (then_op, fvs1) ->
returnM [(emptyNameSet, fvs `plusFV` fvs1, emptyNameSet,
L loc (ExprStmt expr' then_op placeHolderType))]
-rn_rec_stmt all_bndrs (L loc (BindStmt pat' expr _ _)) fv_pat
+rn_rec_stmt _ (L loc (BindStmt pat' expr _ _)) fv_pat
= rnLExpr expr `thenM` \ (expr', fv_expr) ->
lookupSyntaxName bindMName `thenM` \ (bind_op, fvs1) ->
lookupSyntaxName failMName `thenM` \ (fail_op, fvs2) ->
returnM [(bndrs, fvs, bndrs `intersectNameSet` fvs,
L loc (BindStmt pat' expr' bind_op fail_op))]
-rn_rec_stmt all_bndrs (L loc (LetStmt binds@(HsIPBinds _))) _
- = do { addErr (badIpBinds (ptext SLIT("an mdo expression")) binds)
- ; failM }
+rn_rec_stmt _ (L _ (LetStmt binds@(HsIPBinds _))) _
+ = failWith (badIpBinds (ptext (sLit "an mdo expression")) binds)
rn_rec_stmt all_bndrs (L loc (LetStmt (HsValBinds binds'))) _ = do
(binds', du_binds) <-
-- fixities and unused are handled above in rn_rec_stmts_and_then
- rnValBindsRHS all_bndrs binds'
+ rnValBindsRHS (mkNameSet all_bndrs) binds'
returnM [(duDefs du_binds, duUses du_binds,
emptyNameSet, L loc (LetStmt (HsValBinds binds')))]
-- no RecStmt case becuase they get flattened above when doing the LHSes
-rn_rec_stmt all_bndrs stmt@(L loc (RecStmt stmts _ _ _ _)) _
+rn_rec_stmt _ stmt@(L _ (RecStmt _ _ _ _ _)) _
= pprPanic "rn_rec_stmt: RecStmt" (ppr stmt)
-rn_rec_stmt all_bndrs stmt@(L _ (ParStmt _)) _ -- Syntactically illegal in mdo
+rn_rec_stmt _ stmt@(L _ (ParStmt _)) _ -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt: ParStmt" (ppr stmt)
-rn_rec_stmt all_bndrs stmt@(L _ (TransformStmt _ _ _)) _ -- Syntactically illegal in mdo
+rn_rec_stmt _ stmt@(L _ (TransformStmt _ _ _)) _ -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt: TransformStmt" (ppr stmt)
-rn_rec_stmt all_bndrs stmt@(L _ (GroupStmt _ _)) _ -- Syntactically illegal in mdo
+rn_rec_stmt _ stmt@(L _ (GroupStmt _ _)) _ -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt: GroupStmt" (ppr stmt)
+rn_rec_stmt _ (L _ (LetStmt EmptyLocalBinds)) _
+ = panic "rn_rec_stmt: LetStmt EmptyLocalBinds"
+
rn_rec_stmts :: [Name] -> [(LStmtLR Name RdrName, FreeVars)] -> RnM [Segment (LStmt Name)]
rn_rec_stmts bndrs stmts = mappM (uncurry (rn_rec_stmt bndrs)) stmts `thenM` \ segs_s ->
returnM (concat segs_s)
srcSpanPrimLit :: SrcSpan -> HsExpr Name
srcSpanPrimLit span = HsLit (HsStringPrim (mkFastString (showSDoc (ppr span))))
-mkAssertErrorExpr :: RnM (HsExpr Name, FreeVars)
+mkAssertErrorExpr :: RnM (HsExpr Name)
-- Return an expression for (assertError "Foo.hs:27")
mkAssertErrorExpr
= getSrcSpanM `thenM` \ sloc ->
- let
- expr = HsApp (L sloc (HsVar assertErrorName))
- (L sloc (srcSpanPrimLit sloc))
- in
- returnM (expr, emptyFVs)
+ return (HsApp (L sloc (HsVar assertErrorName))
+ (L sloc (srcSpanPrimLit sloc)))
\end{code}
+Note [Adding the implicit parameter to 'assert']
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The renamer transforms (assert e1 e2) to (assert "Foo.hs:27" e1 e2).
+By doing this in the renamer we allow the typechecker to just see the
+expanded application and do the right thing. But it's not really
+the Right Thing because there's no way to "undo" if you want to see
+the original source code. We'll have fix this in due course, when
+we care more about being able to reconstruct the exact original
+program.
+
%************************************************************************
%* *
\subsubsection{Errors}
%************************************************************************
\begin{code}
-patSynErr e = do { addErr (sep [ptext SLIT("Pattern syntax in expression context:"),
- nest 4 (ppr e)])
- ; return (EWildPat, emptyFVs) }
+----------------------
+-- Checking when a particular Stmt is ok
+checkLetStmt :: HsStmtContext Name -> HsLocalBinds RdrName -> RnM ()
+checkLetStmt (ParStmtCtxt _) (HsIPBinds binds) = addErr (badIpBinds (ptext (sLit "a parallel list comprehension:")) binds)
+checkLetStmt _ctxt _binds = return ()
+ -- We do not allow implicit-parameter bindings in a parallel
+ -- list comprehension. I'm not sure what it might mean.
-parStmtErr = addErr (ptext SLIT("Illegal parallel list comprehension: use -XParallelListComp"))
+---------
+checkRecStmt :: HsStmtContext Name -> RnM ()
+checkRecStmt (MDoExpr {}) = return () -- Recursive stmt ok in 'mdo'
+checkRecStmt (DoExpr {}) = return () -- ..and in 'do' but only because of arrows:
+ -- proc x -> do { ...rec... }
+ -- We don't have enough context to distinguish this situation here
+ -- so we leave it to the type checker
+checkRecStmt ctxt = addErr msg
+ where
+ msg = ptext (sLit "Illegal 'rec' stmt in") <+> pprStmtContext ctxt
-transformStmtErr = addErr (ptext SLIT("Illegal transform or grouping list comprehension: use -XTransformListComp"))
-transformStmtOutsideListCompErr = addErr (ptext SLIT("Currently you may only use transform or grouping comprehensions within list comprehensions, not parallel array comprehensions"))
+---------
+checkParStmt :: HsStmtContext Name -> RnM ()
+checkParStmt _
+ = do { parallel_list_comp <- doptM Opt_ParallelListComp
+ ; checkErr parallel_list_comp msg }
+ where
+ msg = ptext (sLit "Illegal parallel list comprehension: use -XParallelListComp")
+
+---------
+checkTransformStmt :: HsStmtContext Name -> RnM ()
+checkTransformStmt ListComp -- Ensure we are really within a list comprehension because otherwise the
+ -- desugarer will break when we come to operate on a parallel array
+ = do { transform_list_comp <- doptM Opt_TransformListComp
+ ; checkErr transform_list_comp msg }
+ where
+ msg = ptext (sLit "Illegal transform or grouping list comprehension: use -XTransformListComp")
+checkTransformStmt (ParStmtCtxt ctxt) = checkTransformStmt ctxt -- Ok to nest inside a parallel comprehension
+checkTransformStmt (TransformStmtCtxt ctxt) = checkTransformStmt ctxt -- Ok to nest inside a parallel comprehension
+checkTransformStmt ctxt = addErr msg
+ where
+ msg = ptext (sLit "Illegal transform or grouping in") <+> pprStmtContext ctxt
+
+---------
+sectionErr :: HsExpr RdrName -> SDoc
+sectionErr expr
+ = hang (ptext (sLit "A section must be enclosed in parentheses"))
+ 2 (ptext (sLit "thus:") <+> (parens (ppr expr)))
+
+patSynErr :: HsExpr RdrName -> RnM (HsExpr Name, FreeVars)
+patSynErr e = do { addErr (sep [ptext (sLit "Pattern syntax in expression context:"),
+ nest 4 (ppr e)])
+ ; return (EWildPat, emptyFVs) }
+badIpBinds :: Outputable a => SDoc -> a -> SDoc
badIpBinds what binds
- = hang (ptext SLIT("Implicit-parameter bindings illegal in") <+> what)
+ = hang (ptext (sLit "Implicit-parameter bindings illegal in") <+> what)
2 (ppr binds)
\end{code}
-
-