- loop [] = thing_inside `thenM` \ thing ->
- returnM ([], thing)
-
- loop ((stmts, bndrs) : pairs)
- = tcStmtsAndThen combine_par ctxt stmts $
- -- Notice we pass on ctxt; the result type is used only
- -- to get escaping type variables for checkExistentialPat
- tcLookupLocalIds bndrs `thenM` \ bndrs' ->
- loop pairs `thenM` \ (pairs', thing) ->
- returnM (([], bndrs') : pairs', thing)
-
- combine_par stmt ((stmts, bndrs) : pairs , thing) = ((stmt:stmts, bndrs) : pairs, thing)
-
- -- RecStmt
-tcStmtAndThen combine ctxt (L src_loc (RecStmt stmts laterNames recNames _)) thing_inside
- = newTyFlexiVarTys (length recNames) liftedTypeKind `thenM` \ recTys ->
- let
- rec_ids = zipWith mkLocalId recNames recTys
- in
- tcExtendIdEnv rec_ids $
- tcStmtsAndThen combine_rec ctxt stmts (
- zipWithM tc_ret recNames recTys `thenM` \ rec_rets ->
- tcLookupLocalIds laterNames `thenM` \ later_ids ->
- returnM ([], (later_ids, rec_rets))
- ) `thenM` \ (stmts', (later_ids, rec_rets)) ->
-
- tcExtendIdEnv later_ids $
- -- NB: The rec_ids for the recursive things
- -- already scope over this part. This binding may shadow
- -- some of them with polymorphic things with the same Name
- -- (see note [RecStmt] in HsExpr)
- getLIE thing_inside `thenM` \ (thing, lie) ->
- bindInstsOfLocalFuns lie later_ids `thenM` \ lie_binds ->
+ glue_binds binds (stmts, thing) = (L loc (LetStmt [binds]) : stmts, thing)
+
+
+-- For the vanilla case, handle the location-setting part
+tcStmts ctxt stmt_chk (L loc stmt : stmts) thing_inside
+ = do { (stmt', (stmts', thing)) <-
+ setSrcSpan loc $
+ addErrCtxt (stmtCtxt ctxt stmt) $
+ stmt_chk ctxt stmt $
+ popErrCtxt $
+ tcStmts ctxt stmt_chk stmts $
+ thing_inside
+ ; return (L loc stmt' : stmts', thing) }
+
+--------------------------------
+-- Pattern guards
+tcGuardStmt :: TcType -> TcStmtChecker
+tcGuardStmt res_ty ctxt (ExprStmt guard _ _) thing_inside
+ = do { guard' <- tcCheckRho guard boolTy
+ ; thing <- thing_inside
+ ; return (ExprStmt guard' noSyntaxExpr boolTy, thing) }
+
+tcGuardStmt res_ty ctxt (BindStmt pat rhs _ _) thing_inside
+ = do { (rhs', rhs_ty) <- tcInferRho rhs
+ ; (pat', thing) <- tcBindPat pat rhs_ty res_ty thing_inside
+ ; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }
+
+tcGuardStmt res_ty ctxt stmt thing_inside
+ = pprPanic "tcGuardStmt: unexpected Stmt" (ppr stmt)
+
+
+--------------------------------
+-- List comprehensions and PArrays
+
+tcLcStmt :: TyCon -- The list/Parray type constructor ([] or PArray)
+ -> TcType -- The element type of the list or PArray
+ -> TcStmtChecker
+
+-- A generator, pat <- rhs
+tcLcStmt m_tc elt_ty ctxt (BindStmt pat rhs _ _) thing_inside
+ = do { (rhs', rhs_ty) <- tcInferRho rhs
+ ; [pat_ty] <- unifyTyConApp m_tc rhs_ty
+ ; (pat', thing) <- tcBindPat pat pat_ty elt_ty thing_inside
+ ; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }
+
+-- A boolean guard
+tcLcStmt m_tc elt_ty ctxt (ExprStmt rhs _ _) thing_inside
+ = do { rhs' <- tcCheckRho rhs boolTy
+ ; thing <- thing_inside
+ ; return (ExprStmt rhs' noSyntaxExpr boolTy, thing) }
+
+-- A parallel set of 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.
+
+tcLcStmt m_tc elt_ty ctxt (ParStmt bndr_stmts_s) thing_inside
+ = do { (pairs', thing) <- loop bndr_stmts_s
+ ; return (ParStmt pairs', thing) }
+ where
+ -- loop :: [([LStmt Name], [Name])] -> TcM ([([LStmt TcId], [TcId])], thing)
+ loop [] = do { thing <- thing_inside
+ ; return ([], thing) }
+
+ loop ((stmts, names) : pairs)
+ = do { (stmts', (ids, pairs', thing))
+ <- tcStmts ctxt (tcLcStmt m_tc elt_ty) stmts $
+ do { ids <- tcLookupLocalIds names
+ ; (pairs', thing) <- loop pairs
+ ; return (ids, pairs', thing) }
+ ; return ( (stmts', ids) : pairs', thing ) }
+
+tcLcStmt m_tc elt_ty ctxt stmt thing_inside
+ = pprPanic "tcLcStmt: unexpected Stmt" (ppr stmt)
+
+--------------------------------
+-- Do-notation
+-- The main excitement here is dealing with rebindable syntax
+
+tcDoStmt :: TcType -- Monad type, m
+ -> TcType -- Result type, m b
+ -> TcStmtChecker
+ -- BindStmt
+tcDoStmt m_ty res_ty ctxt (BindStmt pat rhs bind_op fail_op) thing_inside
+ = do { -- Deal with rebindable syntax; (>>=) :: m a -> (a -> m b) -> m b
+ ; (rhs', rhs_ty) <- tcInferRho rhs
+ -- We should use type *inference* for the RHS computations, becuase of GADTs.
+ -- do { pat <- rhs; <rest> }
+ -- is rather like
+ -- case rhs of { pat -> <rest> }
+ -- We do inference on rhs, so that information about its type can be refined
+ -- when type-checking the pattern.
+
+ ; (n_ty, pat_ty) <- unifyAppTy rhs_ty
+ ; unifyTauTy m_ty n_ty
+ ; let bind_ty = mkFunTys [rhs_ty, mkFunTy pat_ty res_ty] res_ty
+
+ ; (pat', thing) <- tcBindPat pat pat_ty res_ty thing_inside
+
+ -- Rebindable syntax stuff
+ ; bind_op' <- tcSyntaxOp DoOrigin bind_op bind_ty
+ -- If (but only if) the pattern can fail,
+ -- typecheck the 'fail' operator
+ ; fail_op' <- if isIrrefutableHsPat pat'
+ then return noSyntaxExpr
+ else tcSyntaxOp DoOrigin fail_op (mkFunTy stringTy res_ty)
+ ; return (BindStmt pat' rhs' bind_op' fail_op', thing) }
+
+
+tcDoStmt m_ty res_ty ctxt (ExprStmt rhs then_op _) thing_inside
+ = do { -- Deal with rebindable syntax; (>>) :: m a -> m b -> m b
+ a_ty <- newTyFlexiVarTy liftedTypeKind
+ ; let rhs_ty = mkAppTy m_ty a_ty
+ then_ty = mkFunTys [rhs_ty, res_ty] res_ty
+ ; then_op' <- tcSyntaxOp DoOrigin then_op then_ty
+ ; rhs' <- tcCheckSigma rhs rhs_ty
+ ; thing <- thing_inside
+ ; return (ExprStmt rhs' then_op' rhs_ty, thing) }
+
+tcDoStmt m_ty res_ty ctxt stmt thing_inside
+ = pprPanic "tcDoStmt: unexpected Stmt" (ppr stmt)
+
+--------------------------------
+-- Mdo-notation
+-- The distinctive features here are
+-- (a) RecStmts, and
+-- (b) no rebindable syntax
+
+tcMDoStmt :: TcType -- Result type, m b
+ -> (LHsExpr Name -> TcM (LHsExpr TcId, TcType)) -- RHS inference
+ -> TcStmtChecker
+tcMDoStmt res_ty tc_rhs ctxt (BindStmt pat rhs bind_op fail_op) thing_inside
+ = do { (rhs', pat_ty) <- tc_rhs rhs
+ ; (pat', thing) <- tcBindPat pat pat_ty res_ty thing_inside
+ ; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }
+
+tcMDoStmt res_ty tc_rhs ctxt (ExprStmt rhs then_op _) thing_inside
+ = do { (rhs', elt_ty) <- tc_rhs rhs
+ ; thing <- thing_inside
+ ; return (ExprStmt rhs' noSyntaxExpr elt_ty, thing) }
+
+tcMDoStmt res_ty tc_rhs ctxt (RecStmt stmts laterNames recNames _ _) thing_inside
+ = do { rec_tys <- newTyFlexiVarTys (length recNames) liftedTypeKind
+ ; let rec_ids = zipWith mkLocalId recNames rec_tys
+ ; tcExtendIdEnv rec_ids $ do
+ { (stmts', (later_ids, rec_rets))
+ <- tcStmts ctxt (tcMDoStmt res_ty tc_rhs) stmts $
+ -- ToDo: res_ty not really right
+ do { rec_rets <- zipWithM tc_ret recNames rec_tys
+ ; later_ids <- tcLookupLocalIds laterNames
+ ; return (later_ids, rec_rets) }
+
+ ; (thing,lie) <- tcExtendIdEnv later_ids (getLIE thing_inside)
+ -- NB: The rec_ids for the recursive things
+ -- already scope over this part. This binding may shadow
+ -- some of them with polymorphic things with the same Name
+ -- (see note [RecStmt] in HsExpr)
+ ; lie_binds <- bindInstsOfLocalFuns lie later_ids