Improve error reporting for non-rigid GADT matches
[ghc-hetmet.git] / compiler / hsSyn / HsExpr.lhs
index cef711f..66336b6 100644 (file)
@@ -2,10 +2,9 @@
 % (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-
-HsExpr: Abstract Haskell syntax: expressions
-
 \begin{code}
+
+-- | Abstract Haskell syntax for expressions.
 module HsExpr where
 
 #include "HsVersions.h"
@@ -15,7 +14,6 @@ import HsDecls
 import HsPat
 import HsLit
 import HsTypes
-import HsImpExp
 import HsBinds
 
 -- others:
@@ -36,14 +34,16 @@ import FastString
 %************************************************************************
 
 \begin{code}
+-- * Expressions proper
+
 type LHsExpr id = Located (HsExpr id)
 
 -------------------------
--- PostTcExpr is an evidence expression attached to the
--- syntax tree by the type checker (c.f. postTcType)
--- We use a PostTcTable where there are a bunch of pieces of
--- evidence, more than is convenient to keep individually
+-- | PostTcExpr is an evidence expression attached to the syntax tree by the
+-- type checker (c.f. postTcType).
 type PostTcExpr  = HsExpr Id
+-- | We use a PostTcTable where there are a bunch of pieces of evidence, more
+-- than is convenient to keep individually.
 type PostTcTable = [(Name, Id)]
 
 noPostTcExpr :: PostTcExpr
@@ -53,11 +53,12 @@ noPostTcTable :: PostTcTable
 noPostTcTable = []
 
 -------------------------
--- SyntaxExpr is like PostTcExpr, but it's filled in a little earlier,
+-- | SyntaxExpr is like 'PostTcExpr', but it's filled in a little earlier,
 -- by the renamer.  It's used for rebindable syntax.
--- E.g. (>>=) is filled in before the renamer by the appropriate Name
---      for (>>=), and then instantiated by the type checker with its
---      type args tec
+--
+-- E.g. @(>>=)@ is filled in before the renamer by the appropriate 'Name' for
+--      @(>>=)@, and then instantiated by the type checker with its type args
+--      tec
 
 type SyntaxExpr id = HsExpr id
 
@@ -67,29 +68,33 @@ noSyntaxExpr = HsLit (HsString (fsLit "noSyntaxExpr"))
 
 
 type SyntaxTable id = [(Name, SyntaxExpr id)]
--- *** Currently used only for CmdTop (sigh) ***
--- * Before the renamer, this list is noSyntaxTable
+-- ^ Currently used only for 'CmdTop' (sigh)
+--
+-- * Before the renamer, this list is 'noSyntaxTable'
 --
--- * After the renamer, it takes the form [(std_name, HsVar actual_name)]
+-- * After the renamer, it takes the form @[(std_name, HsVar actual_name)]@
 --   For example, for the 'return' op of a monad
---      normal case:            (GHC.Base.return, HsVar GHC.Base.return)
---      with rebindable syntax: (GHC.Base.return, return_22)
---              where return_22 is whatever "return" is in scope
 --
--- * After the type checker, it takes the form [(std_name, <expression>)]
---      where <expression> is the evidence for the method
+--    * normal case:            @(GHC.Base.return, HsVar GHC.Base.return)@
+--
+--    * with rebindable syntax: @(GHC.Base.return, return_22)@
+--              where @return_22@ is whatever @return@ is in scope
+--
+-- * After the type checker, it takes the form @[(std_name, <expression>)]@
+--      where @<expression>@ is the evidence for the method
 
 noSyntaxTable :: SyntaxTable id
 noSyntaxTable = []
 
 
 -------------------------
+-- | A Haskell expression.
 data HsExpr id
-  = HsVar     id                        -- variable
-  | HsIPVar   (IPName id)               -- implicit parameter
-  | HsOverLit (HsOverLit id)            -- Overloaded literals
+  = HsVar     id                        -- ^ variable
+  | HsIPVar   (IPName id)               -- ^ implicit parameter
+  | HsOverLit (HsOverLit id)            -- ^ Overloaded literals
 
-  | HsLit     HsLit                     -- Simple (non-overloaded) literals
+  | HsLit     HsLit                     -- ^ Simple (non-overloaded) literals
 
   | HsLam     (MatchGroup id)           -- Currently always a single match
 
@@ -159,8 +164,10 @@ data HsExpr id
   -- Record update
   | RecordUpd   (LHsExpr id)
                 (HsRecordBinds id)
+--             (HsMatchGroup Id)  -- Filled in by the type checker to be 
+--                                -- a match that does the job
                 [DataCon]          -- Filled in by the type checker to the
-                                   -- *non-empty* list of DataCons that have
+                                   -- _non-empty_ list of DataCons that have
                                    -- all the upd'd fields
                 [PostTcType]       -- Argument types of *input* record type
                 [PostTcType]       --              and  *output* record type
@@ -198,7 +205,7 @@ data HsExpr id
   | HsBracketOut (HsBracket Name)       -- Output of the type checker is
                                         -- the *original*
                  [PendingSplice]        -- renamed expression, plus
-                                        -- *typechecked* splices to be
+                                        -- _typechecked_ splices to be
                                         -- pasted back in by the desugarer
 
   | HsSpliceE (HsSplice id)
@@ -346,7 +353,7 @@ ppr_expr (OpApp e1 op _ e2)
       = hang (ppr op) 2 (sep [pp_e1, pp_e2])
 
     pp_infixly v
-      = sep [nest 2 pp_e1, pprInfix v, nest 2 pp_e2]
+      = sep [nest 2 pp_e1, pprHsInfix v, nest 2 pp_e2]
 
 ppr_expr (NegApp e _) = char '-' <+> pprDebugParendExpr e
 
@@ -359,7 +366,7 @@ ppr_expr (SectionL expr op)
 
     pp_prefixly = hang (hsep [text " \\ x_ ->", ppr op])
                        4 (hsep [pp_expr, ptext (sLit "x_ )")])
-    pp_infixly v = (sep [pp_expr, pprInfix v])
+    pp_infixly v = (sep [pp_expr, pprHsInfix v])
 
 ppr_expr (SectionR op expr)
   = case unLoc op of
@@ -371,7 +378,7 @@ ppr_expr (SectionR op expr)
     pp_prefixly = hang (hsep [text "( \\ x_ ->", ppr op, ptext (sLit "x_")])
                        4 ((<>) pp_expr rparen)
     pp_infixly v
-      = (sep [pprInfix v, pp_expr])
+      = (sep [pprHsInfix v, pp_expr])
 
 --avoid using PatternSignatures for stage1 code portability
 ppr_expr exprType@(HsLam matches)
@@ -379,8 +386,8 @@ ppr_expr exprType@(HsLam matches)
  where idType :: HsExpr id -> HsMatchContext id; idType = undefined
 
 ppr_expr exprType@(HsCase expr matches)
-  = sep [ sep [ptext (sLit "case"), nest 4 (ppr expr), ptext (sLit "of")],
-          nest 2 (pprMatches (CaseAlt `asTypeOf` idType exprType) matches) ]
+  = sep [ sep [ptext (sLit "case"), nest 4 (ppr expr), ptext (sLit "of {")],
+          nest 2 (pprMatches (CaseAlt `asTypeOf` idType exprType) matches <+> char '}') ]
  where idType :: HsExpr id -> HsMatchContext id; idType = undefined
 
 ppr_expr (HsIf e1 e2 e3)
@@ -441,10 +448,7 @@ ppr_expr (HsSpliceE s)       = pprSplice s
 ppr_expr (HsBracket b)       = pprHsBracket b
 ppr_expr (HsBracketOut e []) = ppr e
 ppr_expr (HsBracketOut e ps) = ppr e $$ ptext (sLit "pending") <+> ppr ps
-ppr_expr (HsQuasiQuoteE (HsQuasiQuote name quoter _ quote)) 
-    = char '$' <> brackets (ppr name) <>
-      ptext (sLit "[:") <> ppr quoter <> ptext (sLit "|") <>
-      ppr quote <> ptext (sLit "|]")
+ppr_expr (HsQuasiQuoteE qq)  = ppr qq
 
 ppr_expr (HsProc pat (L _ (HsCmdTop cmd _ _ _)))
   = hsep [ptext (sLit "proc"), ppr pat, ptext (sLit "->"), ppr cmd]
@@ -480,7 +484,7 @@ ppr_expr (HsArrApp arrow arg _ HsHigherOrderApp False)
   = hsep [ppr_lexpr arg, ptext (sLit ">>-"), ppr_lexpr arrow]
 
 ppr_expr (HsArrForm (L _ (HsVar v)) (Just _) [arg1, arg2])
-  = sep [pprCmdArg (unLoc arg1), hsep [pprInfix v, pprCmdArg (unLoc arg2)]]
+  = sep [pprCmdArg (unLoc arg1), hsep [pprHsInfix v, pprCmdArg (unLoc arg2)]]
 ppr_expr (HsArrForm op _ args)
   = hang (ptext (sLit "(|") <> ppr_lexpr op)
          4 (sep (map (pprCmdArg.unLoc) args) <> ptext (sLit "|)"))
@@ -491,11 +495,8 @@ pprCmdArg (HsCmdTop cmd@(L _ (HsArrForm _ Nothing [])) _ _ _)
 pprCmdArg (HsCmdTop cmd _ _ _)
   = parens (ppr_lexpr cmd)
 
--- Put a var in backquotes if it's not an operator already
-pprInfix :: Outputable name => name -> SDoc
-pprInfix v | isOperator ppr_v = ppr_v
-           | otherwise        = char '`' <> ppr_v <> char '`'
-    where ppr_v = ppr v
+instance OutputableBndr id => Outputable (HsCmdTop id) where
+    ppr = pprCmdArg
 
 -- add parallel array brackets around a document
 --
@@ -670,9 +671,12 @@ data Match id
                                 -- Nothing after typechecking
         (GRHSs id)
 
+isEmptyMatchGroup :: MatchGroup id -> Bool
+isEmptyMatchGroup (MatchGroup ms _) = null ms
+
 matchGroupArity :: MatchGroup id -> Arity
 matchGroupArity (MatchGroup [] _)
-  = panic "matchGroupArity"     -- MatchGroup is never empty
+  = panic "matchGroupArity"     -- Precondition: MatchGroup is non-empty
 matchGroupArity (MatchGroup (match:matches) _)
   = ASSERT( all ((== n_pats) . length . hsLMatchPats) matches )
     -- Assertion just checks that all the matches have the same number of pats
@@ -683,13 +687,16 @@ matchGroupArity (MatchGroup (match:matches) _)
 hsLMatchPats :: LMatch id -> [LPat id]
 hsLMatchPats (L _ (Match pats _ _)) = pats
 
--- GRHSs are used both for pattern bindings and for Matches
+-- | GRHSs are used both for pattern bindings and for Matches
 data GRHSs id
-  = GRHSs [LGRHS id]             -- Guarded RHSs
-          (HsLocalBinds id)      -- The where clause
+  = GRHSs {
+      grhssGRHSs :: [LGRHS id],  -- ^ Guarded RHSs
+      grhssLocalBinds :: (HsLocalBinds id) -- ^ The where clause
+    }
 
 type LGRHS id = Located (GRHS id)
 
+-- | Guarded Right Hand Side.
 data GRHS id = GRHS [LStmt id]   -- Guards
                     (LHsExpr id) -- Right hand side
 \end{code}
@@ -1013,10 +1020,10 @@ pp_dotdot = ptext (sLit " .. ")
 \begin{code}
 data HsMatchContext id  -- Context of a Match
   = FunRhs id Bool              -- Function binding for f; True <=> written infix
-  | CaseAlt                     -- Guard on a case alternative
-  | LambdaExpr                  -- Pattern of a lambda
-  | ProcExpr                    -- Pattern of a proc
-  | PatBindRhs                  -- Pattern binding
+  | CaseAlt                     -- Patterns and guards on a case alternative
+  | LambdaExpr                  -- Patterns of a lambda
+  | ProcExpr                    -- Patterns of a proc
+  | PatBindRhs                  -- Patterns in the *guards* of a pattern binding
   | RecUpd                      -- Record update [used only in DsExpr to
                                 --    tell matchWrapper what sort of
                                 --    runtime error message to generate]
@@ -1113,3 +1120,15 @@ matchContextErrString (StmtCtxt (MDoExpr _))     = "'mdo' expression"
 matchContextErrString (StmtCtxt ListComp)        = "list comprehension"
 matchContextErrString (StmtCtxt PArrComp)        = "array comprehension"
 \end{code}
+
+\begin{code}
+pprMatchInCtxt :: (OutputableBndr idL, OutputableBndr idR)
+              => HsMatchContext idL -> Match idR -> SDoc
+pprMatchInCtxt ctxt match  = hang (ptext (sLit "In") <+> pprMatchContext ctxt <> colon) 
+                            4 (pprMatch ctxt match)
+
+pprStmtInCtxt :: (OutputableBndr idL, OutputableBndr idR)
+              => HsStmtContext idL -> StmtLR idL idR -> SDoc
+pprStmtInCtxt ctxt stmt = hang (ptext (sLit "In a stmt of") <+> pprStmtContext ctxt <> colon)
+                         4 (ppr stmt)
+\end{code}