[project @ 2001-06-11 12:24:51 by simonpj]
authorsimonpj <unknown>
Mon, 11 Jun 2001 12:24:53 +0000 (12:24 +0000)
committersimonpj <unknown>
Mon, 11 Jun 2001 12:24:53 +0000 (12:24 +0000)
--------------------------------------
Tidy up and improve "pattern contexts"
--------------------------------------

In various places (renamer, typechecker, desugarer) we need to know
what the context of a pattern match is (case expression, function defn,
let binding, etc).  This commit tidies up the story quite a bit.  I
think it represents a net decrease in code, and certainly it improves the
error messages from:

f x x = 3

Prevsiously we got a message like "Conflicting bindings for x in a pattern match",
but not it says "..in a defn of function f".

WARNING: the tidy up had a more global effect than I originally expected,
so it's possible that some other error messages look a bit peculiar.  They
should be easy to fix, but tell us!

26 files changed:
ghc/compiler/NOTES
ghc/compiler/deSugar/DsBinds.lhs
ghc/compiler/deSugar/DsExpr.lhs
ghc/compiler/deSugar/DsGRHSs.lhs
ghc/compiler/deSugar/DsListComp.lhs
ghc/compiler/deSugar/DsMonad.lhs
ghc/compiler/deSugar/Match.hi-boot
ghc/compiler/deSugar/Match.hi-boot-5
ghc/compiler/deSugar/Match.lhs
ghc/compiler/hsSyn/HsBinds.lhs
ghc/compiler/hsSyn/HsExpr.hi-boot
ghc/compiler/hsSyn/HsExpr.hi-boot-5
ghc/compiler/hsSyn/HsExpr.lhs
ghc/compiler/rename/RnBinds.lhs
ghc/compiler/rename/RnEnv.lhs
ghc/compiler/rename/RnExpr.lhs
ghc/compiler/rename/RnHsSyn.lhs
ghc/compiler/rename/RnSource.lhs
ghc/compiler/typecheck/TcBinds.lhs
ghc/compiler/typecheck/TcExpr.lhs
ghc/compiler/typecheck/TcGenDeriv.lhs
ghc/compiler/typecheck/TcHsSyn.lhs
ghc/compiler/typecheck/TcMatches.hi-boot
ghc/compiler/typecheck/TcMatches.hi-boot-5
ghc/compiler/typecheck/TcMatches.lhs
ghc/compiler/typecheck/TcModule.lhs

index 67b4c62..14725dd 100644 (file)
@@ -54,3 +54,57 @@ completeLazyBind:    [given a simplified RHS]
 
   - add unfolding [this is the only place we add an unfolding]
     add arity
+
+
+
+Right hand sides and arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In many ways we want to treat 
+       (a) the right hand side of a let(rec), and 
+       (b) a function argument
+in the same way.  But not always!  In particular, we would
+like to leave these arguments exactly as they are, so they
+will match a RULE more easily.
+       
+       f (g x, h x)    
+       g (+ x)
+
+It's harder to make the rule match if we ANF-ise the constructor,
+or eta-expand the PAP:
+
+       f (let { a = g x; b = h x } in (a,b))
+       g (\y. + x y)
+
+On the other hand if we see the let-defns
+
+       p = (g x, h x)
+       q = + x
+
+then we *do* want to ANF-ise and eta-expand, so that p and q
+can be safely inlined.   
+
+Even floating lets out is a bit dubious.  For let RHS's we float lets
+out if that exposes a value, so that the value can be inlined more vigorously.
+For example
+
+       r = let x = e in (x,x)
+
+Here, if we float the let out we'll expose a nice constructor. We did experiments
+that showed this to be a generally good thing.  But it was a bad thing to float
+lets out unconditionally, because that meant they got allocated more often.
+
+For function arguments, there's less reason to expose a constructor (it won't
+get inlined).  Just possibly it might make a rule match, but I'm pretty skeptical.
+So for the moment we don't float lets out of function arguments either.
+
+
+Eta expansion
+~~~~~~~~~~~~~~
+For eta expansion, we want to catch things like
+
+       case e of (a,b) -> \x -> case a of (p,q) -> \y -> r
+
+If the \x was on the RHS of a let, we'd eta expand to bring the two
+lambdas together.  And in general that's a good thing to do.  Perhaps
+we should eta expand wherever we find a (value) lambda?  Then the eta
+expansion at a let RHS can concentrate solely on the PAP case.
index cc9c363..f045619 100644 (file)
@@ -78,11 +78,9 @@ dsMonoBinds _ (VarMonoBind var expr) rest
 
 dsMonoBinds auto_scc (FunMonoBind fun _ matches locn) rest
   = putSrcLocDs locn   $
-    matchWrapper (FunRhs (idName fun)) matches error_string    `thenDs` \ (args, body) ->
-    addAutoScc auto_scc (fun, mkLams args body)                        `thenDs` \ pair ->
+    matchWrapper (FunRhs fun) matches                  `thenDs` \ (args, body) ->
+    addAutoScc auto_scc (fun, mkLams args body)                `thenDs` \ pair ->
     returnDs (pair : rest)
-  where
-    error_string = "function " ++ showSDoc (ppr fun)
 
 dsMonoBinds auto_scc (PatMonoBind pat grhss locn) rest
   = putSrcLocDs locn $
index a7f8267..c435500 100644 (file)
@@ -11,11 +11,12 @@ module DsExpr ( dsExpr, dsLet ) where
 
 import HsSyn           ( failureFreePat,
                          HsExpr(..), OutPat(..), HsLit(..), ArithSeqInfo(..),
-                         Stmt(..), HsMatchContext(..), Match(..), HsBinds(..), MonoBinds(..), 
+                         Stmt(..), HsMatchContext(..), HsDoContext(..), 
+                         Match(..), HsBinds(..), MonoBinds(..), 
                          mkSimpleMatch, isDoExpr
                        )
 import TcHsSyn         ( TypecheckedHsExpr, TypecheckedHsBinds,
-                         TypecheckedStmt
+                         TypecheckedStmt, TypecheckedMatchContext
                        )
 import CoreSyn
 import CoreUtils       ( exprType, mkIfThenElse, bindNonRec )
@@ -122,14 +123,13 @@ dsExpr (HsLit lit)       = dsLit lit
 -- HsOverLit has been gotten rid of by the type checker
 
 dsExpr expr@(HsLam a_Match)
-  = matchWrapper LambdaExpr [a_Match] "lambda" `thenDs` \ (binders, matching_code) ->
+  = matchWrapper LambdaExpr [a_Match]  `thenDs` \ (binders, matching_code) ->
     returnDs (mkLams binders matching_code)
 
 dsExpr expr@(HsApp fun arg)      
   = dsExpr fun         `thenDs` \ core_fun ->
     dsExpr arg         `thenDs` \ core_arg ->
     returnDs (core_fun `App` core_arg)
-
 \end{code}
 
 Operator sections.  At first it looks as if we can convert
@@ -204,7 +204,7 @@ dsExpr (HsCase discrim matches src_loc)
  | all ubx_tuple_match matches
  =  putSrcLocDs src_loc $
     dsExpr discrim                     `thenDs` \ core_discrim ->
-    matchWrapper CaseAlt matches "case"        `thenDs` \ ([discrim_var], matching_code) ->
+    matchWrapper CaseAlt matches       `thenDs` \ ([discrim_var], matching_code) ->
     case matching_code of
        Case (Var x) bndr alts | x == discrim_var -> 
                returnDs (Case core_discrim bndr alts)
@@ -216,7 +216,7 @@ dsExpr (HsCase discrim matches src_loc)
 dsExpr (HsCase discrim matches src_loc)
   = putSrcLocDs src_loc $
     dsExpr discrim                     `thenDs` \ core_discrim ->
-    matchWrapper CaseAlt matches "case"        `thenDs` \ ([discrim_var], matching_code) ->
+    matchWrapper CaseAlt matches       `thenDs` \ ([discrim_var], matching_code) ->
     returnDs (bindNonRec discrim_var core_discrim matching_code)
 
 dsExpr (HsLet binds body)
@@ -430,8 +430,8 @@ dsExpr (RecordUpdOut record_expr record_out_ty dicts rbinds)
        -- and the right hand sides with applications of the wrapper Id
        -- so that everything works when we are doing fancy unboxing on the
        -- constructor aguments.
-    mapDs mk_alt cons_to_upd                   `thenDs` \ alts ->
-    matchWrapper RecUpd alts "record update"   `thenDs` \ ([discrim_var], matching_code) ->
+    mapDs mk_alt cons_to_upd           `thenDs` \ alts ->
+    matchWrapper RecUpd alts           `thenDs` \ ([discrim_var], matching_code) ->
 
     returnDs (bindNonRec discrim_var record_expr' matching_code)
 
@@ -490,7 +490,7 @@ dsExpr (ArithSeqIn _)           = panic "dsExpr:ArithSeqIn"
 Basically does the translation given in the Haskell~1.3 report:
 
 \begin{code}
-dsDo   :: HsMatchContext
+dsDo   :: HsDoContext
        -> [TypecheckedStmt]
        -> Id           -- id for: return m
        -> Id           -- id for: (>>=) m
@@ -501,6 +501,9 @@ dsDo        :: HsMatchContext
 dsDo do_or_lc stmts return_id then_id fail_id result_ty
   = let
        (_, b_ty) = splitAppTy result_ty        -- result_ty must be of the form (m b)
+       is_do     = case do_or_lc of
+                       DoExpr   -> True
+                       ListComp -> False
        
        -- For ExprStmt, see the comments near HsExpr.HsStmt about 
        -- exactly what ExprStmts mean!
@@ -508,12 +511,12 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
        -- In dsDo we can only see DoStmt and ListComp (no gaurds)
 
        go [ResultStmt expr locn]
-         | isDoExpr do_or_lc = do_expr expr locn
-         | otherwise         = do_expr expr locn       `thenDs` \ expr2 ->
-                               returnDs (mkApps (Var return_id) [Type b_ty, expr2])
+         | is_do     = do_expr expr locn
+         | otherwise = do_expr expr locn       `thenDs` \ expr2 ->
+                       returnDs (mkApps (Var return_id) [Type b_ty, expr2])
 
        go (ExprStmt expr locn : stmts)
-          | isDoExpr do_or_lc
+         | is_do       -- Do expression
          = do_expr expr locn           `thenDs` \ expr2 ->
            go stmts                    `thenDs` \ rest  ->
            let
@@ -556,8 +559,7 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
                      , mkSimpleMatch [WildPat a_ty] fail_expr (Just result_ty) locn
                      ]
            in
-           matchWrapper DoExpr the_matches match_msg
-                               `thenDs` \ (binders, matching_code) ->
+           matchWrapper (DoCtxt do_or_lc) the_matches  `thenDs` \ (binders, matching_code) ->
            returnDs (mkApps (Var then_id) [Type a_ty, Type b_ty, expr2,
                                            mkLams binders matching_code])
     in
@@ -565,10 +567,6 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
 
   where
     do_expr expr locn = putSrcLocDs locn (dsExpr expr)
-
-    match_msg = case do_or_lc of
-                       DoExpr   -> "`do' statement"
-                       ListComp -> "comprehension"
 \end{code}
 
 
index ab236f9..57ef74f 100644 (file)
@@ -12,7 +12,7 @@ import {-# SOURCE #-} DsExpr  ( dsExpr, dsLet )
 import {-# SOURCE #-} Match   ( matchSinglePat )
 
 import HsSyn           ( Stmt(..), HsExpr(..), GRHSs(..), GRHS(..), HsMatchContext(..) )
-import TcHsSyn         ( TypecheckedGRHSs, TypecheckedPat, TypecheckedStmt )
+import TcHsSyn         ( TypecheckedGRHSs, TypecheckedPat, TypecheckedStmt, TypecheckedMatchContext )
 import CoreSyn         ( CoreExpr )
 import Type            ( Type )
 
@@ -45,8 +45,8 @@ dsGuarded grhss
 In contrast, @dsGRHSs@ produces a @MatchResult@.
 
 \begin{code}
-dsGRHSs :: HsMatchContext -> [TypecheckedPat]  -- These are to build a MatchContext from
-       -> TypecheckedGRHSs                     -- Guarded RHSs
+dsGRHSs :: TypecheckedMatchContext -> [TypecheckedPat] -- These are to build a MatchContext from
+       -> TypecheckedGRHSs                             -- Guarded RHSs
        -> DsM (Type, MatchResult)
 
 dsGRHSs kind pats (GRHSs grhss binds (Just ty))
index ef622eb..929dd3e 100644 (file)
@@ -11,7 +11,7 @@ module DsListComp ( dsListComp ) where
 import {-# SOURCE #-} DsExpr ( dsExpr, dsLet )
 
 import BasicTypes      ( Boxity(..) )
-import HsSyn           ( OutPat(..), HsExpr(..), Stmt(..), HsMatchContext(..) )
+import HsSyn           ( OutPat(..), HsExpr(..), Stmt(..), HsMatchContext(..), HsDoContext(..) )
 import TcHsSyn         ( TypecheckedStmt, TypecheckedPat, TypecheckedHsExpr )
 import DsHsSyn         ( outPatType )
 import CoreSyn
@@ -193,7 +193,7 @@ deBindComp pat core_list1 quals core_list2
        letrec_body = App (Var h) core_list1
     in
     deListComp quals core_fail                 `thenDs` \ rest_expr ->
-    matchSimply (Var u2) ListComp pat
+    matchSimply (Var u2) (DoCtxt ListComp) pat
                rest_expr core_fail             `thenDs` \ core_match ->
     let
        rhs = Lam u1 $
@@ -306,7 +306,8 @@ dfListComp c_id n_id (BindStmt pat list1 locn : quals)
     dfListComp c_id b quals                    `thenDs` \ core_rest ->
 
     -- build the pattern match
-    matchSimply (Var x) ListComp pat core_rest (Var b) `thenDs` \ core_expr ->
+    matchSimply (Var x) (DoCtxt ListComp) 
+               pat core_rest (Var b)           `thenDs` \ core_expr ->
 
     -- now build the outermost foldr, and return
     dsLookupGlobalValue foldrName              `thenDs` \ foldr_id ->
index 3c783ed..6fc4aa7 100644 (file)
@@ -25,7 +25,7 @@ module DsMonad (
 
 #include "HsVersions.h"
 
-import HsSyn           ( HsMatchContext )
+import TcHsSyn         ( TypecheckedPat, TypecheckedMatchContext )
 import Bag             ( emptyBag, snocBag, Bag )
 import ErrUtils        ( WarnMsg )
 import Id              ( mkSysLocal, setIdUnique, Id )
@@ -33,7 +33,6 @@ import Module         ( Module )
 import Var             ( TyVar, setTyVarUnique )
 import Outputable
 import SrcLoc          ( noSrcLoc, SrcLoc )
-import TcHsSyn         ( TypecheckedPat )
 import Type             ( Type )
 import UniqSupply      ( initUs_, splitUniqSupply, uniqFromSupply, uniqsFromSupply,
                          UniqSM, UniqSupply )
@@ -218,7 +217,7 @@ dsLookupGlobalValue name dflags us genv loc mod warns
 
 \begin{code}
 data DsMatchContext
-  = DsMatchContext HsMatchContext [TypecheckedPat] SrcLoc
+  = DsMatchContext TypecheckedMatchContext [TypecheckedPat] SrcLoc
   | NoMatchContext
   deriving ()
 \end{code}
index 2db27a8..f069e91 100644 (file)
@@ -4,6 +4,6 @@ Match match matchExport matchSimply matchSinglePat;
 _declarations_
 1 match _:_ [Var.Id] -> [DsUtils.EquationInfo] -> DsMonad.DsM DsUtils.MatchResult ;;
 1 matchExport _:_ [Var.Id] -> [DsUtils.EquationInfo] -> DsMonad.DsM DsUtils.MatchResult ;;
-1 matchSimply _:_ CoreSyn.CoreExpr -> HsExpr.HsMatchContext -> TcHsSyn.TypecheckedPat -> CoreSyn.CoreExpr -> CoreSyn.CoreExpr -> DsMonad.DsM CoreSyn.CoreExpr ;;
+1 matchSimply _:_ CoreSyn.CoreExpr -> HsExpr.HsMatchContext Var.Id -> TcHsSyn.TypecheckedPat -> CoreSyn.CoreExpr -> CoreSyn.CoreExpr -> DsMonad.DsM CoreSyn.CoreExpr ;;
 1 matchSinglePat _:_ CoreSyn.CoreExpr -> DsMonad.DsMatchContext -> TcHsSyn.TypecheckedPat -> DsUtils.MatchResult -> DsMonad.DsM DsUtils.MatchResult ;;
 
index a0727f4..2e4d223 100644 (file)
@@ -2,5 +2,5 @@ __interface Match 1 0 where
 __export Match match matchExport matchSimply matchSinglePat;
 1 match :: [Var.Id] -> [DsUtils.EquationInfo] -> DsMonad.DsM DsUtils.MatchResult ;
 1 matchExport :: [Var.Id] -> [DsUtils.EquationInfo] -> DsMonad.DsM DsUtils.MatchResult ;
-1 matchSimply :: CoreSyn.CoreExpr -> HsExpr.HsMatchContext -> TcHsSyn.TypecheckedPat -> CoreSyn.CoreExpr -> CoreSyn.CoreExpr -> DsMonad.DsM CoreSyn.CoreExpr ;
+1 matchSimply :: CoreSyn.CoreExpr -> HsExpr.HsMatchContext Var.Id -> TcHsSyn.TypecheckedPat -> CoreSyn.CoreExpr -> CoreSyn.CoreExpr -> DsMonad.DsM CoreSyn.CoreExpr ;
 1 matchSinglePat :: CoreSyn.CoreExpr -> DsMonad.DsMatchContext -> TcHsSyn.TypecheckedPat -> DsUtils.MatchResult -> DsMonad.DsM DsUtils.MatchResult ;
index 0ca118b..92dae22 100644 (file)
@@ -10,7 +10,7 @@ module Match ( match, matchExport, matchWrapper, matchSimply, matchSinglePat ) w
 
 import CmdLineOpts     ( DynFlag(..), dopt )
 import HsSyn           
-import TcHsSyn         ( TypecheckedPat, TypecheckedMatch )
+import TcHsSyn         ( TypecheckedPat, TypecheckedMatch, TypecheckedMatchContext )
 import DsHsSyn         ( outPatType )
 import Check            ( check, ExhaustivePat )
 import CoreSyn
@@ -622,9 +622,8 @@ Call @match@ with all of this information!
 \end{enumerate}
 
 \begin{code}
-matchWrapper :: HsMatchContext         -- For shadowing warning messages
+matchWrapper :: TypecheckedMatchContext        -- For shadowing warning messages
             -> [TypecheckedMatch]      -- Matches being desugared
-            -> String                  -- Error message if the match fails
             -> DsM ([Id], CoreExpr)    -- Results
 \end{code}
 
@@ -651,11 +650,12 @@ one pattern, and match simply only accepts one pattern.
 JJQC 30-Nov-1997
 
 \begin{code}
-matchWrapper kind matches error_string
+matchWrapper ctxt matches
   = getDOptsDs                                 `thenDs` \ dflags ->
-    flattenMatches kind matches                        `thenDs` \ (result_ty, eqns_info) ->
+    flattenMatches ctxt matches                        `thenDs` \ (result_ty, eqns_info) ->
     let
        EqnInfo _ _ arg_pats _ : _ = eqns_info
+       error_string = matchContextErrString ctxt
     in
     mapDs selectMatchVar arg_pats              `thenDs` \ new_vars ->
     match_fun dflags new_vars eqns_info        `thenDs` \ match_result ->
@@ -664,7 +664,7 @@ matchWrapper kind matches error_string
     extractMatchResult match_result fail_expr          `thenDs` \ result_expr ->
     returnDs (new_vars, result_expr)
   where match_fun dflags
-           = case kind of 
+           = case ctxt of 
                 LambdaExpr | dopt Opt_WarnSimplePatterns dflags -> matchExport 
                            | otherwise                          -> match
                 _                                               -> matchExport
@@ -681,11 +681,11 @@ situation where we want to match a single expression against a single
 pattern. It returns an expression.
 
 \begin{code}
-matchSimply :: CoreExpr                -- Scrutinee
-           -> HsMatchContext   -- Match kind
-           -> TypecheckedPat   -- Pattern it should match
-           -> CoreExpr         -- Return this if it matches
-           -> CoreExpr         -- Return this if it doesn't
+matchSimply :: CoreExpr                        -- Scrutinee
+           -> TypecheckedMatchContext  -- Match kind
+           -> TypecheckedPat           -- Pattern it should match
+           -> CoreExpr                 -- Return this if it matches
+           -> CoreExpr                 -- Return this if it doesn't
            -> DsM CoreExpr
 
 matchSimply scrut kind pat result_expr fail_expr
@@ -726,7 +726,7 @@ matchSinglePat scrut ctx pat match_result
 This is actually local to @matchWrapper@.
 
 \begin{code}
-flattenMatches :: HsMatchContext
+flattenMatches :: TypecheckedMatchContext
               -> [TypecheckedMatch]
               -> DsM (Type, [EquationInfo])
 
index 9576c6d..4050a2e 100644 (file)
@@ -10,7 +10,9 @@ module HsBinds where
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-} HsExpr ( pprExpr, HsExpr, pprMatches, Match, pprGRHSs, GRHSs )
+import {-# SOURCE #-} HsExpr ( HsExpr, pprExpr,
+                              Match,  pprFunBind,
+                              GRHSs,  pprPatBind )
 
 -- friends:
 import HsTypes         ( HsType )
@@ -199,11 +201,8 @@ ppr_monobind EmptyMonoBinds = empty
 ppr_monobind (AndMonoBinds binds1 binds2)
       = ppr_monobind binds1 $$ ppr_monobind binds2
 
-ppr_monobind (PatMonoBind pat grhss locn)
-      = sep [ppr pat, nest 4 (pprGRHSs False grhss)]
-
-ppr_monobind (FunMonoBind fun inf matches locn)
-      = pprMatches (False, ppr fun) matches
+ppr_monobind (PatMonoBind pat grhss locn)      = pprPatBind pat grhss
+ppr_monobind (FunMonoBind fun inf matches locn) = pprFunBind fun matches
       -- ToDo: print infix if appropriate
 
 ppr_monobind (VarMonoBind name expr)
index a631f59..2341419 100644 (file)
@@ -1,12 +1,11 @@
 _interface_ HsExpr 1
 _exports_
-HsExpr HsExpr pprExpr Match GRHSs pprMatch pprMatches pprGRHSs ;
+HsExpr HsExpr pprExpr Match GRHSs pprFunBind pprPatBind ;
 _declarations_
 1 data HsExpr i p;
 1 pprExpr _:_ _forall_ [i p] {Outputable.Outputable i, Outputable.Outputable p} => HsExpr.HsExpr i p -> Outputable.SDoc ;;
 
 1 data Match a b ;
 1 data GRHSs a b ;
-1 pprGRHSs _:_ _forall_ [i p] {Outputable.Outputable i, Outputable.Outputable p} => PrelBase.Bool -> HsExpr.GRHSs i p -> Outputable.SDoc ;;
-1 pprMatch _:_ _forall_ [i p] {Outputable.Outputable i, Outputable.Outputable p} => (PrelBase.Bool, Outputable.SDoc) -> HsExpr.Match i p -> Outputable.SDoc ;;
-1 pprMatches _:_ _forall_ [i p] {Outputable.Outputable i, Outputable.Outputable p} => (PrelBase.Bool, Outputable.SDoc) -> [HsExpr.Match i p] -> Outputable.SDoc ;;
+1 pprPatBind _:_ _forall_ [i p] {Outputable.Outputable i, Outputable.Outputable p} => p -> HsExpr.GRHSs i p -> Outputable.SDoc ;;
+1 pprFunBind _:_ _forall_ [i p] {Outputable.Outputable i, Outputable.Outputable p} => i -> [HsExpr.Match i p] -> Outputable.SDoc ;;
index 5f17708..bf952e3 100644 (file)
@@ -1,13 +1,12 @@
 __interface HsExpr 1 0 where
-__export HsExpr HsExpr pprExpr Match GRHSs pprMatch pprMatches pprGRHSs ;
+__export HsExpr HsExpr pprExpr Match GRHSs pprPatBind pprFunBind ;
 
 1 data HsExpr i p ;
 1 pprExpr :: __forall [i p] {Outputable.Outputable i, Outputable.Outputable p} => HsExpr.HsExpr i p -> Outputable.SDoc ;
 
-
 1 data Match a b ;
 1 data GRHSs a b ;
-1 pprGRHSs :: __forall [i p] {Outputable.Outputable i, Outputable.Outputable p} => PrelBase.Bool -> HsExpr.GRHSs i p -> Outputable.SDoc ;
-1 pprMatch :: __forall [i p] {Outputable.Outputable i, Outputable.Outputable p} => (PrelBase.Bool, Outputable.SDoc) -> HsExpr.Match i p -> Outputable.SDoc ;
-1 pprMatches :: __forall [i p] {Outputable.Outputable i, Outputable.Outputable p} => (PrelBase.Bool, Outputable.SDoc) -> [HsExpr.Match i p] -> Outputable.SDoc ;
+
+1 pprPatBind :: __forall [i p] {Outputable.Outputable i, Outputable.Outputable p} => p -> HsExpr.GRHSs i p -> Outputable.SDoc ;
+1 pprFunBind :: __forall [i p] {Outputable.Outputable i, Outputable.Outputable p} => i -> [HsExpr.Match i p] -> Outputable.SDoc ;
 
index 153c7d7..60a1b83 100644 (file)
@@ -83,11 +83,11 @@ data HsExpr id pat
   | HsWith     (HsExpr id pat) -- implicit parameter binding
                [(id, HsExpr id pat)]
 
-  | HsDo       HsMatchContext
+  | HsDo       HsDoContext
                [Stmt id pat]   -- "do":one or more stmts
                SrcLoc
 
-  | HsDoOut    HsMatchContext
+  | HsDoOut    HsDoContext
                [Stmt id pat]   -- "do":one or more stmts
                id              -- id for return
                id              -- id for >>=
@@ -222,7 +222,7 @@ ppr_expr (HsLit lit)     = ppr lit
 ppr_expr (HsOverLit lit) = ppr lit
 
 ppr_expr (HsLam match)
-  = hsep [char '\\', nest 2 (pprMatch (True,empty) match)]
+  = hsep [char '\\', nest 2 (pprMatch LambdaExpr match)]
 
 ppr_expr expr@(HsApp e1 e2)
   = let (fun, args) = collect_args expr [] in
@@ -278,7 +278,7 @@ ppr_expr (SectionR op expr)
 
 ppr_expr (HsCase expr matches _)
   = sep [ sep [ptext SLIT("case"), nest 4 (pprExpr expr), ptext SLIT("of")],
-           nest 2 (pprMatches (True, empty) matches) ]
+           nest 2 (pprMatches CaseAlt matches) ]
 
 ppr_expr (HsIf e1 e2 e3 _)
   = sep [hsep [ptext SLIT("if"), nest 2 (pprExpr e1), ptext SLIT("then")],
@@ -479,46 +479,56 @@ We know the list must have at least one @Match@ in it.
 
 \begin{code}
 pprMatches :: (Outputable id, Outputable pat)
-          => (Bool, SDoc) -> [Match id pat] -> SDoc
-pprMatches print_info matches = vcat (map (pprMatch print_info) matches)
+          => HsMatchContext id -> [Match id pat] -> SDoc
+pprMatches ctxt matches = vcat (map (pprMatch ctxt) matches)
+
+-- Exported to HsBinds, which can't see the defn of HsMatchContext
+pprFunBind :: (Outputable id, Outputable pat)
+          => id -> [Match id pat] -> SDoc
+pprFunBind fun matches = pprMatches (FunRhs fun) matches
+
+-- Exported to HsBinds, which can't see the defn of HsMatchContext
+pprPatBind :: (Outputable id, Outputable pat)
+          => pat -> GRHSs id pat -> SDoc
+pprPatBind pat grhss = sep [ppr pat, nest 4 (pprGRHSs PatBindRhs grhss)]
 
 
 pprMatch :: (Outputable id, Outputable pat)
-          => (Bool, SDoc) -> Match id pat -> SDoc
-pprMatch print_info@(is_case, name) (Match _ pats maybe_ty grhss)
-  = maybe_name <+> sep [sep (map ppr pats), 
-                       ppr_maybe_ty,
-                       nest 2 (pprGRHSs is_case grhss)]
+          => HsMatchContext id -> Match id pat -> SDoc
+pprMatch ctxt (Match _ pats maybe_ty grhss)
+  = pp_name ctxt <+> sep [sep (map ppr pats), 
+                    ppr_maybe_ty,
+                    nest 2 (pprGRHSs ctxt grhss)]
   where
-    maybe_name | is_case   = empty
-              | otherwise = name
+    pp_name (FunRhs fun) = ppr fun
+    pp_name other       = empty
     ppr_maybe_ty = case maybe_ty of
                        Just ty -> dcolon <+> ppr ty
                        Nothing -> empty
 
 
 pprGRHSs :: (Outputable id, Outputable pat)
-        => Bool -> GRHSs id pat -> SDoc
-pprGRHSs is_case (GRHSs grhss binds maybe_ty)
-  = vcat (map (pprGRHS is_case) grhss)
+        => HsMatchContext id -> GRHSs id pat -> SDoc
+pprGRHSs ctxt (GRHSs grhss binds maybe_ty)
+  = vcat (map (pprGRHS ctxt) grhss)
     $$
     (if nullBinds binds then empty
      else text "where" $$ nest 4 (pprDeeper (ppr binds)))
 
 
 pprGRHS :: (Outputable id, Outputable pat)
-       => Bool -> GRHS id pat -> SDoc
+       => HsMatchContext id -> GRHS id pat -> SDoc
 
-pprGRHS is_case (GRHS [ResultStmt expr _] locn)
- =  pp_rhs is_case expr
+pprGRHS ctxt (GRHS [ResultStmt expr _] locn)
+ =  pp_rhs ctxt expr
 
-pprGRHS is_case (GRHS guarded locn)
- = sep [char '|' <+> interpp'SP guards, pp_rhs is_case expr]
+pprGRHS ctxt (GRHS guarded locn)
+ = sep [char '|' <+> interpp'SP guards, pp_rhs ctxt expr]
  where
     ResultStmt expr _ = last guarded   -- Last stmt should be a ResultStmt for guards
     guards           = init guarded
 
-pp_rhs is_case rhs = text (if is_case then "->" else "=") <+> pprDeeper (ppr rhs)
+pp_rhs ctxt rhs = ptext (matchSeparator ctxt) <+> pprDeeper (ppr rhs)
 \end{code}
 
 
@@ -596,7 +606,7 @@ pprStmt (ParStmt stmtss)
 pprStmt (ParStmtOut stmtss)
  = hsep (map (\stmts -> ptext SLIT("| ") <> ppr stmts) stmtss)
 
-pprDo :: (Outputable id, Outputable pat) => HsMatchContext -> [Stmt id pat] -> SDoc
+pprDo :: (Outputable id, Outputable pat) => HsDoContext -> [Stmt id pat] -> SDoc
 pprDo DoExpr stmts   = hang (ptext SLIT("do")) 2 (vcat (map ppr stmts))
 pprDo ListComp stmts = brackets $
                       hang (pprExpr expr <+> char '|')
@@ -644,30 +654,21 @@ pp_dotdot = ptext SLIT(" .. ")
 %************************************************************************
 
 \begin{code}
-data HsMatchContext    -- Context of a Match or Stmt
-  = ListComp           -- List comprehension
-  | DoExpr             -- Do Statment
-
-  | FunRhs Name                -- Function binding for f
+data HsMatchContext id -- Context of a Match or Stmt
+  = DoCtxt HsDoContext -- Do-stmt or list comprehension
+  | FunRhs id          -- Function binding for f
   | CaseAlt            -- Guard on a case alternative
   | LambdaExpr         -- Lambda
   | PatBindRhs         -- Pattern binding
   | RecUpd             -- Record update
   deriving ()
 
--- It's convenient to have FunRhs as a Name
--- throughout so that HsMatchContext doesn't
--- need to be parameterised.
--- In the RdrName world we never use the FunRhs variant.
+data HsDoContext = ListComp | DoExpr
 \end{code}
 
 \begin{code}
-isDoExpr DoExpr = True
-isDoExpr other  = False
-
-isDoOrListComp ListComp = True
-isDoOrListComp DoExpr   = True
-isDoOrListComp other    = False
+isDoExpr (DoCtxt DoExpr) = True
+isDoExpr other                  = False
 \end{code}
 
 \begin{code}
@@ -675,17 +676,25 @@ matchSeparator (FunRhs _)   = SLIT("=")
 matchSeparator CaseAlt      = SLIT("->") 
 matchSeparator LambdaExpr   = SLIT("->") 
 matchSeparator PatBindRhs   = SLIT("=") 
-matchSeparator DoExpr       = SLIT("<-")  
-matchSeparator ListComp     = SLIT("<-")  
+matchSeparator (DoCtxt _)   = SLIT("<-")  
 matchSeparator RecUpd       = panic "When is this used?"
 \end{code}
 
 \begin{code}
-pprMatchContext (FunRhs fun) = ptext SLIT("In the definition of") <+> quotes (ppr fun)
-pprMatchContext CaseAlt             = ptext SLIT("In a group of case alternatives beginning")
-pprMatchContext RecUpd      = ptext SLIT("In a record-update construct")
-pprMatchContext PatBindRhs   = ptext SLIT("In a pattern binding")
-pprMatchContext LambdaExpr   = ptext SLIT("In a lambda abstraction")
-pprMatchContext DoExpr       = ptext SLIT("In a 'do' expression pattern binding")
-pprMatchContext ListComp     = ptext SLIT("In a 'list comprehension' pattern binding")
+pprMatchContext (FunRhs fun)     = ptext SLIT("In the definition of") <+> quotes (ppr fun)
+pprMatchContext CaseAlt                  = ptext SLIT("In a case alternative")
+pprMatchContext RecUpd           = ptext SLIT("In a record-update construct")
+pprMatchContext PatBindRhs       = ptext SLIT("In a pattern binding")
+pprMatchContext LambdaExpr       = ptext SLIT("In a lambda abstraction")
+pprMatchContext (DoCtxt DoExpr)   = ptext SLIT("In a 'do' expression pattern binding")
+pprMatchContext (DoCtxt ListComp) = ptext SLIT("In a 'list comprehension' pattern binding")
+
+-- Used to generate the string for a *runtime* error message
+matchContextErrString (FunRhs fun)     = "function " ++ showSDoc (ppr fun)
+matchContextErrString CaseAlt          = "case"
+matchContextErrString PatBindRhs       = "pattern binding"
+matchContextErrString RecUpd           = "record update"
+matchContextErrString LambdaExpr       =  "lambda"
+matchContextErrString (DoCtxt DoExpr)   = "'do' expression"
+matchContextErrString (DoCtxt ListComp) = "list comprehension"
 \end{code}
index 33dacd7..aea97d3 100644 (file)
@@ -217,7 +217,7 @@ rnMonoBinds mbinds sigs     thing_inside -- Non-empty monobinds
   =    -- Extract all the binders in this group,
        -- and extend current scope, inventing new names for the new binders
        -- This also checks that the names form a set
-    bindLocatedLocalsRn (text "a binding group") 
+    bindLocatedLocalsRn (text "In a binding group") 
                        mbinders_w_srclocs      $ \ new_mbinders ->
     let
        binder_set = mkNameSet new_mbinders
@@ -327,7 +327,7 @@ flattenMonoBinds sigs (FunMonoBind name inf matches locn)
        names_bound_here = unitNameSet new_name
     in
     sigsForMe names_bound_here sigs                    `thenRn` \ sigs_for_me ->
-    mapFvRn rnMatch matches                            `thenRn` \ (new_matches, fvs) ->
+    mapFvRn (rnMatch (FunRhs name)) matches            `thenRn` \ (new_matches, fvs) ->
     mapRn_ (checkPrecMatch inf new_name) new_matches   `thenRn_`
     returnRn
       [(unitNameSet new_name,
@@ -387,12 +387,12 @@ rnMethodBinds gen_tyvars (FunMonoBind name inf matches locn)
        -- Gruesome; bring into scope the correct members of the generic type variables
        -- See comments in RnSource.rnSourceDecl(ClassDecl)
     rn_match match@(Match _ (TypePatIn ty : _) _ _)
-       = extendTyVarEnvFVRn gen_tvs (rnMatch match)
+       = extendTyVarEnvFVRn gen_tvs (rnMatch (FunRhs name) match)
        where
          tvs     = map rdrNameOcc (extractHsTyRdrNames ty)
          gen_tvs = [tv | tv <- gen_tyvars, nameOccName tv `elem` tvs] 
 
-    rn_match match = rnMatch match
+    rn_match match = rnMatch (FunRhs name) match
        
 
 -- Can't handle method pattern-bindings which bind multiple methods.
index 4d04154..e5a185d 100644 (file)
@@ -983,7 +983,7 @@ dupNamesErr descriptor ((name,loc) : dup_things)
   = pushSrcLocRn loc $
     addErrRn ((ptext SLIT("Conflicting definitions for") <+> quotes (ppr name))
              $$ 
-             (ptext SLIT("in") <+> descriptor))
+             descriptor)
 
 warnDeprec :: Name -> DeprecTxt -> RnM d ()
 warnDeprec name txt
@@ -992,3 +992,4 @@ warnDeprec name txt
                     quotes (ppr name) <+> text "is deprecated:", 
                     nest 4 (ppr txt) ])
 \end{code}
+
index 1b28b1a..c89a88b 100644 (file)
@@ -159,9 +159,9 @@ rnPat (TypePatIn name) =
 ************************************************************************
 
 \begin{code}
-rnMatch :: RdrNameMatch -> RnMS (RenamedMatch, FreeVars)
+rnMatch :: HsMatchContext RdrName -> RdrNameMatch -> RnMS (RenamedMatch, FreeVars)
 
-rnMatch match@(Match _ pats maybe_rhs_sig grhss)
+rnMatch ctxt match@(Match _ pats maybe_rhs_sig grhss)
   = pushSrcLocRn (getMatchLoc match)   $
 
        -- Bind pattern-bound type variables
@@ -170,8 +170,8 @@ rnMatch match@(Match _ pats maybe_rhs_sig grhss)
                                Nothing -> []
                                Just ty -> [ty]
        pat_sig_tys = collectSigTysFromPats pats
-       doc_sig     = text "a result type-signature"
-       doc_pat     = text "a pattern match"
+       doc_sig     = text "In a result type-signature"
+       doc_pat     = pprMatchContext ctxt
     in
     bindPatSigTyVars (rhs_sig_tys ++ pat_sig_tys)      $ \ sig_tyvars ->
 
@@ -212,7 +212,7 @@ bindPatSigTyVars tys thing_inside
     let
        tyvars_in_sigs = extractHsTysRdrTyVars tys
        forall_tyvars  = filter (not . (`elemFM` name_env)) tyvars_in_sigs
-       doc_sig        = text "a pattern type-signature"
+       doc_sig        = text "In a pattern type-signature"
     in
     bindNakedTyVarsFVRn doc_sig forall_tyvars thing_inside
 \end{code}
@@ -306,7 +306,7 @@ rnExpr (HsOverLit lit)
     returnRn (HsOverLit lit', fvs)
 
 rnExpr (HsLam match)
-  = rnMatch match      `thenRn` \ (match', fvMatch) ->
+  = rnMatch LambdaExpr match   `thenRn` \ (match', fvMatch) ->
     returnRn (HsLam match', fvMatch)
 
 rnExpr (HsApp fun arg)
@@ -370,8 +370,8 @@ rnExpr (HsSCC lbl expr)
 
 rnExpr (HsCase expr ms src_loc)
   = pushSrcLocRn src_loc $
-    rnExpr expr                        `thenRn` \ (new_expr, e_fvs) ->
-    mapFvRn rnMatch ms         `thenRn` \ (new_ms, ms_fvs) ->
+    rnExpr expr                                `thenRn` \ (new_expr, e_fvs) ->
+    mapFvRn (rnMatch CaseAlt) ms       `thenRn` \ (new_ms, ms_fvs) ->
     returnRn (HsCase new_expr new_ms src_loc, e_fvs `plusFV` ms_fvs)
 
 rnExpr (HsLet binds expr)
@@ -594,7 +594,7 @@ rnStmt (BindStmt pat expr src_loc) thing_inside
     returnRn ((new_binders ++ rest_binders, result),
              fv_expr `plusFV` fvs `plusFV` fv_pat)
   where
-    doc = text "a pattern in do binding" 
+    doc = text "In a pattern in 'do' binding" 
 
 rnStmt (ExprStmt expr src_loc) thing_inside
   = pushSrcLocRn src_loc $
index a1fbfeb..4789d89 100644 (file)
@@ -35,6 +35,7 @@ type RenamedHsBinds           = HsBinds               Name RenamedPat
 type RenamedHsExpr             = HsExpr                Name RenamedPat
 type RenamedHsModule           = HsModule              Name RenamedPat
 type RenamedInstDecl           = InstDecl              Name RenamedPat
+type RenamedMatchContext       = HsMatchContext        Name
 type RenamedMatch              = Match                 Name RenamedPat
 type RenamedMonoBinds          = MonoBinds             Name RenamedPat
 type RenamedPat                        = InPat                 Name
index 71fe8ff..6bb8bc0 100644 (file)
@@ -119,7 +119,7 @@ rnSourceDecl (DefD (DefaultDecl tys src_loc))
     mapFvRn (rnHsTypeFVs doc_str) tys          `thenRn` \ (tys', fvs) ->
     returnRn (DefD (DefaultDecl tys' src_loc), fvs)
   where
-    doc_str = text "a `default' declaration"
+    doc_str = text "In a `default' declaration"
 \end{code}
 
 
@@ -178,7 +178,7 @@ finishSourceInstDecl (InstDecl _       mbinds uprags _               _      )
        -- Used for both source decls only
   = ASSERT( not (maybeToBool maybe_dfun_name) )        -- Source decl!
     let
-       meth_doc    = text "the bindings in an instance declaration"
+       meth_doc    = text "In the bindings in an instance declaration"
        meth_names  = collectLocatedMonoBinders mbinds
        inst_tyvars = case inst_ty of
                        HsForAllTy (Just inst_tyvars) _ _ -> inst_tyvars
@@ -246,7 +246,7 @@ rnHsRuleDecl (HsRule rule_name tvs vars lhs rhs src_loc)
     returnRn (HsRule rule_name sig_tvs' vars' lhs' rhs' src_loc,
              fv_vars `plusFV` fv_lhs `plusFV` fv_rhs)
   where
-    doc = text "the transformation rule" <+> ptext rule_name
+    doc = text "In the transformation rule" <+> ptext rule_name
     sig_tvs = extractRuleBndrsTyVars vars
   
     get_var (RuleBndr v)      = v
@@ -285,7 +285,7 @@ rnTyClDecl (IfaceSig {tcdName = name, tcdType = ty, tcdIdInfo = id_infos, tcdLoc
     mapRn rnIdInfo id_infos            `thenRn` \ id_infos' -> 
     returnRn (IfaceSig {tcdName = name', tcdType = ty', tcdIdInfo = id_infos', tcdLoc = loc})
   where
-    doc_str = text "the interface signature for" <+> quotes (ppr name)
+    doc_str = text "In the interface signature for" <+> quotes (ppr name)
 
 rnTyClDecl (ForeignType {tcdName = name, tcdFoType = spec, tcdLoc = loc})
   = pushSrcLocRn loc                   $
@@ -300,13 +300,24 @@ rnTyClDecl (TyData {tcdND = new_or_data, tcdCtxt = context, tcdName = tycon,
     bindTyVarsRn data_doc tyvars               $ \ tyvars' ->
     rnContext data_doc context                         `thenRn` \ context' ->
     checkDupOrQualNames data_doc con_names     `thenRn_`
+
+       -- Check that there's at least one condecl,
+       -- or else we're reading an interface file, or -fglasgow-exts
+    (if null condecls then
+       doptRn Opt_GlasgowExts  `thenRn` \ glaExts ->
+       getModeRn               `thenRn` \ mode ->
+       checkRn (glaExts || isInterfaceMode mode)
+               (emptyConDeclsErr tycon)
+     else returnRn ()
+    )                                          `thenRn_` 
+
     mapRn rnConDecl condecls                   `thenRn` \ condecls' ->
     mapRn lookupSysBinder sys_names            `thenRn` \ sys_names' ->
     returnRn (TyData {tcdND = new_or_data, tcdCtxt = context', tcdName = tycon',
                      tcdTyVars = tyvars', tcdCons = condecls', tcdNCons = nconstrs,
                      tcdDerivs = Nothing, tcdLoc = src_loc, tcdSysNames = sys_names'})
   where
-    data_doc = text "the data type declaration for" <+> quotes (ppr tycon)
+    data_doc = text "In the data type declaration for" <+> quotes (ppr tycon)
     con_names = map conDeclName condecls
 
 rnTyClDecl (TySynonym {tcdName = name, tcdTyVars = tyvars, tcdSynRhs = ty, tcdLoc = src_loc})
@@ -317,7 +328,7 @@ rnTyClDecl (TySynonym {tcdName = name, tcdTyVars = tyvars, tcdSynRhs = ty, tcdLo
     rnHsType syn_doc (unquantify glaExts ty)   `thenRn` \ ty' ->
     returnRn (TySynonym {tcdName = name', tcdTyVars = tyvars', tcdSynRhs = ty', tcdLoc = src_loc})
   where
-    syn_doc = text "the declaration for type synonym" <+> quotes (ppr name)
+    syn_doc = text "In the declaration for type synonym" <+> quotes (ppr name)
 
        -- For H98 we do *not* universally quantify on the RHS of a synonym
        -- Silently discard context... but the tyvars in the rest won't be in scope
@@ -370,8 +381,8 @@ rnTyClDecl (ClassDecl {tcdCtxt = context, tcdName = cname,
                          tcdFDs = fds', tcdSigs = non_ops' ++ sigs', tcdMeths = Nothing, 
                          tcdSysNames = names', tcdLoc = src_loc})
   where
-    cls_doc  = text "the declaration for class"        <+> ppr cname
-    sig_doc  = text "the signatures for class"         <+> ppr cname
+    cls_doc  = text "In the declaration for class"     <+> ppr cname
+    sig_doc  = text "In the signatures for class"      <+> ppr cname
 
 rnClassOp clas clas_tyvars clas_fds sig@(ClassOpSig op dm_stuff ty locn)
   = pushSrcLocRn locn $
@@ -433,7 +444,7 @@ finishSourceTyClDecl (ClassDecl {tcdMeths = Just mbinds, tcdLoc = src_loc}) -- G
     rnMethodBinds gen_tyvars mbinds                    `thenRn` \ (mbinds', meth_fvs) ->
     returnRn (rn_cls_decl {tcdMeths = Just mbinds'}, meth_fvs)
   where
-    meth_doc = text "the default-methods for class"    <+> ppr (tcdName rn_cls_decl)
+    meth_doc = text "In the default-methods for class" <+> ppr (tcdName rn_cls_decl)
 
 finishSourceTyClDecl _ tycl_decl = returnRn (tycl_decl, emptyFVs)
        -- Not a class or data type declaration
@@ -473,7 +484,7 @@ rnConDecl (ConDecl name wkr tvs cxt details locn)
     rnConDetails doc locn details      `thenRn` \ new_details -> 
     returnRn (ConDecl new_name new_wkr new_tyvars new_context new_details locn)
   where
-    doc = text "the definition of data constructor" <+> quotes (ppr name)
+    doc = text "In the definition of data constructor" <+> quotes (ppr name)
 
 rnConDetails doc locn (VanillaCon tys)
   = mapRn (rnBangTy doc) tys   `thenRn` \ new_tys  ->
@@ -537,7 +548,7 @@ rnHsSigType :: SDoc -> RdrNameHsType -> RnMS RenamedHsType
        -- rnHsSigType is used for source-language type signatures,
        -- which use *implicit* universal quantification.
 rnHsSigType doc_str ty
-  = rnHsType (text "the type signature for" <+> doc_str) ty
+  = rnHsType (text "In the type signature for" <+> doc_str) ty
     
 ---------------------------------------
 rnHsType :: SDoc -> RdrNameHsType -> RnMS RenamedHsType
@@ -872,7 +883,7 @@ forAllWarn doc ty tyvar
                   sep [ptext SLIT("The universally quantified type variable") <+> quotes (ppr tyvar),
                   nest 4 (ptext SLIT("does not appear in the type") <+> quotes (ppr ty))]
                   $$
-                  (ptext SLIT("In") <+> doc)
+                  doc
                 )
           }
 
@@ -896,4 +907,7 @@ dupClassAssertWarn ctxt (assertion : dups)
 naughtyCCallContextErr (HsClassP clas _)
   = sep [ptext SLIT("Can't use class") <+> quotes (ppr clas), 
         ptext SLIT("in a context")]
+emptyConDeclsErr tycon
+  = sep [quotes (ppr tycon) <+> ptext SLIT("has no constructors"),
+        nest 4 (ptext SLIT("(-fglasgow-exts permits this)"))]
 \end{code}
index 44e9477..70ee5bd 100644 (file)
@@ -674,7 +674,7 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
           complete_it xve = tcAddSrcLoc locn                           $
                             tcAddErrCtxt (patMonoBindsCtxt bind)       $
                             tcExtendLocalValEnv xve                    $
-                            tcGRHSs grhss pat_ty PatBindRhs            `thenTc` \ (grhss', lie) ->
+                            tcGRHSs PatBindRhs grhss pat_ty            `thenTc` \ (grhss', lie) ->
                             returnTc (PatMonoBind pat' grhss' locn, lie)
        in
        returnTc (complete_it, lie_req, tvs, ids, lie_avail)
index 9be3c54..793abd1 100644 (file)
@@ -9,7 +9,7 @@ module TcExpr ( tcApp, tcExpr, tcMonoExpr, tcPolyExpr, tcId ) where
 #include "HsVersions.h"
 
 import HsSyn           ( HsExpr(..), HsLit(..), ArithSeqInfo(..), 
-                         HsMatchContext(..), mkMonoBind
+                         HsMatchContext(..), HsDoContext(..), mkMonoBind
                        )
 import RnHsSyn         ( RenamedHsExpr, RenamedRecordBinds )
 import TcHsSyn         ( TcExpr, TcRecordBinds, mkHsLet )
@@ -779,7 +779,7 @@ tcDoStmts do_or_lc stmts src_loc res_ty
                   returnNF_Tc (m_ty, (mkAppTy m_ty, elt_ty))
     )                                                  `thenNF_Tc` \ (tc_ty, m_ty) ->
 
-    tcStmts do_or_lc m_ty stmts                                `thenTc`   \ (stmts', stmts_lie) ->
+    tcStmts (DoCtxt do_or_lc) m_ty stmts               `thenTc`   \ (stmts', stmts_lie) ->
 
        -- Build the then and zero methods in case we need them
        -- It's important that "then" and "return" appear just once in the final LIE,
index 9939a58..1c840a1 100644 (file)
@@ -28,7 +28,7 @@ module TcGenDeriv (
 
 import HsSyn           ( InPat(..), HsExpr(..), MonoBinds(..),
                          Match(..), GRHSs(..), Stmt(..), HsLit(..),
-                         HsBinds(..), HsType(..), HsMatchContext(..),
+                         HsBinds(..), HsType(..), HsDoContext(..),
                          unguardedRHS, mkSimpleMatch, mkMonoBind, andMonoBindList
                        )
 import RdrHsSyn                ( mkHsOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat )
index 78a6676..ab8f3ad 100644 (file)
@@ -21,6 +21,7 @@ module TcHsSyn (
        TypecheckedMatch, TypecheckedHsModule,
        TypecheckedGRHSs, TypecheckedGRHS,
        TypecheckedRecordBinds, TypecheckedDictBinds,
+       TypecheckedMatchContext,
 
        mkHsTyApp, mkHsDictApp, mkHsConApp,
        mkHsTyLam, mkHsDictLam, mkHsLet,
@@ -91,6 +92,7 @@ type TypecheckedHsExpr                = HsExpr        Id TypecheckedPat
 type TypecheckedArithSeqInfo   = ArithSeqInfo  Id TypecheckedPat
 type TypecheckedStmt           = Stmt          Id TypecheckedPat
 type TypecheckedMatch          = Match         Id TypecheckedPat
+type TypecheckedMatchContext   = HsMatchContext Id
 type TypecheckedGRHSs          = GRHSs         Id TypecheckedPat
 type TypecheckedGRHS           = GRHS          Id TypecheckedPat
 type TypecheckedRecordBinds    = HsRecordBinds Id TypecheckedPat
index 593f18e..1ec6b18 100644 (file)
@@ -3,9 +3,9 @@ _exports_
 TcMatches tcGRHSs tcMatchesFun;
 _declarations_
 2 tcGRHSs _:_ _forall_ [s] => 
-             RnHsSyn.RenamedGRHSs
+             HsExpr.HsMatchContext Name.Name
+             -> RnHsSyn.RenamedGRHSs
              -> TcMonad.TcType
-             -> HsExpr.HsMatchContext
              -> TcMonad.TcM s (TcHsSyn.TcGRHSs, Inst.LIE) ;;
 3 tcMatchesFun _:_ _forall_ [s] => 
                [(Name.Name,Var.Id)]
index 044339d..d54594a 100644 (file)
@@ -1,9 +1,8 @@
 __interface TcMatches 1 0 where
 __export TcMatches tcGRHSs tcMatchesFun;
-1 tcGRHSs :: 
-             RnHsSyn.RenamedGRHSs
+1 tcGRHSs ::  HsExpr.HsMatchContext Name.Name
+             -> RnHsSyn.RenamedGRHSs
              -> TcMonad.TcType
-             -> HsExpr.HsMatchContext
              -> TcMonad.TcM (TcHsSyn.TcGRHSs, Inst.LIE) ;
 1 tcMatchesFun :: 
                [(Name.Name,Var.Id)]
index d6ce7a9..20c2a44 100644 (file)
@@ -13,13 +13,13 @@ module TcMatches ( tcMatchesFun, tcMatchesCase, tcMatchLambda,
 import {-# SOURCE #-}  TcExpr( tcExpr )
 
 import HsSyn           ( HsBinds(..), Match(..), GRHSs(..), GRHS(..),
-                         MonoBinds(..), Stmt(..), HsMatchContext(..),
+                         MonoBinds(..), Stmt(..), HsMatchContext(..), HsDoContext(..),
                          pprMatch, getMatchLoc, pprMatchContext, isDoExpr,
                          mkMonoBind, nullMonoBinds, collectSigTysFromPats
                        )
 import RnHsSyn         ( RenamedMatch, RenamedGRHSs, RenamedStmt, RenamedPat, RenamedHsType,
-                         extractHsTyVars )
-import TcHsSyn         ( TcMatch, TcGRHSs, TcStmt, TcDictBinds, TypecheckedPat )
+                         RenamedMatchContext, extractHsTyVars )
+import TcHsSyn         ( TcMatch, TcGRHSs, TcStmt, TcDictBinds, TypecheckedPat, TypecheckedMatchContext )
 
 import TcMonad
 import TcMonoType      ( kcHsSigTypes, tcScopedTyVars, checkSigTyVars, tcHsSigType, sigPatCtxt )
@@ -80,7 +80,7 @@ tcMatchesFun xve fun_name expected_ty matches@(first_match:_)
        -- may show up as something wrong with the (non-existent) type signature
 
        -- No need to zonk expected_ty, because unifyFunTy does that on the fly
-    tcMatches xve matches expected_ty (FunRhs fun_name)
+    tcMatches xve (FunRhs fun_name) matches expected_ty
 \end{code}
 
 @tcMatchesCase@ doesn't do the argument-count check because the
@@ -95,26 +95,26 @@ tcMatchesCase :: [RenamedMatch]             -- The case alternatives
 
 tcMatchesCase matches expr_ty
   = newTyVarTy openTypeKind                                    `thenNF_Tc` \ scrut_ty ->
-    tcMatches [] matches (mkFunTy scrut_ty expr_ty) CaseAlt    `thenTc` \ (matches', lie) ->
+    tcMatches [] CaseAlt matches (mkFunTy scrut_ty expr_ty)    `thenTc` \ (matches', lie) ->
     returnTc (scrut_ty, matches', lie)
 
 tcMatchLambda :: RenamedMatch -> TcType -> TcM (TcMatch, LIE)
-tcMatchLambda match res_ty = tcMatch [] match res_ty LambdaExpr
+tcMatchLambda match res_ty = tcMatch [] LambdaExpr match res_ty
 \end{code}
 
 
 \begin{code}
 tcMatches :: [(Name,Id)]
+         -> RenamedMatchContext 
          -> [RenamedMatch]
          -> TcType
-         -> HsMatchContext 
          -> TcM ([TcMatch], LIE)
 
-tcMatches xve matches expected_ty fun_or_case
+tcMatches xve fun_or_case matches expected_ty
   = mapAndUnzipTc tc_match matches     `thenTc` \ (matches, lies) ->
     returnTc (matches, plusLIEs lies)
   where
-    tc_match match = tcMatch xve match expected_ty fun_or_case
+    tc_match match = tcMatch xve fun_or_case match expected_ty
 \end{code}
 
 
@@ -126,13 +126,13 @@ tcMatches xve matches expected_ty fun_or_case
 
 \begin{code}
 tcMatch :: [(Name,Id)]
+       -> RenamedMatchContext
        -> RenamedMatch
        -> TcType               -- Expected result-type of the Match.
                                -- Early unification with this guy gives better error messages
-       -> HsMatchContext
        -> TcM (TcMatch, LIE)
 
-tcMatch xve1 match@(Match sig_tvs pats maybe_rhs_sig grhss) expected_ty ctxt
+tcMatch xve1 ctxt match@(Match sig_tvs pats maybe_rhs_sig grhss) expected_ty
   = tcAddSrcLoc (getMatchLoc match)            $       -- At one stage I removed this;
     tcAddErrCtxt (matchCtxt ctxt match)                $       -- I'm not sure why, so I put it back
     
@@ -150,7 +150,7 @@ tcMatch xve1 match@(Match sig_tvs pats maybe_rhs_sig grhss) expected_ty ctxt
 
                -- Typecheck the body
                tcExtendLocalValEnv xve1        $
-               tcGRHSs grhss rhs_ty ctxt       `thenTc` \ (grhss', lie) ->
+               tcGRHSs ctxt grhss rhs_ty       `thenTc` \ (grhss', lie) ->
                returnTc ((pats', grhss'), lie)
          )
 
@@ -172,11 +172,11 @@ glue_on _ EmptyMonoBinds grhss = grhss            -- The common case
 glue_on is_rec mbinds (GRHSs grhss binds ty)
   = GRHSs grhss (mkMonoBind mbinds [] is_rec `ThenBinds` binds) ty
 
-tcGRHSs :: RenamedGRHSs
-       -> TcType -> HsMatchContext
+tcGRHSs :: RenamedMatchContext -> RenamedGRHSs
+       -> TcType
        -> TcM (TcGRHSs, LIE)
 
-tcGRHSs (GRHSs grhss binds _) expected_ty ctxt
+tcGRHSs ctxt (GRHSs grhss binds _) expected_ty
   = tcBindsAndThen glue_on binds (tc_grhss grhss)
   where
     tc_grhss grhss
@@ -337,7 +337,7 @@ tcStmts do_or_lc m_ty stmts
 
 tcStmtsAndThen
        :: (TcStmt -> thing -> thing)   -- Combiner
-       -> HsMatchContext
+       -> RenamedMatchContext
         -> (TcType -> TcType, TcType)  -- m, the relationship type of pat and rhs in pat <- rhs
                                        -- elt_ty, where type of the comprehension is (m elt_ty)
         -> [RenamedStmt]
@@ -384,7 +384,7 @@ tcStmtAndThen combine do_or_lc m_ty (ParStmtOut bndr_stmts_s) thing_inside
 
     loop ((bndrs,stmts) : pairs)
       = tcStmtsAndThen 
-               combine_par ListComp m_ty stmts
+               combine_par (DoCtxt ListComp) m_ty stmts
                        -- Notice we pass on m_ty; the result type is used only
                        -- to get escaping type variables for checkExistentialPat
                (tcLookupLocalIds bndrs `thenNF_Tc` \ bndrs' ->
@@ -451,25 +451,12 @@ sameNoOfArgs matches = length (nub (map args_in_match matches)) == 1
 \end{code}
 
 \begin{code}
-matchCtxt CaseAlt match
-  = hang (ptext SLIT("In a case alternative:"))
-        4 (pprMatch (True,empty) {-is_case-} match)
-
-matchCtxt (FunRhs fun) match
-  = hang (hcat [ptext SLIT("In an equation for function "), quotes (ppr_fun), char ':'])
-        4 (pprMatch (False, ppr_fun) {-not case-} match)
-  where
-    ppr_fun = ppr fun
-
-matchCtxt LambdaExpr match
-  = hang (ptext SLIT("In the lambda expression"))
-        4 (pprMatch (True, empty) match)
+matchCtxt ctxt  match  = hang (pprMatchContext ctxt     <> colon) 4 (pprMatch ctxt match)
+stmtCtxt do_or_lc stmt = hang (pprMatchContext do_or_lc <> colon) 4 (ppr stmt)
 
 varyingArgsErr name matches
   = sep [ptext SLIT("Varying number of arguments for function"), quotes (ppr name)]
 
 lurkingRank2SigErr
   = ptext SLIT("Too few explicit arguments when defining a function with a rank-2 type")
-
-stmtCtxt do_or_lc stmt = hang (pprMatchContext do_or_lc <> colon) 4 (ppr stmt)
 \end{code}
index 8842be5..6b7d0c4 100644 (file)
@@ -13,7 +13,7 @@ module TcModule (
 
 import CmdLineOpts     ( DynFlag(..), DynFlags, dopt )
 import HsSyn           ( HsBinds(..), MonoBinds(..), HsDecl(..), HsExpr(..),
-                         Stmt(..), InPat(..), HsMatchContext(..), RuleDecl(..),
+                         Stmt(..), InPat(..), HsMatchContext(..), HsDoContext(..), RuleDecl(..),
                          isIfaceRuleDecl, nullBinds, andMonoBindList, mkSimpleMatch
                        )
 import PrelNames       ( SyntaxMap, mAIN_Name, mainName, ioTyConName, printName,
@@ -196,7 +196,7 @@ tc_stmts names stmts
     in
 
     traceTc (text "tcs 2") `thenNF_Tc_`
-    tcStmtsAndThen combine DoExpr io_ty stmts  (
+    tcStmtsAndThen combine (DoCtxt DoExpr) io_ty stmts (
        -- Look up the names right in the middle,
        -- where they will all be in scope
        mapNF_Tc tcLookupId names                       `thenNF_Tc` \ ids ->