X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcMatches.lhs;h=0bbe1931bb391c8b7b2fed01337123fc32b99396;hp=e07e6dad767b024e7e5b3e57aece7687f8629b2e;hb=79011516105291b58324ce71a87f6bb26a131090;hpb=67cb409159fa9136dff942b8baaec25909416022 diff --git a/compiler/typecheck/TcMatches.lhs b/compiler/typecheck/TcMatches.lhs index e07e6da..0bbe193 100644 --- a/compiler/typecheck/TcMatches.lhs +++ b/compiler/typecheck/TcMatches.lhs @@ -19,13 +19,10 @@ module TcMatches ( tcMatchesFun, tcGRHSsPat, tcMatchesCase, tcMatchLambda, tcDoStmt, tcMDoStmt, tcGuardStmt ) where -#include "HsVersions.h" - import {-# SOURCE #-} TcExpr( tcSyntaxOp, tcInferRho, tcMonoExpr, tcPolyExpr ) import HsSyn import TcRnMonad -import TcGadt import Inst import TcEnv import TcPat @@ -43,8 +40,9 @@ import TysPrim import Outputable import Util import SrcLoc +import FastString -import Control.Monad( liftM ) +import Control.Monad \end{code} %************************************************************************ @@ -84,8 +82,8 @@ tcMatchesFun fun_name inf matches exp_ty tcMatches match_ctxt pat_tys rhs_ty matches } where - doc = ptext SLIT("The equation(s) for") <+> quotes (ppr fun_name) - <+> ptext SLIT("have") <+> speakNOf n_pats (ptext SLIT("argument")) + doc = ptext (sLit "The equation(s) for") <+> quotes (ppr fun_name) + <+> ptext (sLit "have") <+> speakNOf n_pats (ptext (sLit "argument")) n_pats = matchGroupArity matches match_ctxt = MC { mc_what = FunRhs fun_name inf, mc_body = tcBody } \end{code} @@ -109,10 +107,10 @@ tcMatchLambda match res_ty tcMatches match_ctxt pat_tys rhs_ty match where n_pats = matchGroupArity match - doc = sep [ ptext SLIT("The lambda expression") + doc = sep [ ptext (sLit "The lambda expression") <+> quotes (pprSetDepth 1 $ pprMatches (LambdaExpr :: HsMatchContext Name) match), -- The pprSetDepth makes the abstraction print briefly - ptext SLIT("has") <+> speakNOf n_pats (ptext SLIT("argument"))] + ptext (sLit "has") <+> speakNOf n_pats (ptext (sLit "argument"))] match_ctxt = MC { mc_what = LambdaExpr, mc_body = tcBody } \end{code} @@ -122,8 +120,7 @@ tcMatchLambda match res_ty \begin{code} tcGRHSsPat :: GRHSs Name -> BoxyRhoType -> TcM (GRHSs TcId) -- Used for pattern bindings -tcGRHSsPat grhss res_ty = tcGRHSs match_ctxt grhss (emptyRefinement, res_ty) - -- emptyRefinement: no refinement in a pattern binding +tcGRHSsPat grhss res_ty = tcGRHSs match_ctxt grhss res_ty where match_ctxt = MC { mc_what = PatBindRhs, mc_body = tcBody } @@ -145,8 +142,9 @@ tcMatches :: TcMatchCtxt data TcMatchCtxt -- c.f. TcStmtCtxt, also in this module = MC { mc_what :: HsMatchContext Name, -- What kind of thing this is - mc_body :: LHsExpr Name -- Type checker for a body of an alternative - -> (Refinement, BoxyRhoType) + mc_body :: LHsExpr Name -- Type checker for a body of + -- an alternative + -> BoxyRhoType -> TcM (LHsExpr TcId) } tcMatches ctxt pat_tys rhs_ty (MatchGroup matches _) @@ -173,10 +171,10 @@ tcMatch ctxt pat_tys rhs_ty match = tcGRHSs ctxt grhss rhs_ty -- No result signature -- Result type sigs are no longer supported - tc_grhss ctxt (Just res_sig) grhss (co, rhs_ty) - = do { addErr (ptext SLIT("Ignoring (deprecated) result type signature") + tc_grhss ctxt (Just res_sig) grhss rhs_ty + = do { addErr (ptext (sLit "Ignoring (deprecated) result type signature") <+> ppr res_sig) - ; tcGRHSs ctxt grhss (co, rhs_ty) } + ; tcGRHSs ctxt grhss rhs_ty } -- For (\x -> e), tcExpr has already said "In the expresssion \x->e" -- so we don't want to add "In the lambda abstraction \x->e" @@ -186,7 +184,7 @@ tcMatch ctxt pat_tys rhs_ty match m_ctxt -> addErrCtxt (matchCtxt m_ctxt match) thing_inside ------------- -tcGRHSs :: TcMatchCtxt -> GRHSs Name -> (Refinement, BoxyRhoType) +tcGRHSs :: TcMatchCtxt -> GRHSs Name -> BoxyRhoType -> TcM (GRHSs TcId) -- Notice that we pass in the full res_ty, so that we get @@ -197,12 +195,12 @@ tcGRHSs :: TcMatchCtxt -> GRHSs Name -> (Refinement, BoxyRhoType) tcGRHSs ctxt (GRHSs grhss binds) res_ty = do { (binds', grhss') <- tcLocalBinds binds $ - mappM (wrapLocM (tcGRHS ctxt res_ty)) grhss + mapM (wrapLocM (tcGRHS ctxt res_ty)) grhss - ; returnM (GRHSs grhss' binds') } + ; return (GRHSs grhss' binds') } ------------- -tcGRHS :: TcMatchCtxt -> (Refinement, BoxyRhoType) -> GRHS Name -> TcM (GRHS TcId) +tcGRHS :: TcMatchCtxt -> BoxyRhoType -> GRHS Name -> TcM (GRHS TcId) tcGRHS ctxt res_ty (GRHS guards rhs) = do { (guards', rhs') <- tcStmts stmt_ctxt tcGuardStmt guards res_ty $ @@ -228,7 +226,7 @@ tcDoStmts :: HsStmtContext Name tcDoStmts ListComp stmts body res_ty = do { (elt_ty, coi) <- boxySplitListTy res_ty ; (stmts', body') <- tcStmts ListComp (tcLcStmt listTyCon) stmts - (emptyRefinement,elt_ty) $ + elt_ty $ tcBody body ; return $ mkHsWrapCoI coi (HsDo ListComp stmts' body' (mkListTy elt_ty)) } @@ -236,14 +234,14 @@ tcDoStmts ListComp stmts body res_ty tcDoStmts PArrComp stmts body res_ty = do { (elt_ty, coi) <- boxySplitPArrTy res_ty ; (stmts', body') <- tcStmts PArrComp (tcLcStmt parrTyCon) stmts - (emptyRefinement, elt_ty) $ + elt_ty $ tcBody body ; return $ mkHsWrapCoI coi (HsDo PArrComp stmts' body' (mkPArrTy elt_ty)) } tcDoStmts DoExpr stmts body res_ty = do { (stmts', body') <- tcStmts DoExpr tcDoStmt stmts - (emptyRefinement, res_ty) $ + res_ty $ tcBody body ; return (HsDo DoExpr stmts' body' res_ty) } @@ -254,7 +252,7 @@ tcDoStmts ctxt@(MDoExpr _) stmts body res_ty tcMonoExpr rhs (mkAppTy m_ty pat_ty) ; (stmts', body') <- tcStmts ctxt (tcMDoStmt tc_rhs) stmts - (emptyRefinement, res_ty') $ + res_ty' $ tcBody body ; let names = [mfixName, bindMName, thenMName, returnMName, failMName] @@ -265,12 +263,12 @@ tcDoStmts ctxt@(MDoExpr _) stmts body res_ty tcDoStmts ctxt stmts body res_ty = pprPanic "tcDoStmts" (pprStmtContext ctxt) -tcBody :: LHsExpr Name -> (Refinement, BoxyRhoType) -> TcM (LHsExpr TcId) -tcBody body (reft, res_ty) - = do { traceTc (text "tcBody" <+> ppr res_ty <+> ppr reft) - ; let (co, res_ty') = refineResType reft res_ty - ; body' <- tcPolyExpr body res_ty' - ; return (mkLHsWrap co body') } +tcBody :: LHsExpr Name -> BoxyRhoType -> TcM (LHsExpr TcId) +tcBody body res_ty + = do { traceTc (text "tcBody" <+> ppr res_ty) + ; body' <- tcPolyExpr body res_ty + ; return body' + } \end{code} @@ -284,18 +282,15 @@ tcBody body (reft, res_ty) type TcStmtChecker = forall thing. HsStmtContext Name -> Stmt Name - -> (Refinement, BoxyRhoType) -- Result type for comprehension - -> ((Refinement,BoxyRhoType) -> TcM thing) -- Checker for what follows the stmt + -> BoxyRhoType -- Result type for comprehension + -> (BoxyRhoType -> TcM thing) -- Checker for what follows the stmt -> TcM (Stmt TcId, thing) - -- The incoming BoxyRhoType may be refined by type refinements - -- before being passed to the thing_inside - tcStmts :: HsStmtContext Name -> TcStmtChecker -- NB: higher-rank type -> [LStmt Name] - -> (Refinement, BoxyRhoType) - -> ((Refinement, BoxyRhoType) -> TcM thing) + -> BoxyRhoType + -> (BoxyRhoType -> TcM thing) -> TcM ([LStmt TcId], thing) -- Note the higher-rank type. stmt_chk is applied at different @@ -384,7 +379,7 @@ tcLcStmt m_tc ctxt (ParStmt bndr_stmts_s) elt_ty thing_inside ; return (ParStmt pairs', thing) } where -- loop :: [([LStmt Name], [Name])] -> TcM ([([LStmt TcId], [TcId])], thing) - loop [] = do { thing <- thing_inside elt_ty -- No refinement from pattern + loop [] = do { thing <- thing_inside elt_ty ; return ([], thing) } -- matching in the branches loop ((stmts, names) : pairs) @@ -467,42 +462,54 @@ tcLcStmt m_tc ctxt stmt elt_ty thing_inside tcDoStmt :: TcStmtChecker -tcDoStmt ctxt (BindStmt pat rhs bind_op fail_op) reft_res_ty@(_,res_ty) thing_inside +tcDoStmt ctxt (BindStmt pat rhs bind_op fail_op) res_ty thing_inside = do { (rhs', rhs_ty) <- tcInferRho rhs - -- We should use type *inference* for the RHS computations, becuase of GADTs. + -- We should use type *inference* for the RHS computations, + -- becuase of GADTs. -- do { pat <- rhs; } -- is rather like -- case rhs of { pat -> } - -- We do inference on rhs, so that information about its type can be refined - -- when type-checking the pattern. - - -- Deal with rebindable syntax; (>>=) :: rhs_ty -> (a -> res_ty) -> res_ty - ; (bind_op', pat_ty) <- + -- We do inference on rhs, so that information about its type + -- can be refined when type-checking the pattern. + + -- Deal with rebindable syntax: + -- (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty + -- This level of generality is needed for using do-notation + -- in full generality; see Trac #1537 + ; ((bind_op', new_res_ty), pat_ty) <- withBox liftedTypeKind $ \ pat_ty -> + withBox liftedTypeKind $ \ new_res_ty -> tcSyntaxOp DoOrigin bind_op - (mkFunTys [rhs_ty, mkFunTy pat_ty res_ty] res_ty) + (mkFunTys [rhs_ty, mkFunTy pat_ty new_res_ty] res_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) + else tcSyntaxOp DoOrigin fail_op (mkFunTy stringTy new_res_ty) - ; (pat', thing) <- tcLamPat pat pat_ty reft_res_ty thing_inside + ; (pat', thing) <- tcLamPat pat pat_ty new_res_ty thing_inside ; return (BindStmt pat' rhs' bind_op' fail_op', thing) } -tcDoStmt ctxt (ExprStmt rhs then_op _) reft_res_ty@(_,res_ty) thing_inside +tcDoStmt ctxt (ExprStmt rhs then_op _) res_ty thing_inside = do { (rhs', rhs_ty) <- tcInferRho rhs - -- Deal with rebindable syntax; (>>) :: rhs_ty -> res_ty -> res_ty - ; then_op' <- tcSyntaxOp DoOrigin then_op - (mkFunTys [rhs_ty, res_ty] res_ty) + -- Deal with rebindable syntax; (>>) :: rhs_ty -> new_res_ty -> res_ty + ; (then_op', new_res_ty) <- + withBox liftedTypeKind $ \ new_res_ty -> + tcSyntaxOp DoOrigin then_op + (mkFunTys [rhs_ty, new_res_ty] res_ty) - ; thing <- thing_inside reft_res_ty + ; thing <- thing_inside new_res_ty ; return (ExprStmt rhs' then_op' rhs_ty, thing) } +tcDoStmt ctxt (RecStmt {}) res_ty thing_inside + = failWithTc (ptext (sLit "Illegal 'rec' stmt in") <+> pprStmtContext ctxt) + -- This case can't be caught in the renamer + -- see RnExpr.checkRecStmt + tcDoStmt ctxt stmt res_ty thing_inside = pprPanic "tcDoStmt: unexpected Stmt" (ppr stmt) @@ -573,8 +580,8 @@ checkArgs :: Name -> MatchGroup Name -> TcM () checkArgs fun (MatchGroup (match1:matches) _) | null bad_matches = return () | otherwise - = failWithTc (vcat [ptext SLIT("Equations for") <+> quotes (ppr fun) <+> - ptext SLIT("have different numbers of arguments"), + = failWithTc (vcat [ptext (sLit "Equations for") <+> quotes (ppr fun) <+> + ptext (sLit "have different numbers of arguments"), nest 2 (ppr (getLoc match1)), nest 2 (ppr (getLoc (head bad_matches)))]) where @@ -587,9 +594,9 @@ checkArgs fun other = panic "TcPat.checkArgs" -- Matches always non-empty \end{code} \begin{code} -matchCtxt ctxt match = hang (ptext SLIT("In") <+> pprMatchContext ctxt <> colon) +matchCtxt ctxt match = hang (ptext (sLit "In") <+> pprMatchContext ctxt <> colon) 4 (pprMatch ctxt match) -stmtCtxt ctxt stmt = hang (ptext SLIT("In") <+> pprStmtContext ctxt <> colon) +stmtCtxt ctxt stmt = hang (ptext (sLit "In a stmt of") <+> pprStmtContext ctxt <> colon) 4 (ppr stmt) \end{code}