-\begin{code}
-tcMatchPats
- :: [RenamedPat] -> TcType
- -> ([TypecheckedPat] -> TcType -> TcM (a, LIE))
- -> TcM (a, LIE, TcDictBinds)
--- Typecheck the patterns, extend the environment to bind the variables,
--- do the thing inside, use any existentially-bound dictionaries to
--- discharge parts of the returning LIE, and deal with pattern type
--- signatures
-
-tcMatchPats pats expected_ty thing_inside
- = -- STEP 1: Bring pattern-signature type variables into scope
- tcAddScopedTyVars (collectSigTysFromPats pats) (
-
- -- STEP 2: Typecheck the patterns themselves, gathering all the stuff
- tc_match_pats pats expected_ty `thenTc` \ (rhs_ty, pats', lie_req1, ex_tvs, pat_bndrs, lie_avail) ->
-
- -- STEP 3: Extend the environment, and do the thing inside
- let
- xve = bagToList pat_bndrs
- pat_ids = map snd xve
- in
- tcExtendLocalValEnv xve (thing_inside pats' rhs_ty) `thenTc` \ (result, lie_req2) ->
-
- returnTc (rhs_ty, lie_req1, ex_tvs, pat_ids, lie_avail, result, lie_req2)
- ) `thenTc` \ (rhs_ty, lie_req1, ex_tvs, pat_ids, lie_avail, result, lie_req2) ->
-
- -- STEP 4: Check for existentially bound type variables
- -- Do this *outside* the scope of the tcAddScopedTyVars, else checkSigTyVars
- -- complains that 'a' is captured by the inscope 'a'! (Test (d) in checkSigTyVars.)
- --
- -- I'm a bit concerned that lie_req1 from an 'inner' pattern in the list
- -- might need (via lie_req2) something made available from an 'outer'
- -- pattern. But it's inconvenient to deal with, and I can't find an example
- tcCheckExistentialPat pat_ids ex_tvs lie_avail lie_req2 expected_ty `thenTc` \ (lie_req2', ex_binds) ->
- -- NB: we *must* pass "expected_ty" not "result_ty" to tcCheckExistentialPat
- -- For example, we must reject this program:
- -- data C = forall a. C (a -> Int)
- -- f (C g) x = g x
- -- Here, result_ty will be simply Int, but expected_ty is (a -> Int).
-
- returnTc (result, lie_req1 `plusLIE` lie_req2', ex_binds)
-
-tcAddScopedTyVars :: [RenamedHsType] -> TcM a -> TcM a
--- Find the not-already-in-scope signature type variables,
--- kind-check them, and bring them into scope
---
--- We no longer specify that these type variables must be univerally
--- quantified (lots of email on the subject). If you want to put that
--- back in, you need to
--- a) Do a checkSigTyVars after thing_inside
--- b) More insidiously, don't pass in expected_ty, else
--- we unify with it too early and checkSigTyVars barfs
--- Instead you have to pass in a fresh ty var, and unify
--- it with expected_ty afterwards
-tcAddScopedTyVars sig_tys thing_inside
- = tcGetEnv `thenNF_Tc` \ env ->
- let
- all_sig_tvs = foldr (unionNameSets . extractHsTyVars) emptyNameSet sig_tys
- sig_tvs = filter not_in_scope (nameSetToList all_sig_tvs)
- not_in_scope tv = not (tcInLocalScope env tv)
- in
- tcScopedTyVars sig_tvs (kcHsSigTypes sig_tys) thing_inside
-
-tcCheckExistentialPat :: [TcId] -- Ids bound by this pattern
- -> Bag TcTyVar -- Existentially quantified tyvars bound by pattern
- -> LIE -- and context
- -> LIE -- Required context
- -> TcType -- and type of the Match; vars in here must not escape
- -> TcM (LIE, TcDictBinds) -- LIE to float out and dict bindings
-tcCheckExistentialPat ids ex_tvs lie_avail lie_req match_ty
- | isEmptyBag ex_tvs && all not_overloaded ids
- -- Short cut for case when there are no existentials
- -- and no polymorphic overloaded variables
- -- e.g. f :: (forall a. Ord a => a -> a) -> Int -> Int
- -- f op x = ....
- -- Here we must discharge op Methods
- = ASSERT( isEmptyLIE lie_avail )
- returnTc (lie_req, EmptyMonoBinds)
-
- | otherwise
- = tcExtendGlobalTyVars (tyVarsOfType match_ty) $
- tcAddErrCtxtM (sigPatCtxt tv_list ids) $
-
- -- In case there are any polymorpic, overloaded binders in the pattern
- -- (which can happen in the case of rank-2 type signatures, or data constructors
- -- with polymorphic arguments), we must do a bindInstsOfLocalFns here
- bindInstsOfLocalFuns lie_req ids `thenTc` \ (lie1, inst_binds) ->
-
- -- Deal with overloaded functions bound by the pattern
- tcSimplifyCheck doc tv_list (lieToList lie_avail) lie1 `thenTc` \ (lie2, dict_binds) ->
- checkSigTyVars tv_list emptyVarSet `thenTc_`
-
- returnTc (lie2, dict_binds `AndMonoBinds` inst_binds)
- where
- doc = text ("the existential context of a data constructor")
- tv_list = bagToList ex_tvs
- not_overloaded id = not (isOverloadedTy (idType id))
-
-tc_match_pats [] expected_ty
- = returnTc (expected_ty, [], emptyLIE, emptyBag, emptyBag, emptyLIE)
-
-tc_match_pats (pat:pats) expected_ty
- = unifyFunTy expected_ty `thenTc` \ (arg_ty, rest_ty) ->
- tcPat tcMonoPatBndr pat arg_ty `thenTc` \ (pat', lie_req, pat_tvs, pat_ids, lie_avail) ->
- tc_match_pats pats rest_ty `thenTc` \ (rhs_ty, pats', lie_reqs, pats_tvs, pats_ids, lie_avails) ->
- returnTc ( rhs_ty,
- pat':pats',
- lie_req `plusLIE` lie_reqs,
- pat_tvs `unionBags` pats_tvs,
- pat_ids `unionBags` pats_ids,
- lie_avail `plusLIE` lie_avails
- )
+\begin{code}
+tcDoStmts :: HsStmtContext Name
+ -> [LStmt Name]
+ -> LHsExpr Name
+ -> BoxyRhoType
+ -> TcM (HsExpr TcId) -- Returns a HsDo
+tcDoStmts ListComp stmts body res_ty
+ = do { elt_ty <- boxySplitListTy res_ty
+ ; (stmts', body') <- tcStmts ListComp (tcLcStmt listTyCon) stmts elt_ty $
+ tcBody (doBodyCtxt ListComp body) body
+ ; return (HsDo ListComp stmts' body' (mkListTy elt_ty)) }
+
+tcDoStmts PArrComp stmts body res_ty
+ = do { [elt_ty] <- boxySplitTyConApp parrTyCon res_ty
+ ; (stmts', body') <- tcStmts PArrComp (tcLcStmt parrTyCon) stmts elt_ty $
+ tcBody (doBodyCtxt PArrComp body) body
+ ; return (HsDo PArrComp stmts' body' (mkPArrTy elt_ty)) }
+
+tcDoStmts DoExpr stmts body res_ty
+ = do { (m_ty, elt_ty) <- boxySplitAppTy res_ty
+ ; let res_ty' = mkAppTy m_ty elt_ty -- The boxySplit consumes res_ty
+ ; (stmts', body') <- tcStmts DoExpr (tcDoStmt m_ty) stmts res_ty' $
+ tcBody (doBodyCtxt DoExpr body) body
+ ; return (HsDo DoExpr stmts' body' res_ty') }
+
+tcDoStmts ctxt@(MDoExpr _) stmts body res_ty
+ = do { (m_ty, elt_ty) <- boxySplitAppTy res_ty
+ ; let res_ty' = mkAppTy m_ty elt_ty -- The boxySplit consumes res_ty
+ tc_rhs rhs = withBox liftedTypeKind $ \ pat_ty ->
+ tcMonoExpr rhs (mkAppTy m_ty pat_ty)
+
+ ; (stmts', body') <- tcStmts ctxt (tcMDoStmt tc_rhs) stmts res_ty' $
+ tcBody (doBodyCtxt ctxt body) body
+
+ ; let names = [mfixName, bindMName, thenMName, returnMName, failMName]
+ ; insts <- mapM (newMethodFromName DoOrigin m_ty) names
+ ; return (HsDo (MDoExpr (names `zip` insts)) stmts' body' res_ty') }
+
+tcDoStmts ctxt stmts body res_ty = pprPanic "tcDoStmts" (pprStmtContext ctxt)
+
+tcBody :: Message -> LHsExpr Name -> BoxyRhoType -> TcM (LHsExpr TcId)
+tcBody ctxt body res_ty
+ = -- addErrCtxt ctxt $ -- This context adds little that is useful
+ tcPolyExpr body res_ty