View patterns, record wildcards, and record puns
[ghc-hetmet.git] / compiler / deSugar / DsUtils.lhs
index 455db04..9d787ad 100644 (file)
@@ -8,6 +8,13 @@ Utilities for desugaring
 This module exports some utility functions of no great interest.
 
 \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 DsUtils (
        EquationInfo(..), 
        firstPat, shiftEqns,
@@ -18,7 +25,7 @@ module DsUtils (
        cantFailMatchResult, alwaysFailMatchResult,
        extractMatchResult, combineMatchResults, 
        adjustMatchResult,  adjustMatchResultDs,
-       mkCoLetMatchResult, mkGuardedMatchResult, 
+       mkCoLetMatchResult, mkViewMatchResult, mkGuardedMatchResult, 
        matchCanFail, mkEvalMatchResult,
        mkCoPrimCaseMatchResult, mkCoAlgCaseMatchResult,
        wrapBind, wrapBinds,
@@ -69,6 +76,8 @@ import SrcLoc
 import Util
 import ListSetOps
 import FastString
+import StaticFlags
+
 import Data.Char
 
 infixl 4 `mkDsApp`, `mkDsApps`
@@ -240,7 +249,7 @@ worthy of a type synonym and a few handy functions.
 
 \begin{code}
 firstPat :: EquationInfo -> Pat Id
-firstPat eqn = head (eqn_pats eqn)
+firstPat eqn = ASSERT( notNull (eqn_pats eqn) ) head (eqn_pats eqn)
 
 shiftEqns :: [EquationInfo] -> [EquationInfo]
 -- Drop the first pattern in each equation
@@ -310,6 +319,12 @@ seqVar var body = Case (Var var) var (exprType body)
 mkCoLetMatchResult :: CoreBind -> MatchResult -> MatchResult
 mkCoLetMatchResult bind = adjustMatchResult (mkDsLet bind)
 
+-- (mkViewMatchResult var' viewExpr var mr) makes the expression
+-- let var' = viewExpr var in mr
+mkViewMatchResult :: Id -> CoreExpr -> Id -> MatchResult -> MatchResult
+mkViewMatchResult var' viewExpr var = 
+    adjustMatchResult (mkDsLet (NonRec var' (mkDsApp viewExpr (Var var))))
+
 mkEvalMatchResult :: Id -> Type -> MatchResult -> MatchResult
 mkEvalMatchResult var ty
   = adjustMatchResult (\e -> Case (Var var) var ty [(DEFAULT, [], e)]) 
@@ -355,8 +370,8 @@ mkCoAlgCaseMatchResult var ty match_alts
        --  the scrutinised Id to be sufficiently refined to have a TyCon in it]
 
        -- Stuff for newtype
-    (con1, arg_ids1, match_result1) = head match_alts
-    arg_id1    = head arg_ids1
+    (con1, arg_ids1, match_result1) = ASSERT( notNull match_alts ) head match_alts
+    arg_id1    = ASSERT( notNull arg_ids1 ) head arg_ids1
     var_ty      = idType var
     (tc, ty_args) = splitNewTyConApp var_ty
     newtype_rhs = unwrapNewTypeBody tc ty_args (Var var)
@@ -645,7 +660,7 @@ mkSelectorBinds pat val_expr
     is_simple_lpat p = is_simple_pat (unLoc p)
 
     is_simple_pat (TuplePat ps Boxed _)        = all is_triv_lpat ps
-    is_simple_pat (ConPatOut{ pat_args = ps }) = all is_triv_lpat (hsConArgs ps)
+    is_simple_pat (ConPatOut{ pat_args = ps }) = all is_triv_lpat (hsConPatArgs ps)
     is_simple_pat (VarPat _)                  = True
     is_simple_pat (ParPat p)                  = is_simple_lpat p
     is_simple_pat other                               = False
@@ -934,23 +949,29 @@ mkFailurePair expr
 \end{code}
 
 \begin{code}
-mkOptTickBox :: Maybe Int -> CoreExpr -> DsM CoreExpr
+mkOptTickBox :: Maybe (Int,[Id]) -> CoreExpr -> DsM CoreExpr
 mkOptTickBox Nothing e   = return e
-mkOptTickBox (Just ix) e = mkTickBox ix e
+mkOptTickBox (Just (ix,ids)) e = mkTickBox ix ids e
 
-mkTickBox :: Int -> CoreExpr -> DsM CoreExpr
-mkTickBox ix e = do
+mkTickBox :: Int -> [Id] -> CoreExpr -> DsM CoreExpr
+mkTickBox ix vars e = do
        uq <- newUnique         
        mod <- getModuleDs
-       let tick = mkTickBoxOpId uq mod ix
+       let tick | opt_Hpc   = mkTickBoxOpId uq mod ix
+                | otherwise = mkBreakPointOpId uq mod ix
        uq2 <- newUnique        
        let occName = mkVarOcc "tick"
-       let name = mkInternalName uq2 occName noSrcLoc   -- use mkSysLocal?
+       let name = mkInternalName uq2 occName noSrcSpan   -- use mkSysLocal?
        let var  = Id.mkLocalId name realWorldStatePrimTy
-       return $ Case (Var tick) 
-                    var
-                    ty
-                    [(DEFAULT,[],e)]
+       scrut <- 
+          if opt_Hpc 
+            then return (Var tick)
+            else do
+              let tickVar = Var tick
+              let tickType = mkFunTys (map idType vars) realWorldStatePrimTy 
+              let scrutApTy = App tickVar (Type tickType)
+              return (mkApps scrutApTy (map Var vars) :: Expr Id)
+       return $ Case scrut var ty [(DEFAULT,[],e)]
   where
      ty = exprType e
 
@@ -960,10 +981,10 @@ mkBinaryTickBox ixT ixF e = do
        uq <- newUnique         
        mod <- getModuleDs
        let bndr1 = mkSysLocal FSLIT("t1") uq boolTy 
-       falseBox <- mkTickBox ixF $ Var falseDataConId
-       trueBox  <- mkTickBox ixT $ Var trueDataConId
+       falseBox <- mkTickBox ixF [] $ Var falseDataConId
+       trueBox  <- mkTickBox ixT [] $ Var trueDataConId
        return $ Case e bndr1 boolTy
                        [ (DataAlt falseDataCon, [], falseBox)
                        , (DataAlt trueDataCon,  [], trueBox)
                        ]
-\end{code}
\ No newline at end of file
+\end{code}