View patterns, record wildcards, and record puns
[ghc-hetmet.git] / compiler / typecheck / TcMatches.lhs
index d9146d9..d11cb97 100644 (file)
@@ -1,9 +1,18 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-\section[TcMatches]{Typecheck some @Matches@}
+
+TcMatches: Typecheck some @Matches@
 
 \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 TcMatches ( tcMatchesFun, tcGRHSsPat, tcMatchesCase, tcMatchLambda,
                   matchCtxt, TcMatchCtxt(..), 
                   tcStmts, tcDoStmts, tcBody,
@@ -14,36 +23,24 @@ module TcMatches ( tcMatchesFun, tcGRHSsPat, tcMatchesCase, tcMatchLambda,
 
 import {-# SOURCE #-}  TcExpr( tcSyntaxOp, tcInferRho, tcMonoExpr, tcPolyExpr )
 
-import HsSyn           ( HsExpr(..), LHsExpr, MatchGroup(..),
-                         Match(..), LMatch, GRHSs(..), GRHS(..), 
-                         Stmt(..), LStmt, HsMatchContext(..),
-                         HsStmtContext(..), 
-                         pprMatch, isIrrefutableHsPat, mkHsWrap,
-                         mkLHsWrap, pprMatchContext, pprStmtContext,  
-                         noSyntaxExpr, matchGroupArity, pprMatches,
-                         HsWrapper )
-
+import HsSyn
 import TcRnMonad
-import TcGadt          ( Refinement, emptyRefinement, refineResType )
-import Inst            ( newMethodFromName )
-import TcEnv           ( TcId, tcLookupLocalIds, tcLookupId, tcExtendIdEnv )
-import TcPat           ( tcLamPats, tcLamPat )
-import TcMType         ( newFlexiTyVarTy, newFlexiTyVarTys ) 
-import TcType          ( TcType, TcRhoType, 
-                         BoxySigmaType, BoxyRhoType, 
-                         mkFunTys, mkFunTy, mkAppTy, mkTyConApp,
-                         liftedTypeKind )
-import TcBinds         ( tcLocalBinds )
-import TcUnify         ( boxySplitAppTy, boxySplitTyConApp, boxySplitListTy,
-                         subFunTys, tcSubExp, withBox )
-import TcSimplify      ( bindInstsOfLocalFuns )
-import Name            ( Name )
-import TysWiredIn      ( stringTy, boolTy, parrTyCon, listTyCon, mkListTy, mkPArrTy )
-import PrelNames       ( bindMName, returnMName, mfixName, thenMName, failMName )
-import Id              ( idType, mkLocalId )
-import TyCon           ( TyCon )
+import TcGadt
+import Inst
+import TcEnv
+import TcPat
+import TcMType
+import TcType
+import TcBinds
+import TcUnify
+import TcSimplify
+import Name
+import TysWiredIn
+import PrelNames
+import Id
+import TyCon
 import Outputable
-import SrcLoc          ( Located(..), getLoc )
+import SrcLoc
 \end{code}
 
 %************************************************************************
@@ -58,12 +55,12 @@ is used in error messages.  It checks that all the equations have the
 same number of arguments before using @tcMatches@ to do the work.
 
 \begin{code}
-tcMatchesFun :: Name
+tcMatchesFun :: Name -> Bool
             -> MatchGroup Name
             -> BoxyRhoType             -- Expected type of function
             -> TcM (HsWrapper, MatchGroup TcId)        -- Returns type of body
 
-tcMatchesFun fun_name matches exp_ty
+tcMatchesFun fun_name inf matches exp_ty
   = do {  -- Check that they all have the same no of arguments
           -- Location is in the monad, set the caller so that 
           -- any inter-equation error messages get some vaguely
@@ -86,7 +83,7 @@ tcMatchesFun fun_name matches exp_ty
     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, mc_body = tcBody }
+    match_ctxt = MC { mc_what = FunRhs fun_name inf, mc_body = tcBody }
 \end{code}
 
 @tcMatchesCase@ doesn't do the argument-count check because the
@@ -109,7 +106,7 @@ tcMatchLambda match res_ty
   where
     n_pats = matchGroupArity match
     doc = sep [ ptext SLIT("The lambda expression")
-                <+> quotes (pprSetDepth 1 $ pprMatches LambdaExpr match),
+                <+> quotes (pprSetDepth 1 $ pprMatches (LambdaExpr :: HsMatchContext Name) match),
                        -- The pprSetDepth makes the abstraction print briefly
                ptext SLIT("has") <+> speakNOf n_pats (ptext SLIT("argument"))]
     match_ctxt = MC { mc_what = LambdaExpr,
@@ -163,7 +160,7 @@ tcMatch ctxt pat_tys rhs_ty match
   = wrapLocM (tc_match ctxt pat_tys rhs_ty) match
   where
     tc_match ctxt pat_tys rhs_ty match@(Match pats maybe_rhs_sig grhss)
-      = addErrCtxt (matchCtxt (mc_what ctxt) match)    $       
+      = add_match_ctxt match $
         do { (pats', grhss') <- tcLamPats pats pat_tys rhs_ty $
                                tc_grhss ctxt maybe_rhs_sig grhss
           ; return (Match pats' Nothing grhss') }
@@ -177,6 +174,13 @@ tcMatch ctxt pat_tys rhs_ty match
                        <+> ppr res_sig)
           ; tcGRHSs ctxt grhss (co, 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"
+    add_match_ctxt match thing_inside
+       = case mc_what ctxt of
+           LambdaExpr -> thing_inside
+           m_ctxt     -> addErrCtxt (matchCtxt m_ctxt match) thing_inside
+
 -------------
 tcGRHSs :: TcMatchCtxt -> GRHSs Name -> (Refinement, BoxyRhoType) 
        -> TcM (GRHSs TcId)
@@ -218,29 +222,31 @@ tcDoStmts :: HsStmtContext Name
          -> BoxyRhoType
          -> TcM (HsExpr TcId)          -- Returns a HsDo
 tcDoStmts ListComp stmts body res_ty
-  = do { elt_ty <- boxySplitListTy res_ty
+  = do { (elt_ty, coi) <- boxySplitListTy res_ty
        ; (stmts', body') <- tcStmts ListComp (tcLcStmt listTyCon) stmts 
                                     (emptyRefinement,elt_ty) $
                             tcBody body
-       ; return (HsDo ListComp stmts' body' (mkListTy elt_ty)) }
+       ; return $ mkHsWrapCoI coi 
+                     (HsDo ListComp stmts' body' (mkListTy elt_ty)) }
 
 tcDoStmts PArrComp stmts body res_ty
-  = do { [elt_ty] <- boxySplitTyConApp parrTyCon res_ty
+  = do { (elt_ty, coi) <- boxySplitPArrTy res_ty
        ; (stmts', body') <- tcStmts PArrComp (tcLcStmt parrTyCon) stmts 
                                     (emptyRefinement, elt_ty) $
                             tcBody body
-       ; return (HsDo PArrComp stmts' body' (mkPArrTy elt_ty)) }
+       ; return $ mkHsWrapCoI coi 
+                     (HsDo PArrComp stmts' body' (mkPArrTy elt_ty)) }
 
 tcDoStmts DoExpr stmts body res_ty
-  = do { (m_ty, elt_ty) <- boxySplitAppTy res_ty
+  = do { ((m_ty, elt_ty), coi) <- boxySplitAppTy res_ty
        ; let res_ty' = mkAppTy m_ty elt_ty     -- The boxySplit consumes res_ty
        ; (stmts', body') <- tcStmts DoExpr (tcDoStmt m_ty) stmts 
                                     (emptyRefinement, res_ty') $
                             tcBody body
-       ; return (HsDo DoExpr stmts' body' res_ty') }
+       ; return $ mkHsWrapCoI coi (HsDo DoExpr stmts' body' res_ty') }
 
 tcDoStmts ctxt@(MDoExpr _) stmts body res_ty
-  = do { (m_ty, elt_ty) <- boxySplitAppTy res_ty
+  = do { ((m_ty, elt_ty), coi) <- 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)
@@ -251,7 +257,9 @@ tcDoStmts ctxt@(MDoExpr _) stmts body res_ty
 
        ; let names = [mfixName, bindMName, thenMName, returnMName, failMName]
        ; insts <- mapM (newMethodFromName DoOrigin m_ty) names
-       ; return (HsDo (MDoExpr (names `zip` insts)) stmts' body' res_ty') }
+       ; return $ 
+            mkHsWrapCoI coi 
+              (HsDo (MDoExpr (names `zip` insts)) stmts' body' res_ty') }
 
 tcDoStmts ctxt stmts body res_ty = pprPanic "tcDoStmts" (pprStmtContext ctxt)