+Typechecking statements is rendered a bit tricky by parallel list comprehensions:
+
+ [ (g x, h x) | ... ; let g v = ...
+ | ... ; let h v = ... ]
+
+It's possible that g,h are overloaded, so we need to feed the LIE from the
+(g x, h x) up through both lots of bindings (so we get the bindInstsOfLocalFuns).
+Similarly if we had an existential pattern match:
+
+ data T = forall a. Show a => C a
+
+ [ (show x, show y) | ... ; C x <- ...
+ | ... ; C y <- ... ]
+
+Then we need the LIE from (show x, show y) to be simplified against
+the bindings for x and y.
+
+It's difficult to do this in parallel, so we rely on the renamer to
+ensure that g,h and x,y don't duplicate, and simply grow the environment.
+So the binders of the first parallel group will be in scope in the second
+group. But that's fine; there's no shadowing to worry about.
+
+\begin{code}
+tcStmts do_or_lc m_ty stmts
+ = tcStmtsAndThen (:) do_or_lc m_ty stmts (returnTc ([], emptyLIE))
+
+tcStmtsAndThen
+ :: (TcStmt -> thing -> thing) -- Combiner
+ -> HsMatchContext
+ -> (TcType -> TcType, TcType) -- m, the relationship type of pat and rhs in pat <- rhs
+ -- elt_ty, where type of the comprehension is (m elt_ty)
+ -> [RenamedStmt]
+ -> TcM (thing, LIE)
+ -> TcM (thing, LIE)
+
+ -- Base case
+tcStmtsAndThen combine do_or_lc m_ty [] do_next
+ = do_next
+
+ -- LetStmt
+tcStmtsAndThen combine do_or_lc m_ty (LetStmt binds : stmts) do_next
+ = tcBindsAndThen -- No error context, but a binding group is
+ (glue_binds combine) -- rather a large thing for an error context anyway
+ binds
+ (tcStmtsAndThen combine do_or_lc m_ty stmts do_next)
+
+ -- BindStmt
+tcStmtsAndThen combine do_or_lc m_ty@(m,elt_ty) (stmt@(BindStmt pat exp src_loc) : stmts) do_next
+ = tcAddSrcLoc src_loc (
+ tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
+ newTyVarTy liftedTypeKind `thenNF_Tc` \ pat_ty ->
+ tcPat tcMonoPatBndr pat pat_ty `thenTc` \ (pat', pat_lie, pat_tvs, pat_ids, avail) ->
+ tcExpr exp (m pat_ty) `thenTc` \ (exp', exp_lie) ->
+ returnTc (pat', exp',
+ pat_lie `plusLIE` exp_lie,
+ pat_tvs, pat_ids, avail)
+ ) `thenTc` \ (pat', exp', lie_req, pat_tvs, pat_bndrs, lie_avail) ->
+ let
+ new_val_env = bagToList pat_bndrs
+ pat_ids = map snd new_val_env
+ in
+
+ -- Do the rest; we don't need to add the pat_tvs to the envt
+ -- because they all appear in the pat_ids's types
+ tcExtendLocalValEnv new_val_env (
+ tcStmtsAndThen combine do_or_lc m_ty stmts do_next
+ ) `thenTc` \ (thing, stmts_lie) ->
+
+ -- Reinstate context for existential checks
+ tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
+ tcCheckExistentialPat pat_ids pat_tvs lie_avail
+ stmts_lie (m elt_ty) `thenTc` \ (final_lie, dict_binds) ->
+
+ returnTc (combine (BindStmt pat' exp' src_loc)
+ (glue_binds combine Recursive dict_binds thing),
+ lie_req `plusLIE` final_lie)
+
+
+ -- ParStmt
+tcStmtsAndThen combine do_or_lc m_ty (ParStmtOut bndr_stmts_s : stmts) do_next
+ = loop bndr_stmts_s `thenTc` \ ((pairs', thing), lie) ->
+ returnTc (combine (ParStmtOut pairs') thing, lie)