import {-# SOURCE #-} TcSplice( runQuasiQuoteExpr )
#endif /* GHCI */
-import RnSource ( rnSrcDecls, rnSplice, checkTH )
-import RnBinds ( rnLocalBindsAndThen, rnValBindsLHS, rnValBindsRHS,
+import RnSource ( rnSrcDecls, findSplice )
+import RnBinds ( rnLocalBindsAndThen, rnLocalValBindsLHS, rnLocalValBindsRHS,
rnMatchGroup, makeMiniFixityEnv)
import HsSyn
import TcRnMonad
+import TcEnv ( thRnBrack )
import RnEnv
-import RnTypes ( rnHsTypeFVs,
+import RnTypes ( rnHsTypeFVs, rnSplice, checkTH,
mkOpFormRn, mkOpAppRn, mkNegAppRn, checkSectionPrec)
-import RnPat (rnQuasiQuote, rnOverLit, rnPatsAndThen_LocalRightwards, rnBindPat,
- localRecNameMaker, rnLit,
- rnHsRecFields_Con, rnHsRecFields_Update, checkTupSize)
-import DynFlags ( DynFlag(..) )
+import RnPat
+import DynFlags
import BasicTypes ( FixityDirection(..) )
-import PrelNames ( thFAKE, hasKey, assertIdKey, assertErrorName,
- loopAName, choiceAName, appAName, arrAName, composeAName, firstAName,
- negateName, thenMName, bindMName, failMName, groupWithName )
+import PrelNames
import Name
import NameSet
import RdrName
import LoadIface ( loadInterfaceForName )
import UniqSet
-import List ( nub )
+import Data.List
import Util ( isSingleton )
import ListSetOps ( removeDups )
-import Maybes ( expectJust )
import Outputable
import SrcLoc
import FastString
-
-import List ( unzip4 )
import Control.Monad
\end{code}
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}
%************************************************************************
rnExprs :: [LHsExpr RdrName] -> RnM ([LHsExpr Name], FreeVars)
rnExprs ls = rnExprs' ls emptyUniqSet
where
- rnExprs' [] acc = returnM ([], acc)
+ rnExprs' [] acc = return ([], acc)
rnExprs' (expr:exprs) acc
= rnLExpr expr `thenM` \ (expr', fvExpr) ->
acc' = acc `plusFV` fvExpr
in
acc' `seq` rnExprs' exprs acc' `thenM` \ (exprs', fvExprs) ->
- returnM (expr':exprs', fvExprs)
+ return (expr':exprs', fvExprs)
\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 ->
- returnM (HsIPVar name, emptyFVs)
+ return (HsIPVar name, emptyFVs)
rnExpr (HsLit lit@(HsString s))
= do {
- opt_OverloadedStrings <- doptM Opt_OverloadedStrings
+ opt_OverloadedStrings <- xoptM Opt_OverloadedStrings
; if opt_OverloadedStrings then
rnExpr (HsOverLit (mkHsIsString s placeHolderType))
else -- Same as below
rnLit lit `thenM_`
- returnM (HsLit lit, emptyFVs)
+ return (HsLit lit, emptyFVs)
}
rnExpr (HsLit lit)
= rnLit lit `thenM_`
- returnM (HsLit lit, emptyFVs)
+ return (HsLit lit, emptyFVs)
rnExpr (HsOverLit lit)
= rnOverLit lit `thenM` \ (lit', fvs) ->
- returnM (HsOverLit lit', fvs)
+ return (HsOverLit lit', fvs)
rnExpr (HsApp fun arg)
= rnLExpr fun `thenM` \ (fun',fvFun) ->
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) ->
-
+ return (HsApp fun' arg', fvFun `plusFV` fvArg)
+
+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) ->
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)
- = rnLExpr e `thenM` \ (e', fvs_e) ->
- returnM (HsPar e', fvs_e)
+ return (final_e, fv_e `plusFV` fv_neg)
+------------------------------------------
-- 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)
= checkTH e "bracket" `thenM_`
rnBracket br_body `thenM` \ (body', fvs_e) ->
- returnM (HsBracket body', fvs_e)
+ return (HsBracket body', fvs_e)
rnExpr (HsSpliceE splice)
= rnSplice splice `thenM` \ (splice', fvs) ->
- returnM (HsSpliceE splice', fvs)
+ return (HsSpliceE splice', fvs)
#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)
+ = runQuasiQuoteExpr qq `thenM` \ (L _ expr') ->
+ rnExpr expr'
#endif /* GHCI */
-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)
+---------------------------------------------
+-- 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 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)
+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)
+ return (HsCoreAnn ann expr', fvs_expr)
rnExpr (HsSCC lbl expr)
= rnLExpr expr `thenM` \ (expr', fvs_expr) ->
- returnM (HsSCC lbl expr', fvs_expr)
+ return (HsSCC lbl expr', fvs_expr)
rnExpr (HsTickPragma info expr)
= rnLExpr expr `thenM` \ (expr', fvs_expr) ->
- returnM (HsTickPragma info expr', fvs_expr)
+ return (HsTickPragma info expr', fvs_expr)
rnExpr (HsLam matches)
= rnMatchGroup LambdaExpr matches `thenM` \ (matches', fvMatch) ->
- returnM (HsLam matches', fvMatch)
+ return (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)
+ return (HsCase new_expr new_matches, e_fvs `plusFV` ms_fvs)
rnExpr (HsLet binds expr)
= rnLocalBindsAndThen binds $ \ binds' ->
rnLExpr expr `thenM` \ (expr',fvExpr) ->
- returnM (HsLet binds' expr', fvExpr)
+ return (HsLet binds' expr', fvExpr)
rnExpr (HsDo do_or_lc stmts body _)
= do { ((stmts', body'), fvs) <- rnStmts do_or_lc stmts $
rnExpr (ExplicitList _ exps)
= rnExprs exps `thenM` \ (exps', fvs) ->
- returnM (ExplicitList placeHolderType exps', fvs)
+ return (ExplicitList placeHolderType exps', fvs)
rnExpr (ExplicitPArr _ exps)
= rnExprs exps `thenM` \ (exps', fvs) ->
- returnM (ExplicitPArr placeHolderType exps', fvs)
+ return (ExplicitPArr placeHolderType exps', fvs)
-rnExpr (ExplicitTuple exps boxity)
- = checkTupSize (length exps) `thenM_`
- rnExprs exps `thenM` \ (exps', fvs) ->
- returnM (ExplicitTuple exps' boxity, fvs)
+rnExpr (ExplicitTuple tup_args boxity)
+ = do { checkTupleSection tup_args
+ ; checkTupSize (length tup_args)
+ ; (tup_args', fvs) <- mapAndUnzipM rnTupArg tup_args
+ ; return (ExplicitTuple tup_args' boxity, plusFVs fvs) }
+ where
+ rnTupArg (Present e) = do { (e',fvs) <- rnLExpr e; return (Present e', fvs) }
+ rnTupArg (Missing _) = return (Missing placeHolderType, emptyFVs)
rnExpr (RecordCon con_id _ rbinds)
= do { conname <- lookupLocatedOccRn con_id
- ; (rbinds', fvRbinds) <- rnHsRecFields_Con conname rnLExpr rbinds
+ ; (rbinds', fvRbinds) <- rnHsRecBinds (HsRecFieldCon (unLoc conname)) rbinds
; return (RecordCon conname noPostTcExpr rbinds',
fvRbinds `addOneFV` unLoc conname) }
rnExpr (RecordUpd expr rbinds _ _ _)
= do { (expr', fvExpr) <- rnLExpr expr
- ; (rbinds', fvRbinds) <- rnHsRecFields_Update rnLExpr rbinds
+ ; (rbinds', fvRbinds) <- rnHsRecBinds HsRecFieldUpd rbinds
; return (RecordUpd expr' rbinds' [] [] [],
fvExpr `plusFV` fvRbinds) }
where
doc = text "In an expression type signature"
-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 (HsIf _ p b1 b2)
+ = do { (p', fvP) <- rnLExpr p
+ ; (b1', fvB1) <- rnLExpr b1
+ ; (b2', fvB2) <- rnLExpr b2
+ ; rebind <- xoptM Opt_RebindableSyntax
+ ; if not rebind
+ then return (HsIf Nothing p' b1' b2', plusFVs [fvP, fvB1, fvB2])
+ else do { c <- liftM HsVar (lookupOccRn (mkVarUnqual (fsLit "ifThenElse")))
+ ; return (HsIf (Just c) p' b1' b2', plusFVs [fvP, fvB1, fvB2]) }}
rnExpr (HsType a)
= rnHsTypeFVs doc a `thenM` \ (t, fvT) ->
- returnM (HsType t, fvT)
+ return (HsType t, fvT)
where
doc = text "In a type argument"
rnExpr (ArithSeq _ seq)
= rnArithSeq seq `thenM` \ (new_seq, fvs) ->
- returnM (ArithSeq noPostTcExpr new_seq, fvs)
+ return (ArithSeq noPostTcExpr new_seq, fvs)
rnExpr (PArrSeq _ seq)
= rnArithSeq seq `thenM` \ (new_seq, fvs) ->
- returnM (PArrSeq noPostTcExpr new_seq, fvs)
+ return (PArrSeq noPostTcExpr new_seq, fvs)
\end{code}
These three are pattern syntax appearing in expressions.
\begin{code}
rnExpr (HsProc pat body)
= newArrowScope $
- rnPatsAndThen_LocalRightwards ProcExpr [pat] $ \ [pat'] ->
+ rnPat ProcExpr pat $ \ pat' ->
rnCmdTop body `thenM` \ (body',fvBody) ->
- returnM (HsProc pat' body', fvBody)
+ return (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,
+ return (HsArrApp arrow' arg' placeHolderType ho rtl,
fvArrow `plusFV` fvArg)
where
select_arrow_scope tc = case ho of
-- infix form
rnExpr (HsArrForm op (Just _) [arg1, arg2])
= escapeArrowScope (rnLExpr op)
- `thenM` \ (op'@(L _ (HsVar op_name)),fv_op) ->
+ `thenM` \ (op',fv_op) ->
+ let L _ (HsVar op_name) = op' in
rnCmdTop arg1 `thenM` \ (arg1',fv_arg1) ->
rnCmdTop arg2 `thenM` \ (arg2',fv_arg2) ->
lookupFixityRn op_name `thenM` \ fixity ->
mkOpFormRn arg1' op' fixity arg2' `thenM` \ final_e ->
- returnM (final_e,
+ return (final_e,
fv_arg1 `plusFV` fv_op `plusFV` fv_arg2)
rnExpr (HsArrForm op fixity cmds)
= escapeArrowScope (rnLExpr op) `thenM` \ (op',fvOp) ->
rnCmdArgs cmds `thenM` \ (cmds',fvCmds) ->
- returnM (HsArrForm op' fixity cmds', fvOp `plusFV` fvCmds)
+ return (HsArrForm op' fixity cmds', fvOp `plusFV` fvCmds)
rnExpr other = pprPanic "rnExpr: unexpected expression" (ppr other)
-- HsWrap
+
+----------------------
+-- 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}
+
+%************************************************************************
+%* *
+ Records
+%* *
+%************************************************************************
+
+\begin{code}
+rnHsRecBinds :: HsRecFieldContext -> HsRecordBinds RdrName
+ -> RnM (HsRecordBinds Name, FreeVars)
+rnHsRecBinds ctxt rec_binds@(HsRecFields { rec_dotdot = dd })
+ = do { (flds, fvs) <- rnHsRecFields1 ctxt HsVar rec_binds
+ ; (flds', fvss) <- mapAndUnzipM rn_field flds
+ ; return (HsRecFields { rec_flds = flds', rec_dotdot = dd },
+ fvs `plusFV` plusFVs fvss) }
+ where
+ rn_field fld = do { (arg', fvs) <- rnLExpr (hsRecFieldArg fld)
+ ; return (fld { hsRecFieldArg = arg' }, fvs) }
\end{code}
\begin{code}
rnCmdArgs :: [LHsCmdTop RdrName] -> RnM ([LHsCmdTop Name], FreeVars)
-rnCmdArgs [] = returnM ([], emptyFVs)
+rnCmdArgs [] = return ([], emptyFVs)
rnCmdArgs (arg:args)
= rnCmdTop arg `thenM` \ (arg',fvArg) ->
rnCmdArgs args `thenM` \ (args',fvArgs) ->
- returnM (arg':args', fvArg `plusFV` fvArgs)
+ return (arg':args', fvArg `plusFV` fvArgs)
rnCmdTop :: LHsCmdTop RdrName -> RnM (LHsCmdTop Name, FreeVars)
rnCmdTop = wrapLocFstM rnCmdTop'
-- Generate the rebindable syntax for the monad
lookupSyntaxTable cmd_names `thenM` \ (cmd_names', cmd_fvs) ->
- returnM (HsCmdTop cmd' [] placeHolderType cmd_names',
+ return (HsCmdTop cmd' [] placeHolderType cmd_names',
fvCmd `plusFV` cmd_fvs)
---------------------------------------------------
convertOpFormsCmd (HsCase exp matches)
= HsCase exp (convertOpFormsMatch matches)
-convertOpFormsCmd (HsIf exp c1 c2)
- = HsIf exp (convertOpFormsLCmd c1) (convertOpFormsLCmd c2)
+convertOpFormsCmd (HsIf f exp c1 c2)
+ = HsIf f exp (convertOpFormsLCmd c1) (convertOpFormsLCmd c2)
convertOpFormsCmd (HsLet binds cmd)
= HsLet binds (convertOpFormsLCmd 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@(RecStmt { recS_stmts = stmts })
+ = stmt { recS_stmts = map (fmap convertOpFormsStmt) stmts }
convertOpFormsStmt stmt = stmt
convertOpFormsMatch :: MatchGroup id -> MatchGroup id
methodNamesCmd (HsPar c) = methodNamesLCmd c
-methodNamesCmd (HsIf _ c1 c2)
+methodNamesCmd (HsIf _ _ c1 c2)
= methodNamesLCmd c1 `plusFV` methodNamesLCmd c2 `addOneFV` choiceAName
methodNamesCmd (HsLet _ c) = methodNamesLCmd c
methodNamesLStmt = methodNamesStmt . unLoc
methodNamesStmt :: StmtLR Name Name -> FreeVars
-methodNamesStmt (ExprStmt cmd _ _) = methodNamesLCmd cmd
-methodNamesStmt (BindStmt _ cmd _ _) = methodNamesLCmd cmd
-methodNamesStmt (RecStmt stmts _ _ _ _)
- = methodNamesStmts stmts `addOneFV` loopAName
-methodNamesStmt (LetStmt _) = emptyFVs
-methodNamesStmt (ParStmt _) = emptyFVs
-methodNamesStmt (TransformStmt _ _ _) = emptyFVs
-methodNamesStmt (GroupStmt _ _) = emptyFVs
+methodNamesStmt (ExprStmt cmd _ _) = methodNamesLCmd cmd
+methodNamesStmt (BindStmt _ cmd _ _) = methodNamesLCmd cmd
+methodNamesStmt (RecStmt { recS_stmts = stmts }) = methodNamesStmts stmts `addOneFV` loopAName
+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
-- here so we just do what's convenient
\end{code}
rnArithSeq :: ArithSeqInfo RdrName -> RnM (ArithSeqInfo Name, FreeVars)
rnArithSeq (From expr)
= rnLExpr expr `thenM` \ (expr', fvExpr) ->
- returnM (From expr', fvExpr)
+ return (From expr', fvExpr)
rnArithSeq (FromThen expr1 expr2)
= rnLExpr expr1 `thenM` \ (expr1', fvExpr1) ->
rnLExpr expr2 `thenM` \ (expr2', fvExpr2) ->
- returnM (FromThen expr1' expr2', fvExpr1 `plusFV` fvExpr2)
+ return (FromThen expr1' expr2', fvExpr1 `plusFV` fvExpr2)
rnArithSeq (FromTo expr1 expr2)
= rnLExpr expr1 `thenM` \ (expr1', fvExpr1) ->
rnLExpr expr2 `thenM` \ (expr2', fvExpr2) ->
- returnM (FromTo expr1' expr2', fvExpr1 `plusFV` fvExpr2)
+ return (FromTo expr1' expr2', fvExpr1 `plusFV` fvExpr2)
rnArithSeq (FromThenTo expr1 expr2 expr3)
= rnLExpr expr1 `thenM` \ (expr1', fvExpr1) ->
rnLExpr expr2 `thenM` \ (expr2', fvExpr2) ->
rnLExpr expr3 `thenM` \ (expr3', fvExpr3) ->
- returnM (FromThenTo expr1' expr2' expr3',
+ return (FromThenTo expr1' expr2' expr3',
plusFVs [fvExpr1, fvExpr2, fvExpr3])
\end{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
- do { loadInterfaceForName msg name -- home interface is loaded, and this is the
+ ; unless (nameIsLocalOrFrom this_mod name) $ -- Reason: deprecation checking asumes the
+ do { _ <- loadInterfaceForName msg name -- home interface is loaded, and this is the
; return () } -- only way that is going to happen
- ; returnM (VarBr name, unitFV name) }
+ ; return (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 _) = do { addErr (ptext (sLit "Tempate Haskell pattern brackets are not supported yet"));
- failM }
+rnBracket (PatBr p) = rnPat ThPatQuote p $ \ p' -> return (PatBr p', emptyFVs)
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)
- = 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
-
- -- Discard the tcg_env; it contains only extra info about fixity
- ; return (DecBr group', allUses (tcg_dus tcg_env)) } }
+
+rnBracket (DecBrL decls)
+ = do { (group, mb_splice) <- findSplice decls
+ ; case mb_splice of
+ Nothing -> return ()
+ Just (SpliceDecl (L loc _) _, _)
+ -> setSrcSpan loc $
+ addErr (ptext (sLit "Declaration splices are not permitted inside declaration brackets"))
+ -- Why not? See Section 7.3 of the TH paper.
+
+ ; gbl_env <- getGblEnv
+ ; 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
+ ; traceRn (text "rnBracket dec" <+> (ppr (tcg_dus tcg_env) $$ ppr (duUses (tcg_dus tcg_env))))
+ ; return (DecBrG group', duUses (tcg_dus tcg_env)) }
+
+rnBracket (DecBrG _) = panic "rnBracket: unexpected DecBrG"
\end{code}
%************************************************************************
rnStmts :: HsStmtContext Name -> [LStmt RdrName]
-> RnM (thing, FreeVars)
-> RnM (([LStmt Name], thing), FreeVars)
+-- Variables bound by the Stmts, and mentioned in thing_inside,
+-- do not appear in the result FreeVars
-rnStmts (MDoExpr _) = rnMDoStmts
-rnStmts ctxt = rnNormalStmts ctxt
+rnStmts (MDoExpr _) stmts thing_inside = rnMDoStmts stmts thing_inside
+rnStmts ctxt stmts thing_inside = rnNormalStmts ctxt stmts (\ _ -> thing_inside)
rnNormalStmts :: HsStmtContext Name -> [LStmt RdrName]
- -> RnM (thing, FreeVars)
+ -> ([Name] -> RnM (thing, FreeVars))
-> RnM (([LStmt Name], thing), FreeVars)
--- Used for cases *other* than recursive mdo
--- Implements nested scopes
+-- Variables bound by the Stmts, and mentioned in thing_inside,
+-- do not appear in the result FreeVars
+--
+-- Renaming a single RecStmt can give a sequence of smaller Stmts
rnNormalStmts _ [] thing_inside
- = do { (thing, fvs) <- thing_inside
- ; return (([],thing), fvs) }
+ = do { (res, fvs) <- thing_inside []
+ ; return (([], res), 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) }
+rnNormalStmts ctxt (stmt@(L loc _) : stmts) thing_inside
+ = do { ((stmts1, (stmts2, thing)), fvs)
+ <- setSrcSpan loc $
+ rnStmt ctxt stmt $ \ bndrs1 ->
+ rnNormalStmts ctxt stmts $ \ bndrs2 ->
+ thing_inside (bndrs1 ++ bndrs2)
+ ; return (((stmts1 ++ stmts2), thing), fvs) }
-rnStmt :: HsStmtContext Name -> Stmt RdrName
- -> RnM (thing, FreeVars)
- -> RnM ((Stmt Name, thing), FreeVars)
+rnStmt :: HsStmtContext Name -> LStmt RdrName
+ -> ([Name] -> RnM (thing, FreeVars))
+ -> RnM (([LStmt Name], thing), FreeVars)
+-- Variables bound by the Stmt, and mentioned in thing_inside,
+-- do not appear in the result FreeVars
-rnStmt _ (ExprStmt expr _ _) thing_inside
+rnStmt _ (L loc (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),
+ ; (thing, fvs2) <- thing_inside []
+ ; return (([L loc (ExprStmt expr' then_op placeHolderType)], thing),
fv_expr `plusFV` fvs1 `plusFV` fvs2) }
-rnStmt ctxt (BindStmt pat expr _ _) thing_inside
+rnStmt ctxt (L loc (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_LocalRightwards (StmtCtxt ctxt) [pat] $ \ [pat'] -> do
- { (thing, fvs3) <- thing_inside
- ; return ((BindStmt pat' expr' bind_op fail_op, thing),
+ ; rnPat (StmtCtxt ctxt) pat $ \ pat' -> do
+ { (thing, fvs3) <- thing_inside (collectPatBinders pat')
+ ; return (([L loc (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
+rnStmt ctxt (L loc (LetStmt binds)) thing_inside
= do { checkLetStmt ctxt binds
; rnLocalBindsAndThen binds $ \binds' -> do
- { (thing, fvs) <- thing_inside
- ; return ((LetStmt binds', thing), fvs) } }
+ { (thing, fvs) <- thing_inside (collectLocalBinders binds')
+ ; return (([L loc (LetStmt binds')], thing), fvs) } }
-rnStmt ctxt (RecStmt rec_stmts _ _ _ _) thing_inside
+rnStmt ctxt (L _ (RecStmt { recS_stmts = rec_stmts })) thing_inside
= do { checkRecStmt ctxt
- ; rn_rec_stmts_and_then rec_stmts $ \ segs -> do
- { (thing, fvs) <- 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.)
+ -- And 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_and_then rec_stmts $ \ segs -> do
+
+ { let bndrs = nameSetToList $ foldr (unionNameSets . (\(ds,_,_,_) -> ds))
+ emptyNameSet segs
+ ; (thing, fvs_later) <- thing_inside bndrs
+ ; (return_op, fvs1) <- lookupSyntaxName returnMName
+ ; (mfix_op, fvs2) <- lookupSyntaxName mfixName
+ ; (bind_op, fvs3) <- lookupSyntaxName bindMName
; let
+ -- Step 2: 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
- (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
+
+ -- Step 3: 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
+
+ -- Step 4: 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
+ empty_rec_stmt = emptyRecStmt { recS_ret_fn = return_op
+ , recS_mfix_fn = mfix_op
+ , recS_bind_fn = bind_op }
+ (rec_stmts', fvs) = segsToStmts empty_rec_stmt grouped_segs fvs_later
+
+ ; return ((rec_stmts', thing), fvs `plusFV` fvs1 `plusFV` fvs2 `plusFV` fvs3) } }
+
+rnStmt ctxt (L loc (ParStmt segs)) thing_inside
= do { checkParStmt ctxt
; ((segs', thing), fvs) <- rnParallelStmts (ParStmtCtxt ctxt) segs thing_inside
- ; return ((ParStmt segs', thing), fvs) }
+ ; return (([L loc (ParStmt segs')], thing), fvs) }
-rnStmt ctxt (TransformStmt (stmts, _) usingExpr maybeByExpr) thing_inside = do
- checkTransformStmt ctxt
-
- (usingExpr', fv_usingExpr) <- rnLExpr usingExpr
- ((stmts', binders, (maybeByExpr', thing)), fvs) <-
- rnNormalStmtsAndFindUsedBinders (TransformStmtCtxt ctxt) stmts $ \_unshadowed_bndrs -> do
- (maybeByExpr', fv_maybeByExpr) <- rnMaybeLExpr maybeByExpr
- (thing, fv_thing) <- thing_inside
-
- return ((maybeByExpr', thing), fv_maybeByExpr `plusFV` fv_thing)
+rnStmt ctxt (L loc (TransformStmt stmts _ using by)) thing_inside
+ = do { checkTransformStmt ctxt
- return ((TransformStmt (stmts', binders) usingExpr' maybeByExpr', thing), fv_usingExpr `plusFV` fvs)
- where
- rnMaybeLExpr Nothing = return (Nothing, emptyFVs)
- rnMaybeLExpr (Just expr) = do
- (expr', fv_expr) <- rnLExpr expr
- return (Just expr', fv_expr)
+ ; (using', fvs1) <- rnLExpr using
+
+ ; ((stmts', (by', used_bndrs, thing)), fvs2)
+ <- rnNormalStmts (TransformStmtCtxt ctxt) stmts $ \ bndrs ->
+ do { (by', fvs_by) <- case by of
+ Nothing -> return (Nothing, emptyFVs)
+ Just e -> do { (e', fvs) <- rnLExpr e; return (Just e', fvs) }
+ ; (thing, fvs_thing) <- thing_inside bndrs
+ ; let fvs = fvs_by `plusFV` fvs_thing
+ used_bndrs = filter (`elemNameSet` fvs_thing) bndrs
+ ; return ((by', used_bndrs, thing), fvs) }
+
+ ; return (([L loc (TransformStmt stmts' used_bndrs using' by')], thing),
+ fvs1 `plusFV` fvs2) }
-rnStmt ctxt (GroupStmt (stmts, _) groupByClause) thing_inside = do
- checkTransformStmt ctxt
-
- -- We must rename the using expression in the context before the transform is begun
- groupByClauseAction <-
- case groupByClause of
- GroupByNothing usingExpr -> do
- (usingExpr', fv_usingExpr) <- rnLExpr usingExpr
- (return . return) (GroupByNothing usingExpr', fv_usingExpr)
- GroupBySomething eitherUsingExpr byExpr -> do
- (eitherUsingExpr', fv_eitherUsingExpr) <-
- case eitherUsingExpr of
- Right _ -> return (Right $ HsVar groupWithName, unitNameSet groupWithName)
- Left usingExpr -> do
- (usingExpr', fv_usingExpr) <- rnLExpr usingExpr
- return (Left usingExpr', fv_usingExpr)
-
- return $ do
- (byExpr', fv_byExpr) <- rnLExpr byExpr
- return (GroupBySomething eitherUsingExpr' byExpr', fv_eitherUsingExpr `plusFV` fv_byExpr)
+rnStmt ctxt (L loc (GroupStmt stmts _ by using)) thing_inside
+ = do { checkTransformStmt ctxt
- -- We only use rnNormalStmtsAndFindUsedBinders to get unshadowed_bndrs, so
- -- perhaps we could refactor this to use rnNormalStmts directly?
- ((stmts', _, (groupByClause', usedBinderMap, thing)), fvs) <-
- rnNormalStmtsAndFindUsedBinders (TransformStmtCtxt ctxt) stmts $ \unshadowed_bndrs -> do
- (groupByClause', fv_groupByClause) <- groupByClauseAction
-
- unshadowed_bndrs' <- mapM newLocalName unshadowed_bndrs
- let binderMap = zip unshadowed_bndrs unshadowed_bndrs'
-
- -- Bind the "thing" inside a context where we have REBOUND everything
- -- bound by the statements before the group. This is necessary since after
- -- the grouping the same identifiers actually have different meanings
- -- i.e. they refer to lists not singletons!
- (thing, fv_thing) <- bindLocalNames unshadowed_bndrs' thing_inside
-
- -- We remove entries from the binder map that are not used in the thing_inside.
- -- We can then use that usage information to ensure that the free variables do
- -- not contain the things we just bound, but do contain the things we need to
- -- make those bindings (i.e. the corresponding non-listy variables)
-
- -- Note that we also retain those entries which have an old binder in our
- -- own free variables (the using or by expression). This is because this map
- -- is reused in the desugarer to create the type to bind from the statements
- -- that occur before this one. If the binders we need are not in the map, they
- -- will never get bound into our desugared expression and hence the simplifier
- -- crashes as we refer to variables that don't exist!
- let usedBinderMap = filter
- (\(old_binder, new_binder) ->
- (new_binder `elemNameSet` fv_thing) ||
- (old_binder `elemNameSet` fv_groupByClause)) binderMap
- (usedOldBinders, usedNewBinders) = unzip usedBinderMap
- real_fv_thing = (delListFromNameSet fv_thing usedNewBinders) `plusFV` (mkNameSet usedOldBinders)
-
- return ((groupByClause', usedBinderMap, thing), fv_groupByClause `plusFV` real_fv_thing)
-
- traceRn (text "rnStmt: implicitly rebound these used binders:" <+> ppr usedBinderMap)
- return ((GroupStmt (stmts', usedBinderMap) groupByClause', thing), fvs)
-
-rnNormalStmtsAndFindUsedBinders :: HsStmtContext Name
- -> [LStmt RdrName]
- -> ([Name] -> RnM (thing, FreeVars))
- -> RnM (([LStmt Name], [Name], thing), FreeVars)
-rnNormalStmtsAndFindUsedBinders ctxt stmts thing_inside = do
- ((stmts', (used_bndrs, inner_thing)), fvs) <- rnNormalStmts ctxt stmts $ do
- -- Find the Names that are bound by stmts that
- -- by assumption we have just renamed
- local_env <- getLocalRdrEnv
- let
- stmts_binders = collectLStmtsBinders stmts
- bndrs = map (expectJust "rnStmt"
- . lookupLocalRdrEnv local_env
- . unLoc) stmts_binders
-
- -- If shadow, we'll look up (Unqual x) twice, getting
- -- the second binding both times, which is the
- -- one we want
- unshadowed_bndrs = nub bndrs
-
- -- Typecheck the thing inside, passing on all
- -- the Names bound before it for its information
- (thing, fvs) <- thing_inside unshadowed_bndrs
-
- -- Figure out which of the bound names are used
- -- after the statements we renamed
- let used_bndrs = filter (`elemNameSet` fvs) bndrs
- return ((used_bndrs, thing), fvs)
-
- -- 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
- where
- 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) <- rnNormalStmtsAndFindUsedBinders ctxt stmts $ \new_bndrs -> do
- -- Typecheck the thing inside, passing on all
- -- the Names bound, but separately; revert the envt
- setLocalRdrEnv orig_lcl_env $ do
- go orig_lcl_env (new_bndrs ++ bndrs_so_far) segs
-
- let seg' = (stmts', bndrs)
- 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:")
+ -- Rename the 'using' expression in the context before the transform is begun
+ ; (using', fvs1) <- case using of
+ Left e -> do { (e', fvs) <- rnLExpr e; return (Left e', fvs) }
+ Right _ -> do { (e', fvs) <- lookupSyntaxName groupWithName
+ ; return (Right e', fvs) }
+
+ -- Rename the stmts and the 'by' expression
+ -- Keep track of the variables mentioned in the 'by' expression
+ ; ((stmts', (by', used_bndrs, thing)), fvs2)
+ <- rnNormalStmts (TransformStmtCtxt ctxt) stmts $ \ bndrs ->
+ do { (by', fvs_by) <- mapMaybeFvRn rnLExpr by
+ ; (thing, fvs_thing) <- thing_inside bndrs
+ ; let fvs = fvs_by `plusFV` fvs_thing
+ used_bndrs = filter (`elemNameSet` fvs) bndrs
+ ; return ((by', used_bndrs, thing), fvs) }
+
+ ; let all_fvs = fvs1 `plusFV` fvs2
+ bndr_map = used_bndrs `zip` used_bndrs
+ -- See Note [GroupStmt binder map] in HsExpr
+
+ ; traceRn (text "rnStmt: implicitly rebound these used binders:" <+> ppr bndr_map)
+ ; return (([L loc (GroupStmt stmts' bndr_map by' using')], thing), all_fvs) }
+
+
+type ParSeg id = ([LStmt id], [id]) -- The Names are bound by the Stmts
+
+rnParallelStmts :: forall thing. HsStmtContext Name
+ -> [ParSeg RdrName]
+ -> ([Name] -> RnM (thing, FreeVars))
+ -> RnM (([ParSeg Name], thing), FreeVars)
+-- Note [Renaming parallel Stmts]
+rnParallelStmts ctxt segs thing_inside
+ = do { orig_lcl_env <- getLocalRdrEnv
+ ; rn_segs orig_lcl_env [] segs }
+ where
+ rn_segs :: LocalRdrEnv
+ -> [Name] -> [ParSeg RdrName]
+ -> RnM (([ParSeg Name], thing), FreeVars)
+ rn_segs _ bndrs_so_far []
+ = do { let (bndrs', dups) = removeDups cmpByOcc bndrs_so_far
+ ; mapM_ dupErr dups
+ ; (thing, fvs) <- bindLocalNames bndrs' (thing_inside bndrs')
+ ; return (([], thing), fvs) }
+
+ rn_segs env bndrs_so_far ((stmts,_) : segs)
+ = do { ((stmts', (used_bndrs, segs', thing)), fvs)
+ <- rnNormalStmts ctxt stmts $ \ bndrs ->
+ setLocalRdrEnv env $ do
+ { ((segs', thing), fvs) <- rn_segs env (bndrs ++ bndrs_so_far) segs
+ ; let used_bndrs = filter (`elemNameSet` fvs) bndrs
+ ; return ((used_bndrs, segs', thing), fvs) }
+
+ ; let seg' = (stmts', used_bndrs)
+ ; return ((seg':segs', thing), fvs) }
+
+ 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}
+Note [Renaming parallel Stmts]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Renaming parallel statements is painful. Given, say
+ [ a+c | a <- as, bs <- bss
+ | c <- bs, a <- ds ]
+Note that
+ (a) In order to report "Defined by not used" about 'bs', we must rename
+ each group of Stmts with a thing_inside whose FreeVars include at least {a,c}
+
+ (b) We want to report that 'a' is illegally bound in both branches
+
+ (c) The 'bs' in the second group must obviously not be captured by
+ the binding in the first group
+
+To satisfy (a) we nest the segements.
+To satisfy (b) we check for duplicates just before thing_inside.
+To satisfy (c) we reset the LocalRdrEnv each time.
%************************************************************************
%* *
-> 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.)
- -- And 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_and_then stmts $ \ segs -> do {
-
- ; (thing, fvs_later) <- thing_inside
-
- ; let
- -- Step 2: 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
-
- -- Step 3: Group together the segments to make bigger segments
- -- Invariant: in the result, no segment uses a variable
- -- bound in a later segment
+ = rn_rec_stmts_and_then stmts $ \ segs -> do
+ { (thing, fvs_later) <- thing_inside
+ ; let segs_w_fwd_refs = addFwdRefs segs
grouped_segs = glomSegments segs_w_fwd_refs
-
- -- Step 4: 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', fvs) = segsToStmts grouped_segs fvs_later
-
- ; return ((stmts', thing), fvs) }
+ (stmts', fvs) = segsToStmts emptyRecStmt grouped_segs fvs_later
+ ; return ((stmts', thing), fvs) }
---------------------------------------------
; 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 $ do
+ ; let bound_names = collectLStmtsBinders (map fst new_lhs_and_fv)
+ ; bindLocalNamesFV bound_names $
+ addLocalFixities fix_env bound_names $ do
-- (C) do the right-hand-sides and thing-inside
{ segs <- rn_rec_stmts bound_names new_lhs_and_fv
fv_pat)]
rn_rec_stmt_lhs _ (L _ (LetStmt binds@(HsIPBinds _)))
- = do { addErr (badIpBinds (ptext (sLit "an mdo expression")) binds)
- ; failM }
+ = 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
+ = do (_bound_names, binds') <- rnLocalValBindsLHS fix_env binds
return [(L loc (LetStmt (HsValBinds binds')),
-- Warning: this is bogus; see function invariant
emptyFVs
)]
-rn_rec_stmt_lhs fix_env (L _ (RecStmt stmts _ _ _ _)) -- Flatten Rec inside Rec
+-- XXX Do we need to do something with the return and mfix names?
+rn_rec_stmt_lhs fix_env (L _ (RecStmt { recS_stmts = stmts })) -- Flatten Rec inside Rec
= rn_rec_stmts_lhs fix_env stmts
rn_rec_stmt_lhs _ stmt@(L _ (ParStmt _)) -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt" (ppr stmt)
-rn_rec_stmt_lhs _ stmt@(L _ (TransformStmt _ _ _)) -- Syntactically illegal in mdo
+rn_rec_stmt_lhs _ stmt@(L _ (TransformStmt {})) -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt" (ppr stmt)
-rn_rec_stmt_lhs _ stmt@(L _ (GroupStmt _ _)) -- Syntactically illegal in mdo
+rn_rec_stmt_lhs _ stmt@(L _ (GroupStmt {})) -- Syntactically illegal in mdo
= pprPanic "rn_rec_stmt" (ppr stmt)
rn_rec_stmt_lhs _ (L _ (LetStmt EmptyLocalBinds))
rn_rec_stmts_lhs :: MiniFixityEnv
-> [LStmt RdrName]
-> RnM [(LStmtLR Name RdrName, FreeVars)]
-rn_rec_stmts_lhs fix_env stmts =
- let boundNames = collectLStmtsBinders stmts
- doc = text "In a recursive mdo-expression"
- in do
- -- 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.
- checkDupRdrNames doc boundNames
- mappM (rn_rec_stmt_lhs fix_env) stmts `thenM` \ ls -> returnM (concat ls)
+rn_rec_stmts_lhs fix_env stmts
+ = do { ls <- concatMapM (rn_rec_stmt_lhs fix_env) stmts
+ ; let boundNames = collectLStmtsBinders (map fst ls)
+ -- 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 boundNames
+ ; return ls }
-- right-hand-sides
rn_rec_stmt _ (L loc (ExprStmt expr _ _)) _
= rnLExpr expr `thenM` \ (expr', fvs) ->
lookupSyntaxName thenMName `thenM` \ (then_op, fvs1) ->
- returnM [(emptyNameSet, fvs `plusFV` fvs1, emptyNameSet,
+ return [(emptyNameSet, fvs `plusFV` fvs1, emptyNameSet,
L loc (ExprStmt expr' then_op placeHolderType))]
rn_rec_stmt _ (L loc (BindStmt pat' expr _ _)) fv_pat
bndrs = mkNameSet (collectPatBinders pat')
fvs = fv_expr `plusFV` fv_pat `plusFV` fvs1 `plusFV` fvs2
in
- returnM [(bndrs, fvs, bndrs `intersectNameSet` fvs,
+ return [(bndrs, fvs, bndrs `intersectNameSet` fvs,
L loc (BindStmt pat' expr' bind_op fail_op))]
rn_rec_stmt _ (L _ (LetStmt binds@(HsIPBinds _))) _
- = do { addErr (badIpBinds (ptext (sLit "an mdo expression")) binds)
- ; failM }
+ = 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'
- returnM [(duDefs du_binds, duUses du_binds,
- emptyNameSet, L loc (LetStmt (HsValBinds binds')))]
+ rnLocalValBindsRHS (mkNameSet all_bndrs) binds'
+ return [(duDefs du_binds, allUses du_binds,
+ emptyNameSet, L loc (LetStmt (HsValBinds binds')))]
-- no RecStmt case becuase they get flattened above when doing the LHSes
-rn_rec_stmt _ stmt@(L _ (RecStmt _ _ _ _ _)) _
+rn_rec_stmt _ stmt@(L _ (RecStmt {})) _
= pprPanic "rn_rec_stmt: RecStmt" (ppr stmt)
-rn_rec_stmt _ 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 _ 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 _ 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)
+rn_rec_stmts bndrs stmts = mapM (uncurry (rn_rec_stmt bndrs)) stmts `thenM` \ segs_s ->
+ return (concat segs_s)
---------------------------------------------
addFwdRefs :: [Segment a] -> [Segment a]
----------------------------------------------------
-segsToStmts :: [Segment [LStmt Name]]
+segsToStmts :: Stmt Name -- A RecStmt with the SyntaxOps filled in
+ -> [Segment [LStmt Name]]
-> FreeVars -- Free vars used 'later'
-> ([LStmt Name], FreeVars)
-segsToStmts [] fvs_later = ([], fvs_later)
-segsToStmts ((defs, uses, fwds, ss) : segs) fvs_later
+segsToStmts _ [] fvs_later = ([], fvs_later)
+segsToStmts empty_rec_stmt ((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 fvs_later
+ (later_stmts, later_uses) = segsToStmts empty_rec_stmt segs fvs_later
new_stmt | non_rec = head ss
- | 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
+ | otherwise = L (getLoc (head ss)) rec_stmt
+ rec_stmt = empty_rec_stmt { recS_stmts = ss
+ , recS_later_ids = nameSetToList used_later
+ , recS_rec_ids = nameSetToList fwds }
+ non_rec = isSingleton ss && isEmptyNameSet fwds
+ used_later = defs `intersectNameSet` later_uses
-- The ones needed after the RecStmt
\end{code}
\begin{code}
srcSpanPrimLit :: SrcSpan -> HsExpr Name
-srcSpanPrimLit span = HsLit (HsStringPrim (mkFastString (showSDoc (ppr span))))
+srcSpanPrimLit span = HsLit (HsStringPrim (mkFastString (showSDocOneLine (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}
---------
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 (DoExpr {}) = return () -- and in 'do'
checkRecStmt ctxt = addErr msg
where
msg = ptext (sLit "Illegal 'rec' stmt in") <+> pprStmtContext ctxt
---------
checkParStmt :: HsStmtContext Name -> RnM ()
checkParStmt _
- = do { parallel_list_comp <- doptM Opt_ParallelListComp
+ = do { parallel_list_comp <- xoptM 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
+ = do { transform_list_comp <- xoptM Opt_TransformListComp
; checkErr transform_list_comp msg }
where
msg = ptext (sLit "Illegal transform or grouping list comprehension: use -XTransformListComp")
checkTransformStmt ctxt = addErr msg
where
msg = ptext (sLit "Illegal transform or grouping in") <+> pprStmtContext ctxt
-
+
---------
+checkTupleSection :: [HsTupArg RdrName] -> RnM ()
+checkTupleSection args
+ = do { tuple_section <- xoptM Opt_TupleSections
+ ; checkErr (all tupArgPresent args || tuple_section) msg }
+ where
+ msg = ptext (sLit "Illegal tuple section: use -XTupleSections")
+
+---------
+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)])