-\%
+%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcMatches]{Typecheck some @Matches@}
import HsSyn ( HsBinds(..), Match(..), GRHSs(..), GRHS(..),
MonoBinds(..), StmtCtxt(..), Stmt(..),
pprMatch, getMatchLoc, consLetStmt,
- mkMonoBind
+ mkMonoBind, collectSigTysFromPats
)
import RnHsSyn ( RenamedMatch, RenamedGRHSs, RenamedStmt )
import TcHsSyn ( TcMatch, TcGRHSs, TcStmt )
import TcMonad
-import TcMonoType ( checkSigTyVars, tcHsTyVar, tcHsSigType, sigPatCtxt )
-import Inst ( Inst, LIE, plusLIE, emptyLIE, plusLIEs )
-import TcEnv ( tcExtendLocalValEnv, tcExtendGlobalTyVars, tcExtendTyVarEnv, tcGetGlobalTyVars )
+import TcMonoType ( kcHsSigType, tcTyVars, checkSigTyVars, tcHsSigType, sigPatCtxt )
+import Inst ( LIE, plusLIE, emptyLIE, plusLIEs )
+import TcEnv ( tcExtendTyVarEnv, tcExtendLocalValEnv, tcExtendGlobalTyVars )
import TcPat ( tcPat, tcPatBndr_NoSigs, polyPatSig )
-import TcType ( TcType, newTyVarTy, newTyVarTy_OpenKind, zonkTcTyVars )
+import TcType ( TcType, newTyVarTy )
import TcBinds ( tcBindsAndThen )
import TcSimplify ( tcSimplifyAndCheck, bindInstsOfLocalFuns )
import TcUnify ( unifyFunTy, unifyTauTy )
import TysWiredIn ( boolTy )
import BasicTypes ( RecFlag(..) )
-import Type ( Kind, tyVarsOfType, isTauTy, mkFunTy, boxedTypeKind )
+import Type ( tyVarsOfType, isTauTy, mkFunTy, boxedTypeKind, openTypeKind )
import VarSet
import Var ( Id )
-import Util
import Bag
import Outputable
import List ( nub )
-> Name
-> TcType -- Expected type
-> [RenamedMatch]
- -> TcM s ([TcMatch], LIE)
+ -> TcM ([TcMatch], LIE)
tcMatchesFun xve fun_name expected_ty matches@(first_match:_)
= -- Check that they all have the same no of arguments
\begin{code}
tcMatchesCase :: [RenamedMatch] -- The case alternatives
-> TcType -- Type of whole case expressions
- -> TcM s (TcType, -- Inferred type of the scrutinee
+ -> TcM (TcType, -- Inferred type of the scrutinee
[TcMatch], -- Translated alternatives
LIE)
tcMatchesCase matches expr_ty
- = newTyVarTy_OpenKind `thenNF_Tc` \ scrut_ty ->
+ = newTyVarTy openTypeKind `thenNF_Tc` \ scrut_ty ->
tcMatches [] matches (mkFunTy scrut_ty expr_ty) CaseAlt `thenTc` \ (matches', lie) ->
returnTc (scrut_ty, matches', lie)
-tcMatchLambda :: RenamedMatch -> TcType -> TcM s (TcMatch, LIE)
+tcMatchLambda :: RenamedMatch -> TcType -> TcM (TcMatch, LIE)
tcMatchLambda match res_ty = tcMatch [] match res_ty LambdaBody
\end{code}
-> [RenamedMatch]
-> TcType
-> StmtCtxt
- -> TcM s ([TcMatch], LIE)
+ -> TcM ([TcMatch], LIE)
tcMatches xve matches expected_ty fun_or_case
= mapAndUnzipTc tc_match matches `thenTc` \ (matches, lies) ->
-> TcType -- Expected result-type of the Match.
-- Early unification with this guy gives better error messages
-> StmtCtxt
- -> TcM s (TcMatch, LIE)
+ -> TcM (TcMatch, LIE)
tcMatch xve1 match@(Match sig_tvs pats maybe_rhs_sig grhss) expected_ty ctxt
= tcAddSrcLoc (getMatchLoc match) $
-- If there are sig tvs we must be careful *not* to use
-- expected_ty right away, else we'll unify with tyvars free
-- in the envt. So invent a fresh tyvar and use that instead
- newTyVarTy_OpenKind `thenNF_Tc` \ tyvar_ty ->
+ newTyVarTy openTypeKind `thenNF_Tc` \ tyvar_ty ->
-- Extend the tyvar env and check the match itself
- mapNF_Tc tcHsTyVar sig_tvs `thenNF_Tc` \ sig_tyvars ->
- tcExtendTyVarEnv sig_tyvars (
- tc_match tyvar_ty
- ) `thenTc` \ (pat_ids, match_and_lie) ->
+ tcTyVars sig_tvs (mapTc_ kcHsSigType sig_tys) `thenTc` \ sig_tyvars ->
+ tcExtendTyVarEnv sig_tyvars (tc_match tyvar_ty) `thenTc` \ (pat_ids, match_and_lie) ->
-- Check that the scoped type variables from the patterns
-- have not been constrained
tcAddErrCtxtM (sigPatCtxt sig_tyvars pat_ids) (
- checkSigTyVars sig_tyvars
+ checkSigTyVars sig_tyvars emptyVarSet
) `thenTc_`
-- *Now* we're free to unify with expected_ty
returnTc match_and_lie
where
+ sig_tys = case maybe_rhs_sig of { Just t -> [t]; Nothing -> [] }
+ ++ collectSigTysFromPats pats
+
tc_match expected_ty -- Any sig tyvars are in scope by now
= -- STEP 1: Typecheck the patterns
tcMatchPats pats expected_ty `thenTc` \ (rhs_ty, pats', lie_req1, ex_tvs, pat_bndrs, lie_avail) ->
-- STEP 3: Unify with the rhs type signature if any
(case maybe_rhs_sig of
Nothing -> returnTc ()
- Just sig -> tcHsSigType sig `thenTc` \ sig_ty ->
+ Just sig -> tcHsSigType sig `thenTc` \ sig_ty ->
-- Check that the signature isn't a polymorphic one, which
-- we don't permit (at present, anyway)
-- STEP 5: Check for existentially bound type variables
tcExtendGlobalTyVars (tyVarsOfType rhs_ty) (
tcAddErrCtxtM (sigPatCtxt ex_tv_list pat_ids) $
- checkSigTyVars ex_tv_list `thenTc` \ zonked_ex_tvs ->
+ checkSigTyVars ex_tv_list emptyVarSet `thenTc` \ zonked_ex_tvs ->
tcSimplifyAndCheck
(text ("the existential context of a data constructor"))
(mkVarSet zonked_ex_tvs)
tcGRHSs :: RenamedGRHSs
-> TcType -> StmtCtxt
- -> TcM s (TcGRHSs, LIE)
+ -> TcM (TcGRHSs, LIE)
tcGRHSs (GRHSs grhss binds _) expected_ty ctxt
= tcBindsAndThen glue_on binds (tc_grhss grhss)
-> (TcType -> TcType) -- m, the relationship type of pat and rhs in pat <- rhs
-> [RenamedStmt]
-> TcType -- elt_ty, where type of the comprehension is (m elt_ty)
- -> TcM s ([TcStmt], LIE)
+ -> TcM ([TcStmt], LIE)
tcStmts do_or_lc m (stmt@(ReturnStmt exp) : stmts) elt_ty
= ASSERT( null stmts )
tcAddSrcLoc src_loc (
tcSetErrCtxt (stmtCtxt do_or_lc stmt) $
-- exp has type (m tau) for some tau (doesn't matter what)
- newTyVarTy_OpenKind `thenNF_Tc` \ any_ty ->
+ newTyVarTy openTypeKind `thenNF_Tc` \ any_ty ->
tcExpr exp (m any_ty)
) `thenTc` \ (exp', exp_lie) ->
tcStmts do_or_lc m stmts elt_ty `thenTc` \ (stmts', stmts_lie) ->
tcExtendGlobalTyVars (tyVarsOfType (m elt_ty)) $
tcAddErrCtxtM (sigPatCtxt pat_tv_list pat_ids) $
- checkSigTyVars pat_tv_list `thenTc` \ zonked_pat_tvs ->
+ checkSigTyVars pat_tv_list emptyVarSet `thenTc` \ zonked_pat_tvs ->
tcSimplifyAndCheck
(text ("the existential context of a data constructor"))