X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcArrows.lhs;h=3bfa9b4757f0819a346c2a6ac4df438460fa0e98;hb=ac10f8408520a30e8437496d320b8b86afda2e8f;hp=5a76356a9b189c57403ceb5fa646435e5ebb3b2c;hpb=5f553f0c0508cb09b75f78e6c2ac1baa4c01b6aa;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcArrows.lhs b/ghc/compiler/typecheck/TcArrows.lhs index 5a76356..3bfa9b4 100644 --- a/ghc/compiler/typecheck/TcArrows.lhs +++ b/ghc/compiler/typecheck/TcArrows.lhs @@ -8,25 +8,28 @@ module TcArrows ( tcProc ) where #include "HsVersions.h" -import {-# SOURCE #-} TcExpr( tcCheckRho ) +import {-# SOURCE #-} TcExpr( tcMonoExpr, tcInferRho ) import HsSyn -import TcHsSyn ( mkHsLet ) +import TcHsSyn ( mkHsDictLet ) -import TcMatches ( TcStmtCtxt(..), tcMatchPats, matchCtxt, tcStmts, - TcMatchCtxt(..), tcMatchesCase ) +import TcMatches ( matchCtxt, tcStmts, tcMDoStmt, tcGuardStmt, + TcMatchCtxt(..), tcMatchesCase ) -import TcType ( TcType, TcTauType, TcRhoType, mkFunTys, mkTyConApp, - mkTyVarTy, mkAppTys, tcSplitTyConApp_maybe, tcEqType ) -import TcMType ( newTyVarTy, newTyVarTys, newSigTyVar, zonkTcType ) -import TcBinds ( tcBindsAndThen ) +import TcType ( TcType, TcTauType, BoxyRhoType, mkFunTys, mkTyConApp, + mkTyVarTy, mkAppTys, tcSplitTyConApp_maybe, tcEqType, + SkolemInfo(..) ) +import TcMType ( newFlexiTyVarTy, tcInstSkolTyVars, zonkTcType ) +import TcBinds ( tcLocalBinds ) import TcSimplify ( tcSimplifyCheck ) -import TcUnify ( Expected(..), checkSigTyVarsWrt, zapExpectedTo ) +import TcPat ( tcPat, tcPats, PatCtxt(..) ) +import TcUnify ( checkSigTyVarsWrt, boxySplitAppTy ) import TcRnMonad import Inst ( tcSyntaxName ) import Name ( Name ) import TysWiredIn ( boolTy, pairTyCon ) import VarSet +import TysPrim ( alphaTyVar ) import Type ( Kind, mkArrowKinds, liftedTypeKind, openTypeKind, tyVarsOfTypes ) import SrcLoc ( Located(..) ) @@ -43,20 +46,17 @@ import Util ( lengthAtLeast ) \begin{code} tcProc :: InPat Name -> LHsCmdTop Name -- proc pat -> expr - -> Expected TcRhoType -- Expected type of whole proc expression + -> BoxyRhoType -- Expected type of whole proc expression -> TcM (OutPat TcId, LHsCmdTop TcId) tcProc pat cmd exp_ty - = do { arr_ty <- newTyVarTy arrowTyConKind - ; [arg_ty, res_ty] <- newTyVarTys 2 liftedTypeKind - ; zapExpectedTo exp_ty (mkAppTys arr_ty [arg_ty,res_ty]) - + = newArrowScope $ + do { (exp_ty1, res_ty) <- boxySplitAppTy exp_ty + ; (arr_ty, arg_ty) <- boxySplitAppTy exp_ty1 ; let cmd_env = CmdEnv { cmd_arr = arr_ty } - ; ([pat'], cmd', ex_binds) <- incProcLevel $ - tcMatchPats [(pat, Check arg_ty)] (Check res_ty) $ - tcCmdTop cmd_env cmd ([], res_ty) - - ; return (pat', glueBindsOnCmd ex_binds cmd') } + ; (pat', cmd') <- tcPat LamPat pat arg_ty res_ty $ \ res_ty' -> + tcCmdTop cmd_env cmd ([], res_ty') + ; return (pat', cmd') } \end{code} @@ -68,7 +68,10 @@ tcProc pat cmd exp_ty \begin{code} type CmdStack = [TcTauType] -data CmdEnv = CmdEnv { cmd_arr :: TcType } -- The arrow type constructor, of kind *->*->* +data CmdEnv + = CmdEnv { + cmd_arr :: TcType -- arrow type constructor, of kind *->*->* + } mkCmdArrTy :: CmdEnv -> TcTauType -> TcTauType -> TcTauType mkCmdArrTy env t1 t2 = mkAppTys (cmd_arr env) [t1, t2] @@ -83,7 +86,7 @@ tcCmdTop :: CmdEnv -> TcM (LHsCmdTop TcId) tcCmdTop env (L loc (HsCmdTop cmd _ _ names)) (cmd_stk, res_ty) - = addSrcSpan loc $ + = setSrcSpan loc $ do { cmd' <- tcCmd env cmd (cmd_stk, res_ty) ; names' <- mapM (tcSyntaxName ProcOrigin (cmd_arr env)) names ; return (L loc $ HsCmdTop cmd' cmd_stk res_ty names') } @@ -93,7 +96,7 @@ tcCmdTop env (L loc (HsCmdTop cmd _ _ names)) (cmd_stk, res_ty) tcCmd :: CmdEnv -> LHsExpr Name -> (CmdStack, TcTauType) -> TcM (LHsExpr TcId) -- The main recursive function tcCmd env (L loc expr) res_ty - = addSrcSpan loc $ do + = setSrcSpan loc $ do { expr' <- tc_cmd env expr res_ty ; return (L loc expr') } @@ -102,27 +105,25 @@ tc_cmd env (HsPar cmd) res_ty ; return (HsPar cmd') } tc_cmd env (HsLet binds (L body_loc body)) res_ty - = tcBindsAndThen glue binds $ - addSrcSpan body_loc $ - tc_cmd env body res_ty - where - glue binds expr = HsLet [binds] (L body_loc expr) + = do { (binds', body') <- tcLocalBinds binds $ + setSrcSpan body_loc $ + tc_cmd env body res_ty + ; return (HsLet binds' (L body_loc body')) } tc_cmd env in_cmd@(HsCase scrut matches) (stk, res_ty) = addErrCtxt (cmdCtxt in_cmd) $ - tcMatchesCase match_ctxt matches (Check res_ty) - `thenM` \ (scrut_ty, matches') -> addErrCtxt (caseScrutCtxt scrut) ( - tcCheckRho scrut scrut_ty - ) `thenM` \ scrut' -> + tcInferRho scrut + ) `thenM` \ (scrut', scrut_ty) -> + tcMatchesCase match_ctxt scrut_ty matches res_ty `thenM` \ matches' -> returnM (HsCase scrut' matches') where match_ctxt = MC { mc_what = CaseAlt, mc_body = mc_body } - mc_body body (Check res_ty') = tcCmd env body (stk, res_ty') + mc_body body res_ty' = tcCmd env body (stk, res_ty') tc_cmd env (HsIf pred b1 b2) res_ty - = do { pred' <- tcCheckRho pred boolTy + = do { pred' <- tcMonoExpr pred boolTy ; b1' <- tcCmd env b1 res_ty ; b2' <- tcCmd env b2 res_ty ; return (HsIf pred' b1' b2') @@ -130,113 +131,110 @@ tc_cmd env (HsIf pred b1 b2) res_ty ------------------------------------------- -- Arrow application --- (f -< a) or (f =< a) +-- (f -< a) or (f -<< a) tc_cmd env cmd@(HsArrApp fun arg _ ho_app lr) (cmd_stk, res_ty) = addErrCtxt (cmdCtxt cmd) $ - do { arg_ty <- newTyVarTy openTypeKind - ; let fun_ty = mkCmdArrTy env arg_ty res_ty + do { arg_ty <- newFlexiTyVarTy openTypeKind + ; let fun_ty = mkCmdArrTy env (foldl mkPairTy arg_ty cmd_stk) res_ty - ; checkTc (null cmd_stk) (nonEmptyCmdStkErr cmd) + ; fun' <- select_arrow_scope (tcMonoExpr fun fun_ty) - ; fun' <- pop_arrow_binders (tcCheckRho fun fun_ty) - - ; arg' <- tcCheckRho arg arg_ty + ; arg' <- tcMonoExpr arg arg_ty ; return (HsArrApp fun' arg' fun_ty ho_app lr) } where - -- Before type-checking f, remove the "arrow binders" from the - -- environment in the (-<) case. + -- Before type-checking f, use the environment of the enclosing + -- proc for the (-<) case. -- Local bindings, inside the enclosing proc, are not in scope - -- inside f. In the higher-order case (--<), they are. - pop_arrow_binders tc = case ho_app of + -- inside f. In the higher-order case (-<<), they are. + select_arrow_scope tc = case ho_app of HsHigherOrderApp -> tc - HsFirstOrderApp -> popArrowBinders tc + HsFirstOrderApp -> escapeArrowScope tc ------------------------------------------- -- Command application tc_cmd env cmd@(HsApp fun arg) (cmd_stk, res_ty) = addErrCtxt (cmdCtxt cmd) $ - do { arg_ty <- newTyVarTy openTypeKind +-- gaw 2004 FIX? + do { arg_ty <- newFlexiTyVarTy openTypeKind ; fun' <- tcCmd env fun (arg_ty:cmd_stk, res_ty) - ; arg' <- tcCheckRho arg arg_ty + ; arg' <- tcMonoExpr arg arg_ty ; return (HsApp fun' arg') } ------------------------------------------- -- Lambda -tc_cmd env cmd@(HsLam (L mtch_loc match@(Match pats maybe_rhs_sig grhss))) (cmd_stk, res_ty) +-- gaw 2004 +tc_cmd env cmd@(HsLam (MatchGroup [L mtch_loc (match@(Match pats maybe_rhs_sig grhss))] _)) + (cmd_stk, res_ty) = addErrCtxt (matchCtxt match_ctxt match) $ do { -- Check the cmd stack is big enough ; checkTc (lengthAtLeast cmd_stk n_pats) (kappaUnderflow cmd) - ; let pats_w_tys = zip pats (map Check cmd_stk) -- Check the patterns, and the GRHSs inside - ; (pats', grhss', ex_binds) <- addSrcSpan mtch_loc $ - tcMatchPats pats_w_tys (Check res_ty) $ - tc_grhss grhss + ; (pats', grhss') <- setSrcSpan mtch_loc $ + tcPats LamPat pats cmd_stk res_ty $ + tc_grhss grhss - ; return (HsLam (L mtch_loc (Match pats' Nothing (glueBindsOnGRHSs ex_binds grhss')))) + ; let match' = L mtch_loc (Match pats' Nothing grhss') + ; return (HsLam (MatchGroup [match'] res_ty)) } where n_pats = length pats stk' = drop n_pats cmd_stk match_ctxt = LambdaExpr -- Maybe KappaExpr? + pg_ctxt = PatGuard match_ctxt - tc_grhss (GRHSs grhss binds _) - = tcBindsAndThen glueBindsOnGRHSs binds $ - do { grhss' <- mappM (wrapLocM tc_grhs) grhss - ; return (GRHSs grhss' [] res_ty) } + tc_grhss (GRHSs grhss binds) res_ty + = do { (binds', grhss') <- tcLocalBinds binds $ + mapM (wrapLocM (tc_grhs res_ty)) grhss + ; return (GRHSs grhss' binds') } - stmt_ctxt = SC { sc_what = PatGuard match_ctxt, - sc_rhs = tcCheckRho, - sc_body = \ body -> tcCmd env body (stk', res_ty), - sc_ty = res_ty } -- ToDo: Is this right? - tc_grhs (GRHS guarded) - = do { guarded' <- tcStmts stmt_ctxt guarded - ; return (GRHS guarded') } + tc_grhs res_ty (GRHS guards body) + = do { (guards', rhs') <- tcStmts pg_ctxt tcGuardStmt + guards res_ty + (\res_ty' -> tcCmd env body (stk', res_ty')) + ; return (GRHS guards' rhs') } ------------------------------------------- -- Do notation -tc_cmd env cmd@(HsDo do_or_lc stmts _ ty) (cmd_stk, res_ty) +tc_cmd env cmd@(HsDo do_or_lc stmts body ty) (cmd_stk, res_ty) = do { checkTc (null cmd_stk) (nonEmptyCmdStkErr cmd) - ; stmts' <- tcStmts stmt_ctxt stmts - ; return (HsDo do_or_lc stmts' [] res_ty) } - -- The 'methods' needed for the HsDo are in the enclosing HsCmd - -- hence the empty list here + ; (stmts', body') <- tcStmts do_or_lc tc_stmt stmts res_ty $ \ res_ty' -> + tcCmd env body ([], res_ty') + ; return (HsDo do_or_lc stmts' body' res_ty) } where - stmt_ctxt = SC { sc_what = do_or_lc, - sc_rhs = tc_rhs, - sc_body = tc_ret, - sc_ty = res_ty } - - tc_rhs rhs ty = tcCmd env rhs ([], ty) - tc_ret body = tcCmd env body ([], res_ty) + tc_stmt = tcMDoStmt tc_rhs + tc_rhs rhs = do { ty <- newFlexiTyVarTy liftedTypeKind + ; rhs' <- tcCmd env rhs ([], ty) + ; return (rhs', ty) } ----------------------------------------------------------------- --- Arrow ``forms'' (| e |) c1 .. cn +-- Arrow ``forms'' (| e c1 .. cn |) -- -- G |-b c : [s1 .. sm] s -- pop(G) |- e : forall w. b ((w,s1) .. sm) s -- -> a ((w,t1) .. tn) t -- e \not\in (s, s1..sm, t, t1..tn) -- ---------------------------------------------- --- G |-a (| e |) c : [t1 .. tn] t +-- G |-a (| e c |) : [t1 .. tn] t tc_cmd env cmd@(HsArrForm expr fixity cmd_args) (cmd_stk, res_ty) = addErrCtxt (cmdCtxt cmd) $ do { cmds_w_tys <- zipWithM new_cmd_ty cmd_args [1..] - ; w_tv <- newSigTyVar liftedTypeKind - ; let w_ty = mkTyVarTy w_tv + ; span <- getSrcSpanM + ; [w_tv] <- tcInstSkolTyVars (ArrowSkol span) [alphaTyVar] + ; let w_ty = mkTyVarTy w_tv -- Just a convenient starting point -- a ((w,t1) .. tn) t ; let e_res_ty = mkCmdArrTy env (foldl mkPairTy w_ty cmd_stk) res_ty @@ -247,19 +245,18 @@ tc_cmd env cmd@(HsArrForm expr fixity cmd_args) (cmd_stk, res_ty) e_res_ty -- Check expr - ; (expr', lie) <- getLIE (tcCheckRho expr e_ty) + ; (expr', lie) <- escapeArrowScope (getLIE (tcMonoExpr expr e_ty)) ; inst_binds <- tcSimplifyCheck sig_msg [w_tv] [] lie -- Check that the polymorphic variable hasn't been unified with anything -- and is not free in res_ty or the cmd_stk (i.e. t, t1..tn) - ; [w_tv'] <- checkSigTyVarsWrt (tyVarsOfTypes (res_ty:cmd_stk)) - [w_tv] + ; checkSigTyVarsWrt (tyVarsOfTypes (res_ty:cmd_stk)) [w_tv] -- OK, now we are in a position to unscramble -- the s1..sm and check each cmd - ; cmds' <- mapM (tc_cmd w_tv') cmds_w_tys + ; cmds' <- mapM (tc_cmd w_tv) cmds_w_tys - ; returnM (HsArrForm (mkHsTyLam [w_tv'] (mkHsLet inst_binds expr')) fixity cmds') + ; returnM (HsArrForm (mkHsTyLam [w_tv] (mkHsDictLet inst_binds expr')) fixity cmds') } where -- Make the types @@ -267,11 +264,12 @@ tc_cmd env cmd@(HsArrForm expr fixity cmd_args) (cmd_stk, res_ty) new_cmd_ty :: LHsCmdTop Name -> Int -> TcM (LHsCmdTop Name, Int, TcType, TcType, TcType) new_cmd_ty cmd i - = do { b_ty <- newTyVarTy arrowTyConKind - ; tup_ty <- newTyVarTy liftedTypeKind +-- gaw 2004 FIX? + = do { b_ty <- newFlexiTyVarTy arrowTyConKind + ; tup_ty <- newFlexiTyVarTy liftedTypeKind -- We actually make a type variable for the tuple -- because we don't know how deeply nested it is yet - ; s_ty <- newTyVarTy liftedTypeKind + ; s_ty <- newFlexiTyVarTy liftedTypeKind ; return (cmd, i, b_ty, tup_ty, s_ty) } @@ -286,7 +284,7 @@ tc_cmd env cmd@(HsArrForm expr fixity cmd_args) (cmd_stk, res_ty) not (w_tv `elemVarSet` tyVarsOfTypes arg_tys)) (badFormFun i tup_ty') - ; tcCmdTop (CmdEnv { cmd_arr = b }) cmd (arg_tys, s) } + ; tcCmdTop (env { cmd_arr = b }) cmd (arg_tys, s) } unscramble :: TcType -> (TcType, [TcType]) -- unscramble ((w,s1) .. sn) = (w, [s1..sn]) @@ -319,14 +317,9 @@ tc_cmd env cmd _ \begin{code} -glueBindsOnCmd binds (L loc (HsCmdTop cmd stk res_ty names)) - = L loc (HsCmdTop (L loc (HsLet [binds] cmd)) stk res_ty names) - -- Existential bindings become local bindings in the command - - mkPairTy t1 t2 = mkTyConApp pairTyCon [t1,t2] -arrowTyConKind :: Kind -- *->*->* +arrowTyConKind :: Kind -- *->*->* arrowTyConKind = mkArrowKinds [liftedTypeKind, liftedTypeKind] liftedTypeKind \end{code}