X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcArrows.lhs;h=227c6ce923abded27256a736230495ac740d7553;hp=0055d6453feb9f0f60fe7f8a2f8aca2cfae322ac;hb=b10d7d079ec9c3fc22d4700fe484dd297bddb805;hpb=6a05ec5ef5373f61b7f9f5bdc344483417fa801b diff --git a/compiler/typecheck/TcArrows.lhs b/compiler/typecheck/TcArrows.lhs index 0055d64..227c6ce 100644 --- a/compiler/typecheck/TcArrows.lhs +++ b/compiler/typecheck/TcArrows.lhs @@ -5,29 +5,15 @@ Typecheck arrow notation \begin{code} -{-# OPTIONS -w #-} --- The above warning supression flag is a temporary kludge. --- While working on this module you are encouraged to remove it and fix --- any warnings in the module. See --- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings --- for details - module TcArrows ( tcProc ) where -#include "HsVersions.h" - import {-# SOURCE #-} TcExpr( tcMonoExpr, tcInferRho ) import HsSyn -import TcHsSyn - import TcMatches - import TcType import TcMType import TcBinds -import TcSimplify -import TcGadt import TcPat import TcUnify import TcRnMonad @@ -37,11 +23,13 @@ import Name import TysWiredIn import VarSet import TysPrim -import Type import SrcLoc import Outputable +import FastString import Util + +import Control.Monad \end{code} %************************************************************************ @@ -52,19 +40,18 @@ import Util \begin{code} tcProc :: InPat Name -> LHsCmdTop Name -- proc pat -> expr - -> BoxyRhoType -- Expected type of whole proc expression + -> TcRhoType -- Expected type of whole proc expression -> TcM (OutPat TcId, LHsCmdTop TcId, CoercionI) tcProc pat cmd exp_ty = newArrowScope $ - do { ((exp_ty1, res_ty), coi) <- boxySplitAppTy exp_ty - ; ((arr_ty, arg_ty), coi1) <- boxySplitAppTy exp_ty1 + do { (coi, (exp_ty1, res_ty)) <- matchExpectedAppTy exp_ty + ; (coi1, (arr_ty, arg_ty)) <- matchExpectedAppTy exp_ty1 ; let cmd_env = CmdEnv { cmd_arr = arr_ty } - ; (pat', cmd') <- tcLamPat pat arg_ty (emptyRefinement, res_ty) $ - tcCmdTop cmd_env cmd [] - ; let res_coi = mkTransCoI coi (mkAppTyCoI exp_ty1 coi1 res_ty IdCo) - ; return (pat', cmd', res_coi) - } + ; (pat', cmd') <- tcPat ProcExpr pat arg_ty $ + tcCmdTop cmd_env cmd [] res_ty + ; let res_coi = mkTransCoI coi (mkAppTyCoI coi1 (IdCo res_ty)) + ; return (pat', cmd', res_coi) } \end{code} @@ -88,27 +75,27 @@ mkCmdArrTy env t1 t2 = mkAppTys (cmd_arr env) [t1, t2] tcCmdTop :: CmdEnv -> LHsCmdTop Name -> CmdStack - -> (Refinement, TcTauType) -- Expected result type; always a monotype - -- We know exactly how many cmd args are expected, - -- albeit perhaps not their types; so we can pass - -- in a CmdStack + -> TcTauType -- Expected result type; always a monotype + -- We know exactly how many cmd args are expected, + -- albeit perhaps not their types; so we can pass + -- in a CmdStack -> TcM (LHsCmdTop TcId) -tcCmdTop env (L loc (HsCmdTop cmd _ _ names)) cmd_stk reft_res_ty@(_,res_ty) +tcCmdTop env (L loc (HsCmdTop cmd _ _ names)) cmd_stk res_ty = setSrcSpan loc $ - do { cmd' <- tcGuardedCmd env cmd cmd_stk reft_res_ty + do { cmd' <- tcGuardedCmd env cmd cmd_stk res_ty ; names' <- mapM (tcSyntaxName ProcOrigin (cmd_arr env)) names ; return (L loc $ HsCmdTop cmd' cmd_stk res_ty names') } ---------------------------------------- tcGuardedCmd :: CmdEnv -> LHsExpr Name -> CmdStack - -> (Refinement, TcTauType) -> TcM (LHsExpr TcId) + -> TcTauType -> TcM (LHsExpr TcId) -- A wrapper that deals with the refinement (if any) -tcGuardedCmd env expr stk (reft, res_ty) - = do { let (co, res_ty') = refineResType reft res_ty - ; body <- tcCmd env expr (stk, res_ty') - ; return (mkLHsWrap co body) } +tcGuardedCmd env expr stk res_ty + = do { body <- tcCmd env expr (stk, res_ty) + ; return body + } tcCmd :: CmdEnv -> LHsExpr Name -> (CmdStack, TcTauType) -> TcM (LHsExpr TcId) -- The main recursive function @@ -117,6 +104,7 @@ tcCmd env (L loc expr) res_ty { expr' <- tc_cmd env expr res_ty ; return (L loc expr') } +tc_cmd :: CmdEnv -> HsExpr Name -> (CmdStack, TcTauType) -> TcM (HsExpr TcId) tc_cmd env (HsPar cmd) res_ty = do { cmd' <- tcCmd env cmd res_ty ; return (HsPar cmd') } @@ -128,12 +116,10 @@ tc_cmd env (HsLet binds (L body_loc 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) $ - addErrCtxt (caseScrutCtxt scrut) ( - tcInferRho scrut - ) `thenM` \ (scrut', scrut_ty) -> - tcMatchesCase match_ctxt scrut_ty matches res_ty `thenM` \ matches' -> - returnM (HsCase scrut' matches') + = addErrCtxt (cmdCtxt in_cmd) $ do + (scrut', scrut_ty) <- tcInferRho scrut + matches' <- tcMatchesCase match_ctxt scrut_ty matches res_ty + return (HsCase scrut' matches') where match_ctxt = MC { mc_what = CaseAlt, mc_body = mc_body } @@ -174,7 +160,6 @@ tc_cmd env cmd@(HsArrApp fun arg _ ho_app lr) (cmd_stk, res_ty) tc_cmd env cmd@(HsApp fun arg) (cmd_stk, res_ty) = addErrCtxt (cmdCtxt cmd) $ --- gaw 2004 FIX? do { arg_ty <- newFlexiTyVarTy openTypeKind ; fun' <- tcCmd env fun (arg_ty:cmd_stk, res_ty) @@ -186,9 +171,9 @@ tc_cmd env cmd@(HsApp fun arg) (cmd_stk, res_ty) ------------------------------------------- -- Lambda -tc_cmd env cmd@(HsLam (MatchGroup [L mtch_loc (match@(Match pats maybe_rhs_sig grhss))] _)) +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) $ + = addErrCtxt (pprMatchInCtxt match_ctxt match) $ do { -- Check the cmd stack is big enough ; checkTc (lengthAtLeast cmd_stk n_pats) @@ -196,8 +181,8 @@ tc_cmd env cmd@(HsLam (MatchGroup [L mtch_loc (match@(Match pats maybe_rhs_sig g -- Check the patterns, and the GRHSs inside ; (pats', grhss') <- setSrcSpan mtch_loc $ - tcLamPats pats cmd_stk res_ty $ - tc_grhss grhss + tcPats LambdaExpr pats cmd_stk $ + tc_grhss grhss res_ty ; let match' = L mtch_loc (Match pats' Nothing grhss') ; return (HsLam (MatchGroup [match'] res_ty)) @@ -222,13 +207,12 @@ tc_cmd env cmd@(HsLam (MatchGroup [L mtch_loc (match@(Match pats maybe_rhs_sig g ------------------------------------------- -- Do notation -tc_cmd env cmd@(HsDo do_or_lc stmts body 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', body') <- tcStmts do_or_lc tc_stmt stmts (emptyRefinement, res_ty) $ + ; (stmts', body') <- tcStmts do_or_lc (tcMDoStmt tc_rhs) stmts res_ty $ tcGuardedCmd env body [] ; return (HsDo do_or_lc stmts' body' res_ty) } where - tc_stmt = tcMDoStmt tc_rhs tc_rhs rhs = do { ty <- newFlexiTyVarTy liftedTypeKind ; rhs' <- tcCmd env rhs ([], ty) ; return (rhs', ty) } @@ -247,7 +231,6 @@ tc_cmd env cmd@(HsDo do_or_lc stmts body ty) (cmd_stk, res_ty) 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..] - ; span <- getSrcSpanM ; [w_tv] <- tcInstSkolTyVars ArrowSkol [alphaTyVar] ; let w_ty = mkTyVarTy w_tv -- Just a convenient starting point @@ -260,22 +243,15 @@ tc_cmd env cmd@(HsArrForm expr fixity cmd_args) (cmd_stk, res_ty) e_res_ty -- Check expr - ; (expr', lie) <- escapeArrowScope (getLIE (tcMonoExpr expr e_ty)) - ; loc <- getInstLoc (SigOrigin ArrowSkol) - ; inst_binds <- tcSimplifyCheck loc [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) - ; checkSigTyVarsWrt (tyVarsOfTypes (res_ty:cmd_stk)) [w_tv] + ; (inst_binds, expr') <- checkConstraints ArrowSkol [w_tv] [] $ + escapeArrowScope (tcMonoExpr expr e_ty) -- 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 - ; returnM (HsArrForm (noLoc $ HsWrap (WpTyLam w_tv) - (unLoc $ mkHsDictLet inst_binds expr')) - fixity cmds') - } + ; let wrap = WpTyLam w_tv <.> mkWpLet inst_binds + ; return (HsArrForm (mkLHsWrap wrap expr') fixity cmds') } where -- Make the types -- b, ((e,s1) .. sm), s @@ -301,26 +277,25 @@ 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 (env { cmd_arr = b }) cmd arg_tys (emptyRefinement, s) } + ; tcCmdTop (env { cmd_arr = b }) cmd arg_tys s } unscramble :: TcType -> (TcType, [TcType]) -- unscramble ((w,s1) .. sn) = (w, [s1..sn]) - unscramble ty + unscramble ty = unscramble' ty [] + + unscramble' ty ss = case tcSplitTyConApp_maybe ty of Just (tc, [t,s]) | tc == pairTyCon - -> let - (w,ss) = unscramble t - in (w, s:ss) - - other -> (ty, []) + -> unscramble' t (s:ss) + _ -> (ty, ss) ----------------------------------------------------------------- -- Base case for illegal commands -- This is where expressions that aren't commands get rejected -tc_cmd env cmd _ - = failWithTc (vcat [ptext SLIT("The expression"), nest 2 (ppr cmd), - ptext SLIT("was found where an arrow command was expected")]) +tc_cmd _ cmd _ + = failWithTc (vcat [ptext (sLit "The expression"), nest 2 (ppr cmd), + ptext (sLit "was found where an arrow command was expected")]) \end{code} @@ -332,6 +307,7 @@ tc_cmd env cmd _ \begin{code} +mkPairTy :: Type -> Type -> Type mkPairTy t1 t2 = mkTyConApp pairTyCon [t1,t2] arrowTyConKind :: Kind -- *->*->* @@ -346,20 +322,21 @@ arrowTyConKind = mkArrowKinds [liftedTypeKind, liftedTypeKind] liftedTypeKind %************************************************************************ \begin{code} -cmdCtxt cmd = ptext SLIT("In the command:") <+> ppr cmd - -caseScrutCtxt cmd - = hang (ptext SLIT("In the scrutinee of a case command:")) 4 (ppr cmd) +cmdCtxt :: HsExpr Name -> SDoc +cmdCtxt cmd = ptext (sLit "In the command:") <+> ppr cmd +nonEmptyCmdStkErr :: HsExpr Name -> SDoc nonEmptyCmdStkErr cmd - = hang (ptext SLIT("Non-empty command stack at command:")) - 4 (ppr cmd) + = hang (ptext (sLit "Non-empty command stack at command:")) + 2 (ppr cmd) +kappaUnderflow :: HsExpr Name -> SDoc kappaUnderflow cmd - = hang (ptext SLIT("Command stack underflow at command:")) - 4 (ppr cmd) + = hang (ptext (sLit "Command stack underflow at command:")) + 2 (ppr cmd) +badFormFun :: Int -> TcType -> SDoc badFormFun i tup_ty' - = hang (ptext SLIT("The type of the") <+> speakNth i <+> ptext SLIT("argument of a command form has the wrong shape")) - 4 (ptext SLIT("Argument type:") <+> ppr tup_ty') + = hang (ptext (sLit "The type of the") <+> speakNth i <+> ptext (sLit "argument of a command form has the wrong shape")) + 2 (ptext (sLit "Argument type:") <+> ppr tup_ty') \end{code}