\begin{code}
module RnExpr (
- rnMatch, rnGRHSs, rnExpr, rnExprs, rnStmts,
- checkPrecMatch
+ rnLExpr, rnExpr, rnStmts
) where
#include "HsVersions.h"
-import {-# SOURCE #-} RnSource ( rnSrcDecls, rnBindsAndThen, rnBinds )
-
--- RnSource imports RnBinds.rnTopMonoBinds, RnExpr.rnExpr
--- RnBinds imports RnExpr.rnMatch, etc
--- RnExpr imports [boot] RnSource.rnSrcDecls, RnSource.rnBinds
-
+import RnSource ( rnSrcDecls, rnSplice, checkTH )
+import RnBinds ( rnLocalBindsAndThen, rnValBinds,
+ rnMatchGroup, trimWith )
import HsSyn
-import RdrHsSyn
import RnHsSyn
import TcRnMonad
import RnEnv
import OccName ( plusOccEnv )
-import RnNames ( importsFromLocalDecls )
-import RnTypes ( rnHsTypeFVs, rnPat, litFVs, rnOverLit, rnPatsAndThen,
- dupFieldErr, precParseErr, sectionPrecErr, patSigErr, checkTupSize )
-import CmdLineOpts ( DynFlag(..) )
-import BasicTypes ( Fixity(..), FixityDirection(..), negateFixity, compareFixity )
-import PrelNames ( hasKey, assertIdKey, assertErrorName,
+import RnNames ( getLocalDeclBinders, extendRdrEnvRn )
+import RnTypes ( rnHsTypeFVs, rnLPat, rnOverLit, rnPatsAndThen, rnLit,
+ mkOpFormRn, mkOpAppRn, mkNegAppRn, checkSectionPrec,
+ dupFieldErr, checkTupSize )
+import DynFlags ( DynFlag(..) )
+import BasicTypes ( FixityDirection(..) )
+import PrelNames ( thFAKE, hasKey, assertIdKey, assertErrorName,
loopAName, choiceAName, appAName, arrAName, composeAName, firstAName,
- negateName, monadNames, mfixName )
-import Name ( Name, nameOccName )
+ negateName, thenMName, bindMName, failMName )
+import Name ( Name, nameOccName, nameIsLocalOrFrom )
import NameSet
+import RdrName ( RdrName, emptyGlobalRdrEnv, plusGlobalRdrEnv, extendLocalRdrEnv, lookupLocalRdrEnv )
+import LoadIface ( loadHomeInterface )
import UnicodeUtil ( stringToUtf8 )
import UniqFM ( isNullUFM )
import UniqSet ( emptyUniqSet )
+import List ( nub )
import Util ( isSingleton )
-import List ( unzip4 )
import ListSetOps ( removeDups )
+import Maybes ( fromJust )
import Outputable
-import SrcLoc ( noSrcLoc )
+import SrcLoc ( Located(..), unLoc, getLoc, cmpLocated )
import FastString
-\end{code}
-
-************************************************************************
-* *
-\subsection{Match}
-* *
-************************************************************************
-
-\begin{code}
-rnMatch :: HsMatchContext Name -> RdrNameMatch -> RnM (RenamedMatch, FreeVars)
-
-rnMatch ctxt match@(Match pats maybe_rhs_sig grhss)
- = addSrcLoc (getMatchLoc match) $
-
- -- Deal with the rhs type signature
- bindPatSigTyVarsFV rhs_sig_tys $
- doptM Opt_GlasgowExts `thenM` \ opt_GlasgowExts ->
- (case maybe_rhs_sig of
- Nothing -> returnM (Nothing, emptyFVs)
- Just ty | opt_GlasgowExts -> rnHsTypeFVs doc_sig ty `thenM` \ (ty', ty_fvs) ->
- returnM (Just ty', ty_fvs)
- | otherwise -> addErr (patSigErr ty) `thenM_`
- returnM (Nothing, emptyFVs)
- ) `thenM` \ (maybe_rhs_sig', ty_fvs) ->
-
- -- Now the main event
- rnPatsAndThen ctxt True pats $ \ pats' ->
- rnGRHSs ctxt grhss `thenM` \ (grhss', grhss_fvs) ->
-
- returnM (Match pats' maybe_rhs_sig' grhss', grhss_fvs `plusFV` ty_fvs)
- -- The bindPatSigTyVarsFV and rnPatsAndThen will remove the bound FVs
- where
- rhs_sig_tys = case maybe_rhs_sig of
- Nothing -> []
- Just ty -> [ty]
- doc_sig = text "In a result type-signature"
+import List ( unzip4 )
\end{code}
%************************************************************************
%* *
-\subsubsection{Guarded right-hand sides (GRHSs)}
-%* *
-%************************************************************************
-
-\begin{code}
-rnGRHSs :: HsMatchContext Name -> RdrNameGRHSs -> RnM (RenamedGRHSs, FreeVars)
-
-rnGRHSs ctxt (GRHSs grhss binds _)
- = rnBindsAndThen binds $ \ binds' ->
- mapFvRn (rnGRHS ctxt) grhss `thenM` \ (grhss', fvGRHSs) ->
- returnM (GRHSs grhss' binds' placeHolderType, fvGRHSs)
-
-rnGRHS ctxt (GRHS guarded locn)
- = addSrcLoc locn $
- doptM Opt_GlasgowExts `thenM` \ opt_GlasgowExts ->
- checkM (opt_GlasgowExts || is_standard_guard guarded)
- (addWarn (nonStdGuardErr guarded)) `thenM_`
-
- rnStmts (PatGuard ctxt) guarded `thenM` \ (guarded', fvs) ->
- returnM (GRHS guarded' locn, fvs)
- where
- -- Standard Haskell 1.4 guards are just a single boolean
- -- expression, rather than a list of qualifiers as in the
- -- Glasgow extension
- is_standard_guard [ResultStmt _ _] = True
- is_standard_guard [ExprStmt _ _ _, ResultStmt _ _] = True
- is_standard_guard other = False
-\end{code}
-
-%************************************************************************
-%* *
\subsubsection{Expressions}
%* *
%************************************************************************
\begin{code}
-rnExprs :: [RdrNameHsExpr] -> RnM ([RenamedHsExpr], FreeVars)
+rnExprs :: [LHsExpr RdrName] -> RnM ([LHsExpr Name], FreeVars)
rnExprs ls = rnExprs' ls emptyUniqSet
where
rnExprs' [] acc = returnM ([], acc)
rnExprs' (expr:exprs) acc
- = rnExpr expr `thenM` \ (expr', fvExpr) ->
+ = rnLExpr expr `thenM` \ (expr', fvExpr) ->
-- Now we do a "seq" on the free vars because typically it's small
-- or empty, especially in very long lists of constants
Variables. We look up the variable and return the resulting name.
\begin{code}
-rnExpr :: RdrNameHsExpr -> RnM (RenamedHsExpr, FreeVars)
+rnLExpr :: LHsExpr RdrName -> RnM (LHsExpr Name, FreeVars)
+rnLExpr = wrapLocFstM rnExpr
+
+rnExpr :: HsExpr RdrName -> RnM (HsExpr Name, FreeVars)
rnExpr (HsVar v)
= lookupOccRn v `thenM` \ name ->
returnM (HsIPVar name, emptyFVs)
rnExpr (HsLit lit)
- = litFVs lit `thenM` \ fvs ->
- returnM (HsLit lit, fvs)
+ = rnLit lit `thenM_`
+ returnM (HsLit lit, emptyFVs)
rnExpr (HsOverLit lit)
= rnOverLit lit `thenM` \ (lit', fvs) ->
returnM (HsOverLit lit', fvs)
-rnExpr (HsLam match)
- = rnMatch LambdaExpr match `thenM` \ (match', fvMatch) ->
- returnM (HsLam match', fvMatch)
-
rnExpr (HsApp fun arg)
- = rnExpr fun `thenM` \ (fun',fvFun) ->
- rnExpr arg `thenM` \ (arg',fvArg) ->
+ = rnLExpr fun `thenM` \ (fun',fvFun) ->
+ rnLExpr arg `thenM` \ (arg',fvArg) ->
returnM (HsApp fun' arg', fvFun `plusFV` fvArg)
rnExpr (OpApp e1 op _ e2)
- = rnExpr e1 `thenM` \ (e1', fv_e1) ->
- rnExpr e2 `thenM` \ (e2', fv_e2) ->
- rnExpr op `thenM` \ (op'@(HsVar op_name), fv_op) ->
+ = rnLExpr e1 `thenM` \ (e1', fv_e1) ->
+ rnLExpr e2 `thenM` \ (e2', fv_e2) ->
+ rnLExpr op `thenM` \ (op'@(L _ (HsVar op_name)), fv_op) ->
-- Deal with fixity
-- When renaming code synthesised from "deriving" declarations
fv_e1 `plusFV` fv_op `plusFV` fv_e2)
rnExpr (NegApp e _)
- = rnExpr e `thenM` \ (e', fv_e) ->
+ = rnLExpr e `thenM` \ (e', fv_e) ->
lookupSyntaxName negateName `thenM` \ (neg_name, fv_neg) ->
mkNegAppRn e' neg_name `thenM` \ final_e ->
returnM (final_e, fv_e `plusFV` fv_neg)
rnExpr (HsPar e)
- = rnExpr e `thenM` \ (e', fvs_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.
-rnExpr e@(HsBracket br_body loc)
- = addSrcLoc loc $
- checkTH e "bracket" `thenM_`
+rnExpr e@(HsBracket br_body)
+ = checkTH e "bracket" `thenM_`
rnBracket br_body `thenM` \ (body', fvs_e) ->
- returnM (HsBracket body' loc, fvs_e)
+ returnM (HsBracket body', fvs_e)
-rnExpr e@(HsSplice n splice loc)
- = addSrcLoc loc $
- checkTH e "splice" `thenM_`
- newLocalsRn [(n,loc)] `thenM` \ [n'] ->
- rnExpr splice `thenM` \ (splice', fvs_e) ->
- returnM (HsSplice n' splice' loc, fvs_e)
+rnExpr e@(HsSpliceE splice)
+ = rnSplice splice `thenM` \ (splice', fvs) ->
+ returnM (HsSpliceE splice', fvs)
rnExpr section@(SectionL expr op)
- = rnExpr expr `thenM` \ (expr', fvs_expr) ->
- rnExpr op `thenM` \ (op', fvs_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)
rnExpr section@(SectionR op expr)
- = rnExpr op `thenM` \ (op', fvs_op) ->
- rnExpr expr `thenM` \ (expr', fvs_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)
rnExpr (HsCoreAnn ann expr)
- = rnExpr expr `thenM` \ (expr', fvs_expr) ->
+ = rnLExpr expr `thenM` \ (expr', fvs_expr) ->
returnM (HsCoreAnn ann expr', fvs_expr)
rnExpr (HsSCC lbl expr)
- = rnExpr expr `thenM` \ (expr', fvs_expr) ->
+ = rnLExpr expr `thenM` \ (expr', fvs_expr) ->
returnM (HsSCC lbl expr', fvs_expr)
-rnExpr (HsCase expr ms src_loc)
- = addSrcLoc src_loc $
- rnExpr expr `thenM` \ (new_expr, e_fvs) ->
- mapFvRn (rnMatch CaseAlt) ms `thenM` \ (new_ms, ms_fvs) ->
- returnM (HsCase new_expr new_ms src_loc, e_fvs `plusFV` ms_fvs)
+rnExpr (HsLam matches)
+ = rnMatchGroup LambdaExpr matches `thenM` \ (matches', fvMatch) ->
+ returnM (HsLam matches', fvMatch)
+
+rnExpr (HsCase expr matches)
+ = rnLExpr expr `thenM` \ (new_expr, e_fvs) ->
+ rnMatchGroup CaseAlt matches `thenM` \ (new_matches, ms_fvs) ->
+ returnM (HsCase new_expr new_matches, e_fvs `plusFV` ms_fvs)
rnExpr (HsLet binds expr)
- = rnBindsAndThen binds $ \ binds' ->
- rnExpr expr `thenM` \ (expr',fvExpr) ->
+ = rnLocalBindsAndThen binds $ \ binds' ->
+ rnLExpr expr `thenM` \ (expr',fvExpr) ->
returnM (HsLet binds' expr', fvExpr)
-rnExpr e@(HsDo do_or_lc stmts _ _ src_loc)
- = addSrcLoc src_loc $
- rnStmts do_or_lc stmts `thenM` \ (stmts', fvs) ->
-
- -- Check the statement list ends in an expression
- case last stmts' of {
- ResultStmt _ _ -> returnM () ;
- _ -> addErr (doStmtListErr do_or_lc e)
- } `thenM_`
-
- -- Generate the rebindable syntax for the monad
- lookupSyntaxNames syntax_names `thenM` \ (syntax_names', monad_fvs) ->
-
- returnM (HsDo do_or_lc stmts' syntax_names' placeHolderType src_loc,
- fvs `plusFV` monad_fvs)
- where
- syntax_names = case do_or_lc of
- DoExpr -> monadNames
- MDoExpr -> monadNames ++ [mfixName]
- other -> []
+rnExpr e@(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) }
rnExpr (ExplicitList _ exps)
= rnExprs exps `thenM` \ (exps', fvs) ->
tup_size = length exps
tycon_name = tupleTyCon_name boxity tup_size
-rnExpr (RecordCon con_id rbinds)
- = lookupOccRn con_id `thenM` \ conname ->
+rnExpr (RecordCon con_id _ rbinds)
+ = lookupLocatedOccRn con_id `thenM` \ conname ->
rnRbinds "construction" rbinds `thenM` \ (rbinds', fvRbinds) ->
- returnM (RecordCon conname rbinds', fvRbinds `addOneFV` conname)
+ returnM (RecordCon conname noPostTcExpr rbinds',
+ fvRbinds `addOneFV` unLoc conname)
-rnExpr (RecordUpd expr rbinds)
- = rnExpr expr `thenM` \ (expr', fvExpr) ->
+rnExpr (RecordUpd expr rbinds _ _)
+ = rnLExpr expr `thenM` \ (expr', fvExpr) ->
rnRbinds "update" rbinds `thenM` \ (rbinds', fvRbinds) ->
- returnM (RecordUpd expr' rbinds', fvExpr `plusFV` fvRbinds)
+ returnM (RecordUpd expr' rbinds' placeHolderType placeHolderType,
+ fvExpr `plusFV` fvRbinds)
rnExpr (ExprWithTySig expr pty)
- = rnExpr expr `thenM` \ (expr', fvExpr) ->
+ = rnLExpr expr `thenM` \ (expr', fvExpr) ->
rnHsTypeFVs doc pty `thenM` \ (pty', fvTy) ->
returnM (ExprWithTySig expr' pty', fvExpr `plusFV` fvTy)
where
doc = text "In an expression type signature"
-rnExpr (HsIf p b1 b2 src_loc)
- = addSrcLoc src_loc $
- rnExpr p `thenM` \ (p', fvP) ->
- rnExpr b1 `thenM` \ (b1', fvB1) ->
- rnExpr b2 `thenM` \ (b2', fvB2) ->
- returnM (HsIf p' b1' b2' src_loc, plusFVs [fvP, fvB1, fvB2])
+rnExpr (HsIf p b1 b2)
+ = rnLExpr p `thenM` \ (p', fvP) ->
+ rnLExpr b1 `thenM` \ (b1', fvB1) ->
+ rnLExpr b2 `thenM` \ (b2', fvB2) ->
+ returnM (HsIf p' b1' b2', plusFVs [fvP, fvB1, fvB2])
rnExpr (HsType a)
= rnHsTypeFVs doc a `thenM` \ (t, fvT) ->
where
doc = text "In a type argument"
-rnExpr (ArithSeqIn seq)
+rnExpr (ArithSeq _ seq)
= rnArithSeq seq `thenM` \ (new_seq, fvs) ->
- returnM (ArithSeqIn new_seq, fvs)
+ returnM (ArithSeq noPostTcExpr new_seq, fvs)
-rnExpr (PArrSeqIn seq)
+rnExpr (PArrSeq _ seq)
= rnArithSeq seq `thenM` \ (new_seq, fvs) ->
- returnM (PArrSeqIn new_seq, fvs)
+ returnM (PArrSeq noPostTcExpr new_seq, fvs)
\end{code}
These three are pattern syntax appearing in expressions.
%************************************************************************
\begin{code}
-rnExpr (HsProc pat body src_loc)
- = addSrcLoc src_loc $
- rnPatsAndThen ProcExpr True [pat] $ \ [pat'] ->
- rnCmdTop body `thenM` \ (body',fvBody) ->
- returnM (HsProc pat' body' src_loc, fvBody)
-
-rnExpr (HsArrApp arrow arg _ ho rtl srcloc)
- = rnExpr arrow `thenM` \ (arrow',fvArrow) ->
- rnExpr arg `thenM` \ (arg',fvArg) ->
- returnM (HsArrApp arrow' arg' placeHolderType ho rtl srcloc,
+rnExpr (HsProc pat body)
+ = newArrowScope $
+ rnPatsAndThen ProcExpr [pat] $ \ [pat'] ->
+ rnCmdTop body `thenM` \ (body',fvBody) ->
+ returnM (HsProc pat' body', fvBody)
+
+rnExpr (HsArrApp arrow arg _ ho rtl)
+ = select_arrow_scope (rnLExpr arrow) `thenM` \ (arrow',fvArrow) ->
+ rnLExpr arg `thenM` \ (arg',fvArg) ->
+ returnM (HsArrApp arrow' arg' placeHolderType ho rtl,
fvArrow `plusFV` fvArg)
+ where
+ select_arrow_scope tc = case ho of
+ HsHigherOrderApp -> tc
+ HsFirstOrderApp -> escapeArrowScope tc
-- infix form
-rnExpr (HsArrForm op (Just _) [arg1, arg2] srcloc)
- = rnExpr op `thenM` \ (op'@(HsVar op_name),fv_op) ->
+rnExpr (HsArrForm op (Just _) [arg1, arg2])
+ = escapeArrowScope (rnLExpr op)
+ `thenM` \ (op'@(L _ (HsVar op_name)),fv_op) ->
rnCmdTop arg1 `thenM` \ (arg1',fv_arg1) ->
rnCmdTop arg2 `thenM` \ (arg2',fv_arg2) ->
returnM (final_e,
fv_arg1 `plusFV` fv_op `plusFV` fv_arg2)
-rnExpr (HsArrForm op fixity cmds srcloc)
- = rnExpr op `thenM` \ (op',fvOp) ->
- rnCmdArgs cmds `thenM` \ (cmds',fvCmds) ->
- returnM (HsArrForm op' fixity cmds' srcloc,
- fvOp `plusFV` fvCmds)
-
----------------------------
--- Deal with fixity (cf mkOpAppRn for the method)
-
-mkOpFormRn :: RenamedHsCmdTop -- Left operand; already rearranged
- -> RenamedHsExpr -> Fixity -- Operator and fixity
- -> RenamedHsCmdTop -- Right operand (not an infix)
- -> RnM RenamedHsCmd
-
----------------------------
--- (e11 `op1` e12) `op2` e2
-mkOpFormRn a1@(HsCmdTop (HsArrForm op1 (Just fix1) [a11,a12] loc1) _ _ _) op2 fix2 a2
- | nofix_error
- = addErr (precParseErr (ppr_op op1,fix1) (ppr_op op2,fix2)) `thenM_`
- returnM (HsArrForm op2 (Just fix2) [a1, a2] loc1)
-
- | associate_right
- = mkOpFormRn a12 op2 fix2 a2 `thenM` \ new_c ->
- returnM (HsArrForm op1 (Just fix1)
- [a11, HsCmdTop new_c [] placeHolderType []] loc1)
- where
- (nofix_error, associate_right) = compareFixity fix1 fix2
-
----------------------------
--- Default case
-mkOpFormRn arg1 op fix arg2 -- Default case, no rearrangment
- = returnM (HsArrForm op (Just fix) [arg1, arg2] noSrcLoc)
+rnExpr (HsArrForm op fixity cmds)
+ = escapeArrowScope (rnLExpr op) `thenM` \ (op',fvOp) ->
+ rnCmdArgs cmds `thenM` \ (cmds',fvCmds) ->
+ returnM (HsArrForm op' fixity cmds', fvOp `plusFV` fvCmds)
+rnExpr other = pprPanic "rnExpr: unexpected expression" (ppr other)
+ -- DictApp, DictLam, TyApp, TyLam
\end{code}
rnCmdArgs args `thenM` \ (args',fvArgs) ->
returnM (arg':args', fvArg `plusFV` fvArgs)
-rnCmdTop (HsCmdTop cmd _ _ _)
- = rnExpr (convertOpFormsCmd cmd) `thenM` \ (cmd', fvCmd) ->
- let
+
+rnCmdTop = wrapLocFstM rnCmdTop'
+ where
+ rnCmdTop' (HsCmdTop cmd _ _ _)
+ = rnLExpr (convertOpFormsLCmd cmd) `thenM` \ (cmd', fvCmd) ->
+ let
cmd_names = [arrAName, composeAName, firstAName] ++
- nameSetToList (methodNamesCmd cmd')
- in
+ nameSetToList (methodNamesCmd (unLoc cmd'))
+ in
-- Generate the rebindable syntax for the monad
- lookupSyntaxNames cmd_names `thenM` \ (cmd_names', cmd_fvs) ->
+ lookupSyntaxTable cmd_names `thenM` \ (cmd_names', cmd_fvs) ->
- returnM (HsCmdTop cmd' [] placeHolderType cmd_names',
+ returnM (HsCmdTop cmd' [] placeHolderType cmd_names',
fvCmd `plusFV` cmd_fvs)
---------------------------------------------------
-- convert OpApp's in a command context to HsArrForm's
-convertOpFormsCmd :: HsCmd id -> HsCmd id
+convertOpFormsLCmd :: LHsCmd id -> LHsCmd id
+convertOpFormsLCmd = fmap convertOpFormsCmd
-convertOpFormsCmd (HsApp c e) = HsApp (convertOpFormsCmd c) e
+convertOpFormsCmd :: HsCmd id -> HsCmd id
+convertOpFormsCmd (HsApp c e) = HsApp (convertOpFormsLCmd c) e
convertOpFormsCmd (HsLam match) = HsLam (convertOpFormsMatch match)
-
convertOpFormsCmd (OpApp c1 op fixity c2)
= let
- arg1 = HsCmdTop (convertOpFormsCmd c1) [] placeHolderType []
- arg2 = HsCmdTop (convertOpFormsCmd c2) [] placeHolderType []
+ arg1 = L (getLoc c1) $ HsCmdTop (convertOpFormsLCmd c1) [] placeHolderType []
+ arg2 = L (getLoc c2) $ HsCmdTop (convertOpFormsLCmd c2) [] placeHolderType []
in
- HsArrForm op (Just fixity) [arg1, arg2] noSrcLoc
+ HsArrForm op (Just fixity) [arg1, arg2]
-convertOpFormsCmd (HsPar c) = HsPar (convertOpFormsCmd c)
+convertOpFormsCmd (HsPar c) = HsPar (convertOpFormsLCmd c)
-convertOpFormsCmd (HsCase exp matches locn)
- = HsCase exp (map convertOpFormsMatch matches) locn
+-- gaw 2004
+convertOpFormsCmd (HsCase exp matches)
+ = HsCase exp (convertOpFormsMatch matches)
-convertOpFormsCmd (HsIf exp c1 c2 locn)
- = HsIf exp (convertOpFormsCmd c1) (convertOpFormsCmd c2) locn
+convertOpFormsCmd (HsIf exp c1 c2)
+ = HsIf exp (convertOpFormsLCmd c1) (convertOpFormsLCmd c2)
convertOpFormsCmd (HsLet binds cmd)
- = HsLet binds (convertOpFormsCmd cmd)
+ = HsLet binds (convertOpFormsLCmd cmd)
-convertOpFormsCmd (HsDo ctxt stmts ids ty locn)
- = HsDo ctxt (map convertOpFormsStmt stmts) ids ty locn
+convertOpFormsCmd (HsDo ctxt stmts body ty)
+ = HsDo ctxt (map (fmap convertOpFormsStmt) stmts)
+ (convertOpFormsLCmd body) ty
-- Anything else is unchanged. This includes HsArrForm (already done),
-- things with no sub-commands, and illegal commands (which will be
-- caught by the type checker)
convertOpFormsCmd c = c
-convertOpFormsStmt (BindStmt pat cmd locn)
- = BindStmt pat (convertOpFormsCmd cmd) locn
-convertOpFormsStmt (ResultStmt cmd locn)
- = ResultStmt (convertOpFormsCmd cmd) locn
-convertOpFormsStmt (ExprStmt cmd ty locn)
- = ExprStmt (convertOpFormsCmd cmd) ty locn
-convertOpFormsStmt (RecStmt stmts lvs rvs es)
- = RecStmt (map convertOpFormsStmt stmts) lvs rvs es
+convertOpFormsStmt (BindStmt pat cmd _ _)
+ = BindStmt pat (convertOpFormsLCmd cmd) noSyntaxExpr noSyntaxExpr
+convertOpFormsStmt (ExprStmt cmd _ _)
+ = ExprStmt (convertOpFormsLCmd cmd) noSyntaxExpr placeHolderType
+convertOpFormsStmt (RecStmt stmts lvs rvs es binds)
+ = RecStmt (map (fmap convertOpFormsStmt) stmts) lvs rvs es binds
convertOpFormsStmt stmt = stmt
-convertOpFormsMatch (Match pat mty grhss)
- = Match pat mty (convertOpFormsGRHSs grhss)
+convertOpFormsMatch (MatchGroup ms ty)
+ = MatchGroup (map (fmap convert) ms) ty
+ where convert (Match pat mty grhss)
+ = Match pat mty (convertOpFormsGRHSs grhss)
-convertOpFormsGRHSs (GRHSs grhss binds ty)
- = GRHSs (map convertOpFormsGRHS grhss) binds ty
+convertOpFormsGRHSs (GRHSs grhss binds)
+ = GRHSs (map convertOpFormsGRHS grhss) binds
-convertOpFormsGRHS (GRHS stmts locn)
- = let
- (ResultStmt cmd locn') = last stmts
- in
- GRHS (init stmts ++ [ResultStmt (convertOpFormsCmd cmd) locn']) locn
+convertOpFormsGRHS = fmap convert
+ where
+ convert (GRHS stmts cmd) = GRHS stmts (convertOpFormsLCmd cmd)
---------------------------------------------------
type CmdNeeds = FreeVars -- Only inhabitants are
-- appAName, choiceAName, loopAName
-- find what methods the Cmd needs (loop, choice, apply)
+methodNamesLCmd :: LHsCmd Name -> CmdNeeds
+methodNamesLCmd = methodNamesCmd . unLoc
+
methodNamesCmd :: HsCmd Name -> CmdNeeds
-methodNamesCmd cmd@(HsArrApp _arrow _arg _ HsFirstOrderApp _rtl _srcloc)
+methodNamesCmd cmd@(HsArrApp _arrow _arg _ HsFirstOrderApp _rtl)
= emptyFVs
-methodNamesCmd cmd@(HsArrApp _arrow _arg _ HsHigherOrderApp _rtl _srcloc)
+methodNamesCmd cmd@(HsArrApp _arrow _arg _ HsHigherOrderApp _rtl)
= unitFV appAName
methodNamesCmd cmd@(HsArrForm {}) = emptyFVs
-methodNamesCmd (HsPar c) = methodNamesCmd c
+methodNamesCmd (HsPar c) = methodNamesLCmd c
-methodNamesCmd (HsIf p c1 c2 loc)
- = methodNamesCmd c1 `plusFV` methodNamesCmd c2 `addOneFV` choiceAName
+methodNamesCmd (HsIf p c1 c2)
+ = methodNamesLCmd c1 `plusFV` methodNamesLCmd c2 `addOneFV` choiceAName
-methodNamesCmd (HsLet b c) = methodNamesCmd c
+methodNamesCmd (HsLet b c) = methodNamesLCmd c
-methodNamesCmd (HsDo sc stmts rbs ty loc) = methodNamesStmts stmts
+methodNamesCmd (HsDo sc stmts body ty)
+ = methodNamesStmts stmts `plusFV` methodNamesLCmd body
-methodNamesCmd (HsApp c e) = methodNamesCmd c
+methodNamesCmd (HsApp c e) = methodNamesLCmd c
methodNamesCmd (HsLam match) = methodNamesMatch match
-methodNamesCmd (HsCase scrut matches loc)
- = plusFVs (map methodNamesMatch matches) `addOneFV` choiceAName
+methodNamesCmd (HsCase scrut matches)
+ = methodNamesMatch matches `addOneFV` choiceAName
methodNamesCmd other = emptyFVs
-- Other forms can't occur in commands, but it's not convenient
-- The type checker will complain later
---------------------------------------------------
-methodNamesMatch (Match pats sig_ty grhss) = methodNamesGRHSs grhss
+methodNamesMatch (MatchGroup ms ty)
+ = plusFVs (map do_one ms)
+ where
+ do_one (L _ (Match pats sig_ty grhss)) = methodNamesGRHSs grhss
-------------------------------------------------
-methodNamesGRHSs (GRHSs grhss binds ty) = plusFVs (map methodNamesGRHS grhss)
+-- gaw 2004
+methodNamesGRHSs (GRHSs grhss binds) = plusFVs (map methodNamesGRHS grhss)
-------------------------------------------------
-methodNamesGRHS (GRHS stmts loc) = methodNamesStmt (last stmts)
+methodNamesGRHS (L _ (GRHS stmts rhs)) = methodNamesLCmd rhs
---------------------------------------------------
-methodNamesStmts stmts = plusFVs (map methodNamesStmt stmts)
+methodNamesStmts stmts = plusFVs (map methodNamesLStmt stmts)
---------------------------------------------------
-methodNamesStmt (ResultStmt cmd loc) = methodNamesCmd cmd
-methodNamesStmt (ExprStmt cmd ty loc) = methodNamesCmd cmd
-methodNamesStmt (BindStmt pat cmd loc) = methodNamesCmd cmd
-methodNamesStmt (RecStmt stmts lvs rvs es)
+methodNamesLStmt = methodNamesStmt . unLoc
+
+methodNamesStmt (ExprStmt cmd _ _) = methodNamesLCmd cmd
+methodNamesStmt (BindStmt pat cmd _ _) = methodNamesLCmd cmd
+methodNamesStmt (RecStmt stmts _ _ _ _)
= methodNamesStmts stmts `addOneFV` loopAName
methodNamesStmt (LetStmt b) = emptyFVs
methodNamesStmt (ParStmt ss) = emptyFVs
\begin{code}
rnArithSeq (From expr)
- = rnExpr expr `thenM` \ (expr', fvExpr) ->
+ = rnLExpr expr `thenM` \ (expr', fvExpr) ->
returnM (From expr', fvExpr)
rnArithSeq (FromThen expr1 expr2)
- = rnExpr expr1 `thenM` \ (expr1', fvExpr1) ->
- rnExpr expr2 `thenM` \ (expr2', fvExpr2) ->
+ = rnLExpr expr1 `thenM` \ (expr1', fvExpr1) ->
+ rnLExpr expr2 `thenM` \ (expr2', fvExpr2) ->
returnM (FromThen expr1' expr2', fvExpr1 `plusFV` fvExpr2)
rnArithSeq (FromTo expr1 expr2)
- = rnExpr expr1 `thenM` \ (expr1', fvExpr1) ->
- rnExpr expr2 `thenM` \ (expr2', fvExpr2) ->
+ = rnLExpr expr1 `thenM` \ (expr1', fvExpr1) ->
+ rnLExpr expr2 `thenM` \ (expr2', fvExpr2) ->
returnM (FromTo expr1' expr2', fvExpr1 `plusFV` fvExpr2)
rnArithSeq (FromThenTo expr1 expr2 expr3)
- = rnExpr expr1 `thenM` \ (expr1', fvExpr1) ->
- rnExpr expr2 `thenM` \ (expr2', fvExpr2) ->
- rnExpr expr3 `thenM` \ (expr3', fvExpr3) ->
+ = rnLExpr expr1 `thenM` \ (expr1', fvExpr1) ->
+ rnLExpr expr2 `thenM` \ (expr2', fvExpr2) ->
+ rnLExpr expr3 `thenM` \ (expr3', fvExpr3) ->
returnM (FromThenTo expr1' expr2' expr3',
plusFVs [fvExpr1, fvExpr2, fvExpr3])
\end{code}
mapFvRn rn_rbind rbinds `thenM` \ (rbinds', fvRbind) ->
returnM (rbinds', fvRbind)
where
- (_, dup_fields) = removeDups compare [ f | (f,_) <- rbinds ]
+ (_, dup_fields) = removeDups cmpLocated [ f | (f,_) <- rbinds ]
- field_dup_err dups = addErr (dupFieldErr str dups)
+ field_dup_err dups = mappM_ (\f -> addLocErr f (dupFieldErr str)) dups
rn_rbind (field, expr)
- = lookupGlobalOccRn field `thenM` \ fieldname ->
- rnExpr expr `thenM` \ (expr', fvExpr) ->
- returnM ((fieldname, expr'), fvExpr `addOneFV` fieldname)
+ = lookupLocatedGlobalOccRn field `thenM` \ fieldname ->
+ rnLExpr expr `thenM` \ (expr', fvExpr) ->
+ returnM ((fieldname, expr'), fvExpr `addOneFV` unLoc fieldname)
\end{code}
%************************************************************************
%************************************************************************
\begin{code}
-rnBracket (VarBr n) = lookupOccRn n `thenM` \ name ->
- returnM (VarBr name, unitFV name)
-rnBracket (ExpBr e) = rnExpr e `thenM` \ (e', fvs) ->
- returnM (ExpBr e', fvs)
-rnBracket (PatBr p) = rnPat p `thenM` \ (p', fvs) ->
- returnM (PatBr p', fvs)
-rnBracket (TypBr t) = rnHsTypeFVs doc t `thenM` \ (t', fvs) ->
- returnM (TypBr t', fvs)
+rnBracket (VarBr n) = do { name <- lookupOccRn n
+ ; this_mod <- getModule
+ ; checkM (nameIsLocalOrFrom this_mod name) $ -- Reason: deprecation checking asumes the
+ do { loadHomeInterface msg name -- home interface is loaded, and this is 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")
+
+rnBracket (ExpBr e) = do { (e', fvs) <- rnLExpr e
+ ; return (ExpBr e', fvs) }
+rnBracket (PatBr p) = do { (p', fvs) <- rnLPat p
+ ; return (PatBr p', fvs) }
+rnBracket (TypBr t) = do { (t', fvs) <- rnHsTypeFVs doc t
+ ; return (TypBr t', fvs) }
where
doc = ptext SLIT("In a Template-Haskell quoted type")
rnBracket (DecBr group)
- = importsFromLocalDecls group `thenM` \ (rdr_env, avails) ->
- -- Discard avails (not useful here)
-
- updGblEnv (\gbl -> gbl { tcg_rdr_env = tcg_rdr_env gbl `plusOccEnv` rdr_env}) $
- -- Notice plusOccEnv, not plusGlobalRdrEnv. In this situation we want
- -- to *shadow* top-level bindings. E.g.
+ = do { gbl_env <- getGblEnv
+
+ ; let gbl_env1 = gbl_env { tcg_mod = thFAKE }
+ -- Note the 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.
+
+ ; names <- getLocalDeclBinders gbl_env1 group
+ ; rdr_env' <- extendRdrEnvRn emptyGlobalRdrEnv names
+ -- Furthermore, the names in the bracket shouldn't conflict with
+ -- existing top-level names E.g.
-- foo = 1
-- bar = [d| foo = 1|]
- -- So we drop down to plusOccEnv. (Perhaps there should be a fn in RdrName.)
-
- rnSrcDecls group `thenM` \ (tcg_env, group') ->
- -- Discard the tcg_env; it contains only extra info about fixity
- let
- dus = tcg_dus tcg_env
- in
- returnM (DecBr group', allUses dus)
+ -- But both 'foo's get a LocalDef provenance, so we'd get a complaint unless
+ -- we start with an emptyGlobalRdrEnv
+
+ ; setGblEnv (gbl_env { tcg_rdr_env = tcg_rdr_env gbl_env1 `plusOccEnv` rdr_env',
+ tcg_dus = emptyDUs }) $ do
+ -- Notice plusOccEnv, not plusGlobalRdrEnv. In this situation we want
+ -- to *shadow* top-level bindings. (See the 'foo' example above.)
+ -- 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 emptyDUs is so that we just collect uses for this group alone
+
+ { (tcg_env, group') <- rnSrcDecls group
+ -- Discard the tcg_env; it contains only extra info about fixity
+ ; return (DecBr group', allUses (tcg_dus tcg_env)) } }
\end{code}
%************************************************************************
%************************************************************************
\begin{code}
-rnStmts :: HsStmtContext Name -> [RdrNameStmt] -> RnM ([RenamedStmt], FreeVars)
+rnStmts :: HsStmtContext Name -> [LStmt RdrName]
+ -> RnM (thing, FreeVars)
+ -> RnM (([LStmt Name], thing), FreeVars)
-rnStmts MDoExpr stmts = rnMDoStmts stmts
-rnStmts ctxt stmts = rnNormalStmts ctxt stmts
+rnStmts (MDoExpr _) = rnMDoStmts
+rnStmts ctxt = rnNormalStmts ctxt
-rnNormalStmts :: HsStmtContext Name -> [RdrNameStmt] -> RnM ([RenamedStmt], FreeVars)
+rnNormalStmts :: HsStmtContext Name -> [LStmt RdrName]
+ -> RnM (thing, FreeVars)
+ -> RnM (([LStmt Name], thing), FreeVars)
-- Used for cases *other* than recursive mdo
-- Implements nested scopes
-rnNormalStmts ctxt [] = returnM ([], emptyFVs)
- -- Happens at the end of the sub-lists of a ParStmts
-
-rnNormalStmts ctxt (ExprStmt expr _ src_loc : stmts)
- = addSrcLoc src_loc $
- rnExpr expr `thenM` \ (expr', fv_expr) ->
- rnNormalStmts ctxt stmts `thenM` \ (stmts', fvs) ->
- returnM (ExprStmt expr' placeHolderType src_loc : stmts',
- fv_expr `plusFV` fvs)
-
-rnNormalStmts ctxt [ResultStmt expr src_loc]
- = addSrcLoc src_loc $
- rnExpr expr `thenM` \ (expr', fv_expr) ->
- returnM ([ResultStmt expr' src_loc], fv_expr)
+rnNormalStmts ctxt [] thing_inside
+ = do { (thing, fvs) <- thing_inside
+ ; return (([],thing), fvs) }
-rnNormalStmts ctxt (BindStmt pat expr src_loc : stmts)
- = addSrcLoc src_loc $
- rnExpr expr `thenM` \ (expr', fv_expr) ->
- -- The binders do not scope over the expression
-
- let
- reportUnused =
- case ctxt of
- ParStmtCtxt{} -> False
- _ -> True
- in
- rnPatsAndThen (StmtCtxt ctxt) reportUnused [pat] $ \ [pat'] ->
- rnNormalStmts ctxt stmts `thenM` \ (stmts', fvs) ->
- returnM (BindStmt pat' expr' src_loc : stmts',
- fv_expr `plusFV` fvs) -- fv_expr shouldn't really be filtered by
- -- the rnPatsAndThen, but it does not matter
-
-rnNormalStmts ctxt (LetStmt binds : stmts)
- = checkErr (ok ctxt binds) (badIpBinds binds) `thenM_`
- rnBindsAndThen binds ( \ binds' ->
- rnNormalStmts ctxt stmts `thenM` \ (stmts', fvs) ->
- returnM (LetStmt binds' : stmts', fvs))
+rnNormalStmts ctxt (L loc stmt : stmts) thing_inside
+ = do { ((stmt', (stmts', thing)), fvs)
+ <- rnStmt ctxt stmt $
+ rnNormalStmts ctxt stmts thing_inside
+ ; return (((L loc stmt' : stmts'), thing), fvs) }
+
+rnStmt :: HsStmtContext Name -> Stmt RdrName
+ -> RnM (thing, FreeVars)
+ -> RnM ((Stmt Name, thing), FreeVars)
+
+rnStmt ctxt (ExprStmt expr _ _) thing_inside
+ = do { (expr', fv_expr) <- rnLExpr expr
+ ; (then_op, fvs1) <- lookupSyntaxName thenMName
+ ; (thing, fvs2) <- thing_inside
+ ; return ((ExprStmt expr' then_op placeHolderType, thing),
+ fv_expr `plusFV` fvs1 `plusFV` fvs2) }
+
+rnStmt ctxt (BindStmt pat expr _ _) thing_inside
+ = do { (expr', fv_expr) <- rnLExpr expr
+ -- The binders do not scope over the expression
+ ; (bind_op, fvs1) <- lookupSyntaxName bindMName
+ ; (fail_op, fvs2) <- lookupSyntaxName failMName
+ ; rnPatsAndThen (StmtCtxt ctxt) [pat] $ \ [pat'] -> do
+ { (thing, fvs3) <- thing_inside
+ ; return ((BindStmt pat' expr' bind_op fail_op, thing),
+ fv_expr `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) }}
+ -- 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 _) (IPBinds _) = False
- ok _ _ = True
-
-rnNormalStmts ctxt (ParStmt stmtss : stmts)
- = doptM Opt_GlasgowExts `thenM` \ opt_GlasgowExts ->
- checkM opt_GlasgowExts parStmtErr `thenM_`
- mapFvRn rn_branch stmtss `thenM` \ (stmtss', fv_stmtss) ->
- let
- bndrss :: [[Name]] -- NB: Name, not RdrName
- bndrss = map collectStmtsBinders stmtss'
- (bndrs, dups) = removeDups cmpByOcc (concat bndrss)
- in
- mappM dupErr dups `thenM` \ _ ->
- bindLocalNamesFV bndrs $
- -- Note: binders are returned in scope order, so one may
- -- shadow the next; e.g. x <- xs; x <- ys
- rnNormalStmts ctxt stmts `thenM` \ (stmts', fvs) ->
-
- -- Cut down the exported binders to just the ones needed in the body
- let
- used_bndrs_s = map (filter (`elemNameSet` fvs)) bndrss
- unused_bndrs = filter (not . (`elemNameSet` fvs)) bndrs
- in
- -- With processing of the branches and the tail of comprehension done,
- -- we can finally compute&report any unused ParStmt binders.
- warnUnusedMatches unused_bndrs `thenM_`
- returnM (ParStmt (stmtss' `zip` used_bndrs_s) : stmts',
- fv_stmtss `plusFV` fvs)
- where
- rn_branch (stmts, _) = rnNormalStmts (ParStmtCtxt ctxt) stmts
-
- cmpByOcc n1 n2 = nameOccName n1 `compare` nameOccName n2
- dupErr (v:_) = addErr (ptext SLIT("Duplicate binding in parallel list comprehension for:")
- <+> quotes (ppr v))
+ ok (ParStmtCtxt _) (HsIPBinds _) = False
+ ok _ _ = True
-rnNormalStmts ctxt (RecStmt rec_stmts _ _ _ : stmts)
- = bindLocalsRn doc (collectStmtsBinders rec_stmts) $ \ _ ->
- rn_rec_stmts rec_stmts `thenM` \ segs ->
- rnNormalStmts ctxt stmts `thenM` \ (stmts', fvs) ->
+rnStmt ctxt (RecStmt rec_stmts _ _ _ _) thing_inside
+ = bindLocatedLocalsRn doc (collectLStmtsBinders rec_stmts) $ \ bndrs ->
+ rn_rec_stmts bndrs rec_stmts `thenM` \ 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 (RecStmt rec_stmts' later_vars fwd_vars [] : stmts', uses `plusFV` fvs)
+ returnM ((rec_stmt, thing), uses `plusFV` fvs)
where
doc = text "In a recursive do statement"
+
+rnStmt ctxt (ParStmt segs) thing_inside
+ = do { opt_GlasgowExts <- doptM Opt_GlasgowExts
+ ; checkM opt_GlasgowExts parStmtErr
+ ; orig_lcl_env <- getLocalRdrEnv
+ ; ((segs',thing), fvs) <- go orig_lcl_env [] segs
+ ; return ((ParStmt segs', thing), fvs) }
+ where
+-- type ParSeg id = [([LStmt id], [id])]
+-- go :: NameSet -> [ParSeg RdrName]
+-- -> RnM (([ParSeg Name], thing), FreeVars)
+
+ go orig_lcl_env bndrs []
+ = do { let { (bndrs', dups) = removeDups cmpByOcc bndrs
+ ; inner_env = extendLocalRdrEnv orig_lcl_env bndrs' }
+ ; mappM dupErr dups
+ ; (thing, fvs) <- setLocalRdrEnv inner_env thing_inside
+ ; return (([], thing), fvs) }
+
+ go orig_lcl_env bndrs_so_far ((stmts, _) : segs)
+ = do { ((stmts', (bndrs, segs', thing)), fvs)
+ <- rnNormalStmts par_ctxt stmts $ do
+ { -- Find the Names that are bound by stmts
+ lcl_env <- getLocalRdrEnv
+ ; let { rdr_bndrs = collectLStmtsBinders stmts
+ ; bndrs = map ( fromJust
+ . lookupLocalRdrEnv lcl_env
+ . unLoc) rdr_bndrs
+ ; new_bndrs = nub bndrs ++ bndrs_so_far
+ -- The nub is because there might be shadowing
+ -- x <- e1; x <- e2
+ -- So we'll look up (Unqual x) twice, getting
+ -- the second binding both times, which is the
+ } -- one we want
+
+ -- Typecheck the thing inside, passing on all
+ -- the Names bound, but separately; revert the envt
+ ; ((segs', thing), fvs) <- setLocalRdrEnv orig_lcl_env $
+ go orig_lcl_env new_bndrs segs
+
+ -- Figure out which of the bound names are used
+ ; let used_bndrs = filter (`elemNameSet` fvs) bndrs
+ ; return ((used_bndrs, segs', thing), fvs) }
+
+ ; let seg' = (stmts', bndrs)
+ ; return (((seg':segs'), thing),
+ delListFromNameSet fvs bndrs) }
+
+ par_ctxt = ParStmtCtxt ctxt
+
+ cmpByOcc n1 n2 = nameOccName n1 `compare` nameOccName n2
+ dupErr vs = addErr (ptext SLIT("Duplicate binding in parallel list comprehension for:")
+ <+> quotes (ppr (head vs)))
\end{code}
----------------------------------------------------
-rnMDoStmts :: [RdrNameStmt] -> RnM ([RenamedStmt], FreeVars)
-rnMDoStmts stmts
+rnMDoStmts :: [LStmt RdrName]
+ -> RnM (thing, FreeVars)
+ -> RnM (([LStmt Name], thing), FreeVars)
+rnMDoStmts stmts thing_inside
= -- Step1: bring all the binders of the mdo into scope
-- Remember that this also removes the binders from the
-- finally-returned free-vars
- bindLocalsRn doc (collectStmtsBinders stmts) $ \ _ ->
-
+ bindLocatedLocalsRn doc (collectLStmtsBinders stmts) $ \ bndrs ->
+ do {
-- Step 2: Rename each individual stmt, making a
-- singleton segment. At this stage the FwdRefs field
-- isn't finished: it's empty for all except a BindStmt
-- for which it's the fwd refs within the bind itself
-- (This set may not be empty, because we're in a recursive
-- context.)
- rn_rec_stmts stmts `thenM` \ segs ->
- let
+ segs <- rn_rec_stmts bndrs stmts
+
+ ; (thing, fvs_later) <- thing_inside
+
+ ; let
-- Step 3: Fill in the fwd refs.
-- The segments are all singletons, but their fwd-ref
-- field mentions all the things used by the segment
-- that are bound after their use
- segs_w_fwd_refs = addFwdRefs segs
+ segs_w_fwd_refs = addFwdRefs segs
-- Step 4: Group together the segments to make bigger segments
-- Invariant: in the result, no segment uses a variable
-- bound in a later segment
- grouped_segs = glomSegments segs_w_fwd_refs
+ grouped_segs = glomSegments segs_w_fwd_refs
-- Step 5: Turn the segments into Stmts
-- Use RecStmt when and only when there are fwd refs
-- Also gather up the uses from the end towards the
-- start, so we can tell the RecStmt which things are
-- used 'after' the RecStmt
- stmts_w_fvs = segsToStmts grouped_segs
- in
- returnM stmts_w_fvs
+ (stmts', fvs) = segsToStmts grouped_segs fvs_later
+
+ ; return ((stmts', thing), fvs) }
where
- doc = text "In a mdo-expression"
+ doc = text "In a recursive mdo-expression"
+---------------------------------------------
+rn_rec_stmts :: [Name] -> [LStmt RdrName] -> RnM [Segment (LStmt Name)]
+rn_rec_stmts bndrs stmts = mappM (rn_rec_stmt bndrs) stmts `thenM` \ segs_s ->
+ returnM (concat segs_s)
----------------------------------------------------
-rn_rec_stmt :: RdrNameStmt -> RnM [Segment RenamedStmt]
+rn_rec_stmt :: [Name] -> LStmt RdrName -> RnM [Segment (LStmt Name)]
-- 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 (ExprStmt expr _ src_loc)
- = addSrcLoc src_loc (rnExpr expr) `thenM` \ (expr', fvs) ->
- returnM [(emptyNameSet, fvs, emptyNameSet,
- ExprStmt expr' placeHolderType src_loc)]
-
-rn_rec_stmt (ResultStmt expr src_loc)
- = addSrcLoc src_loc (rnExpr expr) `thenM` \ (expr', fvs) ->
- returnM [(emptyNameSet, fvs, emptyNameSet,
- ResultStmt expr' src_loc)]
-
-rn_rec_stmt (BindStmt pat expr src_loc)
- = addSrcLoc src_loc $
- rnExpr expr `thenM` \ (expr', fv_expr) ->
- rnPat pat `thenM` \ (pat', fv_pat) ->
+rn_rec_stmt all_bndrs (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 _ _))
+ = rnLExpr expr `thenM` \ (expr', fv_expr) ->
+ rnLPat pat `thenM` \ (pat', fv_pat) ->
+ lookupSyntaxName bindMName `thenM` \ (bind_op, fvs1) ->
+ lookupSyntaxName failMName `thenM` \ (fail_op, fvs2) ->
let
bndrs = mkNameSet (collectPatBinders pat')
- fvs = fv_expr `plusFV` fv_pat
+ fvs = fv_expr `plusFV` fv_pat `plusFV` fvs1 `plusFV` fvs2
in
returnM [(bndrs, fvs, bndrs `intersectNameSet` fvs,
- BindStmt pat' expr' src_loc)]
+ 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 (LetStmt binds)
- = rnBinds binds `thenM` \ (binds', du_binds) ->
+rn_rec_stmt all_bndrs (L loc (LetStmt (HsValBinds binds)))
+ = rnValBinds (trimWith all_bndrs) binds `thenM` \ (binds', du_binds) ->
returnM [(duDefs du_binds, duUses du_binds,
- emptyNameSet, LetStmt binds')]
+ emptyNameSet, L loc (LetStmt (HsValBinds binds')))]
-rn_rec_stmt (RecStmt stmts _ _ _) -- Flatten Rec inside Rec
- = rn_rec_stmts stmts
+rn_rec_stmt all_bndrs (L loc (RecStmt stmts _ _ _ _)) -- Flatten Rec inside Rec
+ = rn_rec_stmts all_bndrs stmts
-rn_rec_stmt stmt@(ParStmt _) -- Syntactically illegal in mdo
+rn_rec_stmt all_bndrs stmt@(L _ (ParStmt _)) -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt" (ppr stmt)
---------------------------------------------
-rn_rec_stmts :: [RdrNameStmt] -> RnM [Segment RenamedStmt]
-rn_rec_stmts stmts = mappM rn_rec_stmt stmts `thenM` \ segs_s ->
- returnM (concat segs_s)
-
-
----------------------------------------------
addFwdRefs :: [Segment a] -> [Segment a]
-- So far the segments only have forward refs *within* the Stmt
-- (which happens for bind: x <- ...x...)
-- q <- x ; z <- y } ;
-- r <- x }
-glomSegments :: [Segment RenamedStmt] -> [Segment [RenamedStmt]]
+glomSegments :: [Segment (LStmt Name)] -> [Segment [LStmt Name]]
glomSegments [] = []
glomSegments ((defs,uses,fwds,stmt) : segs)
----------------------------------------------------
-segsToStmts :: [Segment [RenamedStmt]] -> ([RenamedStmt], FreeVars)
-
-segsToStmts [] = ([], emptyFVs)
-segsToStmts ((defs, uses, fwds, ss) : segs)
- = (new_stmt : later_stmts, later_uses `plusFV` uses)
+segsToStmts :: [Segment [LStmt Name]]
+ -> FreeVars -- Free vars used 'later'
+ -> ([LStmt Name], FreeVars)
+
+segsToStmts [] fvs_later = ([], fvs_later)
+segsToStmts ((defs, uses, fwds, ss) : segs) fvs_later
+ = ASSERT( not (null ss) )
+ (new_stmt : later_stmts, later_uses `plusFV` uses)
where
- (later_stmts, later_uses) = segsToStmts segs
+ (later_stmts, later_uses) = segsToStmts segs fvs_later
new_stmt | non_rec = head ss
- | otherwise = RecStmt ss (nameSetToList used_later) (nameSetToList fwds) []
+ | otherwise = L (getLoc (head ss)) $
+ RecStmt ss (nameSetToList used_later) (nameSetToList fwds)
+ [] emptyLHsBinds
where
non_rec = isSingleton ss && isEmptyNameSet fwds
used_later = defs `intersectNameSet` later_uses
%************************************************************************
%* *
-\subsubsection{Precedence Parsing}
-%* *
-%************************************************************************
-
-@mkOpAppRn@ deals with operator fixities. The argument expressions
-are assumed to be already correctly arranged. It needs the fixities
-recorded in the OpApp nodes, because fixity info applies to the things
-the programmer actually wrote, so you can't find it out from the Name.
-
-Furthermore, the second argument is guaranteed not to be another
-operator application. Why? Because the parser parses all
-operator appications left-associatively, EXCEPT negation, which
-we need to handle specially.
-
-\begin{code}
-mkOpAppRn :: RenamedHsExpr -- Left operand; already rearranged
- -> RenamedHsExpr -> Fixity -- Operator and fixity
- -> RenamedHsExpr -- Right operand (not an OpApp, but might
- -- be a NegApp)
- -> RnM RenamedHsExpr
-
----------------------------
--- (e11 `op1` e12) `op2` e2
-mkOpAppRn e1@(OpApp e11 op1 fix1 e12) op2 fix2 e2
- | nofix_error
- = addErr (precParseErr (ppr_op op1,fix1) (ppr_op op2,fix2)) `thenM_`
- returnM (OpApp e1 op2 fix2 e2)
-
- | associate_right
- = mkOpAppRn e12 op2 fix2 e2 `thenM` \ new_e ->
- returnM (OpApp e11 op1 fix1 new_e)
- where
- (nofix_error, associate_right) = compareFixity fix1 fix2
-
----------------------------
--- (- neg_arg) `op` e2
-mkOpAppRn e1@(NegApp neg_arg neg_name) op2 fix2 e2
- | nofix_error
- = addErr (precParseErr (pp_prefix_minus,negateFixity) (ppr_op op2,fix2)) `thenM_`
- returnM (OpApp e1 op2 fix2 e2)
-
- | associate_right
- = mkOpAppRn neg_arg op2 fix2 e2 `thenM` \ new_e ->
- returnM (NegApp new_e neg_name)
- where
- (nofix_error, associate_right) = compareFixity negateFixity fix2
-
----------------------------
--- e1 `op` - neg_arg
-mkOpAppRn e1 op1 fix1 e2@(NegApp neg_arg _) -- NegApp can occur on the right
- | not associate_right -- We *want* right association
- = addErr (precParseErr (ppr_op op1, fix1) (pp_prefix_minus, negateFixity)) `thenM_`
- returnM (OpApp e1 op1 fix1 e2)
- where
- (_, associate_right) = compareFixity fix1 negateFixity
-
----------------------------
--- Default case
-mkOpAppRn e1 op fix e2 -- Default case, no rearrangment
- = ASSERT2( right_op_ok fix e2,
- ppr e1 $$ text "---" $$ ppr op $$ text "---" $$ ppr fix $$ text "---" $$ ppr e2
- )
- returnM (OpApp e1 op fix e2)
-
--- Parser left-associates everything, but
--- derived instances may have correctly-associated things to
--- in the right operarand. So we just check that the right operand is OK
-right_op_ok fix1 (OpApp _ _ fix2 _)
- = not error_please && associate_right
- where
- (error_please, associate_right) = compareFixity fix1 fix2
-right_op_ok fix1 other
- = True
-
--- Parser initially makes negation bind more tightly than any other operator
--- And "deriving" code should respect this (use HsPar if not)
-mkNegAppRn neg_arg neg_name
- = ASSERT( not_op_app neg_arg )
- returnM (NegApp neg_arg neg_name)
-
-not_op_app (OpApp _ _ _ _) = False
-not_op_app other = True
-\end{code}
-
-\begin{code}
-checkPrecMatch :: Bool -> Name -> RenamedMatch -> RnM ()
-
-checkPrecMatch False fn match
- = returnM ()
-
-checkPrecMatch True op (Match (p1:p2:_) _ _)
- -- True indicates an infix lhs
- = -- See comments with rnExpr (OpApp ...) about "deriving"
- checkPrec op p1 False `thenM_`
- checkPrec op p2 True
-
-checkPrecMatch True op _ = panic "checkPrecMatch"
-
-checkPrec op (ConPatIn op1 (InfixCon _ _)) right
- = lookupFixityRn op `thenM` \ op_fix@(Fixity op_prec op_dir) ->
- lookupFixityRn op1 `thenM` \ op1_fix@(Fixity op1_prec op1_dir) ->
- let
- inf_ok = op1_prec > op_prec ||
- (op1_prec == op_prec &&
- (op1_dir == InfixR && op_dir == InfixR && right ||
- op1_dir == InfixL && op_dir == InfixL && not right))
-
- info = (ppr_op op, op_fix)
- info1 = (ppr_op op1, op1_fix)
- (infol, infor) = if right then (info, info1) else (info1, info)
- in
- checkErr inf_ok (precParseErr infol infor)
-
-checkPrec op pat right
- = returnM ()
-
--- Check precedence of (arg op) or (op arg) respectively
--- If arg is itself an operator application, then either
--- (a) its precedence must be higher than that of op
--- (b) its precedency & associativity must be the same as that of op
-checkSectionPrec direction section op arg
- = case arg of
- OpApp _ op fix _ -> go_for_it (ppr_op op) fix
- NegApp _ _ -> go_for_it pp_prefix_minus negateFixity
- other -> returnM ()
- where
- HsVar op_name = op
- go_for_it pp_arg_op arg_fix@(Fixity arg_prec assoc)
- = lookupFixityRn op_name `thenM` \ op_fix@(Fixity op_prec _) ->
- checkErr (op_prec < arg_prec
- || op_prec == arg_prec && direction == assoc)
- (sectionPrecErr (ppr_op op_name, op_fix)
- (pp_arg_op, arg_fix) section)
-\end{code}
-
-
-%************************************************************************
-%* *
\subsubsection{Assertion utils}
%* *
%************************************************************************
\begin{code}
-mkAssertErrorExpr :: RnM (RenamedHsExpr, FreeVars)
+mkAssertErrorExpr :: RnM (HsExpr Name, FreeVars)
-- Return an expression for (assertError "Foo.hs:27")
mkAssertErrorExpr
- = getSrcLocM `thenM` \ sloc ->
+ = getSrcSpanM `thenM` \ sloc ->
let
- expr = HsApp (HsVar assertErrorName) (HsLit msg)
+ expr = HsApp (L sloc (HsVar assertErrorName)) (L sloc (HsLit msg))
msg = HsStringPrim (mkFastString (stringToUtf8 (showSDoc (ppr sloc))))
in
returnM (expr, emptyFVs)
%************************************************************************
\begin{code}
-ppr_op op = quotes (ppr op) -- Here, op can be a Name or a (Var n), where n is a Name
-pp_prefix_minus = ptext SLIT("prefix `-'")
-
-nonStdGuardErr guard
- = hang (ptext
- SLIT("accepting non-standard pattern guards (-fglasgow-exts to suppress this message)")
- ) 4 (ppr guard)
-
patSynErr e
= sep [ptext SLIT("Pattern syntax in expression context:"),
nest 4 (ppr e)]
-doStmtListErr do_or_lc e
- = sep [quotes (text binder_name) <+> ptext SLIT("statements must end in expression:"),
- nest 4 (ppr e)]
- where
- binder_name = case do_or_lc of
- MDoExpr -> "mdo"
- other -> "do"
-
-#ifdef GHCI
-checkTH e what = returnM () -- OK
-#else
-checkTH e what -- Raise an error in a stage-1 compiler
- = addErr (vcat [ptext SLIT("Template Haskell") <+> text what <+>
- ptext SLIT("illegal in a stage-1 compiler"),
- nest 2 (ppr e)])
-#endif
-
parStmtErr = addErr (ptext SLIT("Illegal parallel list comprehension: use -fglasgow-exts"))
-badIpBinds binds
- = hang (ptext SLIT("Implicit-parameter bindings illegal in a parallel list comprehension:")) 4
- (ppr binds)
+badIpBinds what binds
+ = hang (ptext SLIT("Implicit-parameter bindings illegal in") <+> what)
+ 2 (ppr binds)
\end{code}