Add rebindable syntax for if-then-else
[ghc-hetmet.git] / compiler / deSugar / Coverage.lhs
index f2ad77c..d894523 100644 (file)
@@ -7,43 +7,35 @@
 \begin{code}
 module Coverage (addCoverageTicksToBinds) where
 
-#include "HsVersions.h"
-
 import HsSyn
 import Module
 import Outputable
 import DynFlags
-import Monad           
+import Control.Monad
 import SrcLoc
 import ErrUtils
 import Name
 import Bag
-import Var
+import Id
 import VarSet
 import Data.List
 import FastString
 import HscTypes        
 import StaticFlags
-import UniqFM
-import Type
 import TyCon
-import FiniteMap
-import PackageConfig 
+import MonadUtils
+import Maybes
 
 import Data.Array
-import System.Time (ClockTime(..))
-import System.IO   (FilePath)
-#if __GLASGOW_HASKELL__ < 603
-import Compat.Directory ( createDirectoryIfMissing )
-#else
 import System.Directory ( createDirectoryIfMissing )
-#endif
 
 import Trace.Hpc.Mix
 import Trace.Hpc.Util
 
 import BreakArray 
 import Data.HashTable   ( hashString )
+import Data.Map (Map)
+import qualified Data.Map as Map
 \end{code}
 
 
@@ -58,29 +50,35 @@ addCoverageTicksToBinds
         :: DynFlags
         -> Module
         -> ModLocation          -- of the current module
-       -> [TyCon]              -- type constructor in this module
+        -> [TyCon]             -- type constructor in this module
         -> LHsBinds Id
         -> IO (LHsBinds Id, HpcInfo, ModBreaks)
 
-addCoverageTicksToBinds dflags mod mod_loc tyCons binds = do 
-
-  let orig_file = 
-             case ml_hs_file mod_loc of
-                   Just file -> file
-                   Nothing -> panic "can not find the original file during hpc trans"
+addCoverageTicksToBinds dflags mod mod_loc tyCons binds = 
+ case ml_hs_file mod_loc of
+ Nothing -> return (binds, emptyHpcInfo False, emptyModBreaks)
+ Just orig_file -> do
 
   if "boot" `isSuffixOf` orig_file then return (binds, emptyHpcInfo False, emptyModBreaks) else do
 
+  -- Now, we try look for a file generated from a .hsc file to a .hs file, by peeking ahead.
+
+  let top_pos = catMaybes $ foldrBag (\ (L pos _) rest -> srcSpanFileName_maybe pos : rest) [] binds
+  let orig_file2 = case top_pos of
+                    (file_name:_) 
+                      | ".hsc" `isSuffixOf` unpackFS file_name -> unpackFS file_name
+                    _ -> orig_file
+
   let mod_name = moduleNameString (moduleName mod)
 
   let (binds1,_,st)
                 = unTM (addTickLHsBinds binds) 
                   (TTE
-                      { fileName    = mkFastString orig_file
+                      { fileName    = mkFastString orig_file2
                      , declPath     = []
                       , inScope      = emptyVarSet
-                     , blackList    = listToFM [ (getSrcSpan (tyConName tyCon),()) 
-                                               | tyCon <- tyCons ]
+                     , blackList    = Map.fromList [ (getSrcSpan (tyConName tyCon),()) 
+                                                   | tyCon <- tyCons ]
                       })
                   (TT 
                      { tickBoxCount = 0
@@ -99,14 +97,14 @@ addCoverageTicksToBinds dflags mod mod_loc tyCons binds = do
 
      let tabStop = 1 -- <tab> counts as a normal char in GHC's location ranges.
      createDirectoryIfMissing True hpc_mod_dir
-     modTime <- getModificationTime orig_file
+     modTime <- getModificationTime orig_file2
      let entries' = [ (hpcPos, box) 
                     | (span,_,box) <- entries, hpcPos <- [mkHpcPos span] ]
      when (length entries' /= tickBoxCount st) $ do
        panic "the number of .mix entries are inconsistent"
-     let hashNo = mixHash orig_file modTime tabStop entries'
+     let hashNo = mixHash orig_file2 modTime tabStop entries'
      mixCreate hpc_mod_dir mod_name 
-              $ Mix orig_file modTime (toHash hashNo) tabStop entries'
+              $ Mix orig_file2 modTime (toHash hashNo) tabStop entries'
      return $ hashNo 
    else do
      return $ 0
@@ -141,14 +139,14 @@ addTickLHsBinds :: LHsBinds Id -> TM (LHsBinds Id)
 addTickLHsBinds binds = mapBagM addTickLHsBind binds
 
 addTickLHsBind :: LHsBind Id -> TM (LHsBind Id)
-addTickLHsBind (L pos t@(AbsBinds abs_tvs abs_dicts abs_exports abs_binds)) = do
-  abs_binds' <- addTickLHsBinds abs_binds
-  return $ L pos $ AbsBinds abs_tvs abs_dicts abs_exports abs_binds'
+addTickLHsBind (L pos bind@(AbsBinds { abs_binds = binds })) = do
+  binds' <- addTickLHsBinds binds
+  return $ L pos $ bind { abs_binds = binds' }
 addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id)  }))) = do 
   let name = getOccString id
   decl_path <- getPathEntry
 
-  (fvs, mg@(MatchGroup matches' ty)) <- 
+  (fvs, (MatchGroup matches' ty)) <- 
         getFreeVars $
         addPathEntry name $
         addTickMatchGroup (fun_matches funBind)
@@ -188,12 +186,8 @@ addTickLHsBind (L pos (pat@(PatBind { pat_rhs = rhs }))) = do
 -}                        
   return $ L pos $ pat { pat_rhs = rhs' }
 
-{- only internal stuff, not from source, uses VarBind, so we ignore it.
-addTickLHsBind (VarBind var_id var_rhs) = do
-  var_rhs' <- addTickLHsExpr var_rhs  
-  return $ VarBind var_id var_rhs'
--}
-addTickLHsBind other = return other
+-- Only internal stuff, not from source, uses VarBind, so we ignore it.
+addTickLHsBind var_bind@(L _ (VarBind {})) = return var_bind
 
 -- Add a tick to the expression no matter what it is.  There is one exception:
 -- for the debugger, if the expression is a 'let', then we don't want to add
@@ -242,7 +236,7 @@ isGoodBreakExpr (RecordCon {}) = True
 isGoodBreakExpr (RecordUpd {}) = True
 isGoodBreakExpr (ArithSeq {})  = True
 isGoodBreakExpr (PArrSeq {})   = True
-isGoodBreakExpr other          = False 
+isGoodBreakExpr _other         = False 
 
 addTickLHsExprOptAlt :: Bool -> LHsExpr Id -> TM (LHsExpr Id)
 addTickLHsExprOptAlt oneOfMany (L pos e0)
@@ -252,16 +246,16 @@ addTickLHsExprOptAlt oneOfMany (L pos e0)
         addTickHsExpr e0
 
 addBinTickLHsExpr :: (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
-addBinTickLHsExpr boxLabel (L pos e0) = do
-    e1 <- addTickHsExpr e0
-    allocBinTickBox boxLabel $ L pos e1
+addBinTickLHsExpr boxLabel (L pos e0) =
+    allocBinTickBox boxLabel pos $
+        addTickHsExpr e0
 
 addTickHsExpr :: HsExpr Id -> TM (HsExpr Id)
 addTickHsExpr e@(HsVar id) = do freeVar id; return e
 addTickHsExpr e@(HsIPVar _) = return e
 addTickHsExpr e@(HsOverLit _) = return e
 addTickHsExpr e@(HsLit _) = return e
-addTickHsExpr e@(HsLam matchgroup) =
+addTickHsExpr (HsLam matchgroup) =
         liftM HsLam (addTickMatchGroup matchgroup)
 addTickHsExpr (HsApp e1 e2) = 
        liftM2 HsApp (addTickLHsExprNever e1) (addTickLHsExpr e2)
@@ -284,17 +278,21 @@ addTickHsExpr (SectionR e1 e2) =
        liftM2 SectionR
                (addTickLHsExpr e1)
                (addTickLHsExpr e2)
+addTickHsExpr (ExplicitTuple es boxity) =
+        liftM2 ExplicitTuple
+                (mapM addTickTupArg es)
+                (return boxity)
 addTickHsExpr (HsCase e mgs) = 
        liftM2 HsCase
                (addTickLHsExpr e) 
                (addTickMatchGroup mgs)
-addTickHsExpr (HsIf     e1 e2 e3) = 
-       liftM3 HsIf
+addTickHsExpr (HsIf cnd e1 e2 e3) = 
+       liftM3 (HsIf cnd)
                (addBinTickLHsExpr (BinBox CondBinBox) e1)
                (addTickLHsExprOptAlt True e2)
                (addTickLHsExprOptAlt True e3)
 addTickHsExpr (HsLet binds e) =
-       bindLocals (map unLoc $ collectLocalBinders binds) $
+       bindLocals (collectLocalBinders binds) $
        liftM2 HsLet
                (addTickHsLocalBinds binds) -- to think about: !patterns.
                 (addTickLHsExprNeverOrAlways e)
@@ -307,17 +305,13 @@ addTickHsExpr (HsDo cxt stmts last_exp srcloc) = do
                    ListComp -> Just $ BinBox QualBinBox
                    _        -> Nothing
 addTickHsExpr (ExplicitList ty es) = 
-       liftM2 ExplicitList 
+       liftM2 ExplicitList
                (return ty)
                (mapM (addTickLHsExpr) es)
 addTickHsExpr (ExplicitPArr ty es) =
        liftM2 ExplicitPArr
                (return ty)
                (mapM (addTickLHsExpr) es)
-addTickHsExpr (ExplicitTuple es box) =
-       liftM2 ExplicitTuple
-               (mapM (addTickLHsExpr) es)
-               (return box)
 addTickHsExpr (RecordCon id ty rec_binds) = 
        liftM3 RecordCon
                (return id)
@@ -338,7 +332,7 @@ addTickHsExpr (ArithSeq      ty arith_seq) =
        liftM2 ArithSeq 
                (return ty)
                (addTickArithSeqInfo arith_seq)
-addTickHsExpr (HsTickPragma (file,(l1,c1),(l2,c2)) (L pos e0)) = do
+addTickHsExpr (HsTickPragma _ (L pos e0)) = do
     e2 <- allocTickBox (ExpBox False) pos $
                 addTickHsExpr e0
     return $ unLoc e2
@@ -378,16 +372,16 @@ addTickHsExpr (HsArrForm e fix cmdtop) =
               (return fix)
               (mapM (liftL (addTickHsCmdTop)) cmdtop)
 
-addTickHsExpr e@(HsType ty) = return e
+addTickHsExpr e@(HsType _) = return e
 
 -- Others dhould never happen in expression content.
-addTickHsExpr e@(ExprWithTySig {}) = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(EAsPat _ _)       = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(ELazyPat _)       = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(EWildPat)         = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(HsBinTick _ _ _)  = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(HsTick _ _ _)     = pprPanic "addTickHsExpr" (ppr e)
+addTickHsExpr e  = pprPanic "addTickHsExpr" (ppr e)
 
+addTickTupArg :: HsTupArg Id -> TM (HsTupArg Id)
+addTickTupArg (Present e)  = do { e' <- addTickLHsExpr e; return (Present e') }
+addTickTupArg (Missing ty) = return (Missing ty)
+
+addTickMatchGroup :: MatchGroup Id -> TM (MatchGroup Id)
 addTickMatchGroup (MatchGroup matches ty) = do
   let isOneOfMany = matchesOneOfMany matches
   matches' <- mapM (liftL (addTickMatch isOneOfMany)) matches
@@ -406,7 +400,7 @@ addTickGRHSs isOneOfMany (GRHSs guarded local_binds) = do
     guarded' <- mapM (liftL (addTickGRHS isOneOfMany)) guarded
     return $ GRHSs guarded' local_binds'
   where
-    binders = map unLoc (collectLocalBinders local_binds)
+    binders = collectLocalBinders local_binds
 
 addTickGRHS :: Bool -> GRHS Id -> TM (GRHS Id)
 addTickGRHS isOneOfMany (GRHS stmts expr) = do
@@ -428,10 +422,10 @@ addTickLStmts' isGuard lstmts res
         a <- res
         return (lstmts', a)
   where
-        binders = map unLoc (collectLStmtsBinders lstmts)
+        binders = collectLStmtsBinders lstmts
 
 addTickStmt :: (Maybe (Bool -> BoxLabel)) -> Stmt Id -> TM (Stmt Id)
-addTickStmt isGuard (BindStmt pat e bind fail) = do
+addTickStmt _isGuard (BindStmt pat e bind fail) = do
        liftM4 BindStmt
                (addTickLPat pat)
                (addTickLHsExprAlways e)
@@ -439,30 +433,56 @@ addTickStmt isGuard (BindStmt pat e bind fail) = do
                (addTickSyntaxExpr hpcSrcSpan fail)
 addTickStmt isGuard (ExprStmt e bind' ty) = do
        liftM3 ExprStmt
-               (addTick e)
+               (addTick isGuard e)
                (addTickSyntaxExpr hpcSrcSpan bind')
                (return ty)
-  where
-   addTick e | Just fn <- isGuard = addBinTickLHsExpr fn e
-             | otherwise          = addTickLHsExprAlways e
-
-addTickStmt isGuard (LetStmt binds) = do
+addTickStmt _isGuard (LetStmt binds) = do
        liftM LetStmt
                (addTickHsLocalBinds binds)
 addTickStmt isGuard (ParStmt pairs) = do
-       liftM ParStmt (mapM process pairs)
-  where
-       process (stmts,ids) = 
-               liftM2 (,) 
-                       (addTickLStmts isGuard stmts)
-                       (return ids)
-addTickStmt isGuard (RecStmt stmts ids1 ids2 tys dictbinds) = do
-       liftM5 RecStmt 
-               (addTickLStmts isGuard stmts)
-               (return ids1)
-               (return ids2)
-               (return tys)
-               (addTickDictBinds dictbinds)
+    liftM ParStmt 
+        (mapM (addTickStmtAndBinders isGuard) pairs)
+
+addTickStmt isGuard (TransformStmt stmts ids usingExpr maybeByExpr) = do
+    liftM4 TransformStmt 
+        (addTickLStmts isGuard stmts)
+        (return ids)
+        (addTickLHsExprAlways usingExpr)
+        (addTickMaybeByLHsExpr maybeByExpr)
+
+addTickStmt isGuard (GroupStmt stmts binderMap by using) = do
+    liftM4 GroupStmt 
+        (addTickLStmts isGuard stmts)
+        (return binderMap)
+        (fmapMaybeM  addTickLHsExprAlways by)
+       (fmapEitherM addTickLHsExprAlways (addTickSyntaxExpr hpcSrcSpan) using)
+
+addTickStmt isGuard stmt@(RecStmt {})
+  = do { stmts' <- addTickLStmts isGuard (recS_stmts stmt)
+       ; ret'   <- addTickSyntaxExpr hpcSrcSpan (recS_ret_fn stmt)
+       ; mfix'  <- addTickSyntaxExpr hpcSrcSpan (recS_mfix_fn stmt)
+       ; bind'  <- addTickSyntaxExpr hpcSrcSpan (recS_bind_fn stmt)
+       ; dicts' <- addTickEvBinds (recS_dicts stmt)
+       ; return (stmt { recS_stmts = stmts', recS_ret_fn = ret'
+                      , recS_mfix_fn = mfix', recS_bind_fn = bind'
+                      , recS_dicts = dicts' }) }
+
+addTick :: Maybe (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
+addTick isGuard e | Just fn <- isGuard = addBinTickLHsExpr fn e
+                  | otherwise          = addTickLHsExprAlways e
+
+addTickStmtAndBinders :: Maybe (Bool -> BoxLabel) -> ([LStmt Id], a) 
+                      -> TM ([LStmt Id], a)
+addTickStmtAndBinders isGuard (stmts, ids) = 
+    liftM2 (,) 
+        (addTickLStmts isGuard stmts)
+        (return ids)
+
+addTickMaybeByLHsExpr :: Maybe (LHsExpr Id) -> TM (Maybe (LHsExpr Id))
+addTickMaybeByLHsExpr maybeByExpr = 
+    case maybeByExpr of
+        Nothing -> return Nothing
+        Just byExpr -> addTickLHsExprAlways byExpr >>= (return . Just)
 
 addTickHsLocalBinds :: HsLocalBinds Id -> TM (HsLocalBinds Id)
 addTickHsLocalBinds (HsValBinds binds) = 
@@ -473,6 +493,7 @@ addTickHsLocalBinds (HsIPBinds binds)  =
                (addTickHsIPBinds binds)
 addTickHsLocalBinds (EmptyLocalBinds)  = return EmptyLocalBinds
 
+addTickHsValBinds :: HsValBindsLR Id a -> TM (HsValBindsLR Id b)
 addTickHsValBinds (ValBindsOut binds sigs) =
        liftM2 ValBindsOut
                (mapM (\ (rec,binds') -> 
@@ -481,11 +502,13 @@ addTickHsValBinds (ValBindsOut binds sigs) =
                                        (addTickLHsBinds binds'))
                        binds)
                (return sigs)
+addTickHsValBinds _ = panic "addTickHsValBinds"
 
+addTickHsIPBinds :: HsIPBinds Id -> TM (HsIPBinds Id)
 addTickHsIPBinds (IPBinds ipbinds dictbinds) =
        liftM2 IPBinds
                (mapM (liftL (addTickIPBind)) ipbinds)
-               (addTickDictBinds dictbinds)
+               (return dictbinds)
 
 addTickIPBind :: IPBind Id -> TM (IPBind Id)
 addTickIPBind (IPBind nm e) =
@@ -513,8 +536,8 @@ addTickHsCmdTop (HsCmdTop cmd tys ty syntaxtable) =
 addTickLHsCmd ::  LHsCmd Id -> TM (LHsCmd Id)
 addTickLHsCmd x = addTickLHsExpr x
 
-addTickDictBinds :: DictBinds Id -> TM (DictBinds Id)
-addTickDictBinds x = addTickLHsBinds x
+addTickEvBinds :: TcEvBinds -> TM TcEvBinds
+addTickEvBinds x = return x   -- No coverage testing for dictionary binding
 
 addTickHsRecordBinds :: HsRecordBinds Id -> TM (HsRecordBinds Id)
 addTickHsRecordBinds (HsRecFields fields dd) 
@@ -552,12 +575,13 @@ data TickTransState = TT { tickBoxCount:: Int
 data TickTransEnv = TTE { fileName      :: FastString
                        , declPath     :: [String]
                         , inScope      :: VarSet
-                       , blackList   :: FiniteMap SrcSpan ()
+                       , blackList   :: Map SrcSpan ()
                        }
 
 --     deriving Show
 
 type FreeVars = OccEnv Id
+noFVs :: FreeVars
 noFVs = emptyOccEnv
 
 -- Note [freevars]
@@ -577,7 +601,7 @@ data TM a = TM { unTM :: TickTransEnv -> TickTransState -> (a,FreeVars,TickTrans
         -- monad (FreeVars).
 
 instance Monad TM where
-  return a = TM $ \ env st -> (a,noFVs,st)
+  return a = TM $ \ _env st -> (a,noFVs,st)
   (TM m) >>= k = TM $ \ env st -> 
                                case m env st of
                                  (r1,fv1,st1) -> 
@@ -588,8 +612,8 @@ instance Monad TM where
 -- getState :: TM TickTransState
 -- getState = TM $ \ env st -> (st, noFVs, st)
 
-setState :: (TickTransState -> TickTransState) -> TM ()
-setState f = TM $ \ env st -> ((), noFVs, f st)
+-- setState :: (TickTransState -> TickTransState) -> TM ()
+-- setState f = TM $ \ env st -> ((), noFVs, f st)
 
 getEnv :: TM TickTransEnv
 getEnv = TM $ \ env st -> (env, noFVs, st)
@@ -621,7 +645,7 @@ getFileName = fileName `liftM` getEnv
 sameFileName :: SrcSpan -> TM a -> TM a -> TM a
 sameFileName pos out_of_scope in_scope = do
   file_name <- getFileName
-  case optSrcSpanFileName pos of 
+  case srcSpanFileName_maybe pos of 
     Just file_name2 
       | file_name == file_name2 -> in_scope
     _ -> out_of_scope
@@ -630,12 +654,12 @@ bindLocals :: [Id] -> TM a -> TM a
 bindLocals new_ids (TM m)
   = TM $ \ env st -> 
                  case m env{ inScope = inScope env `extendVarSetList` new_ids } st of
-                   (r, fv, st') -> (r, fv `delListFromUFM` occs, st')
+                   (r, fv, st') -> (r, fv `delListFromOccEnv` occs, st')
   where occs = [ nameOccName (idName id) | id <- new_ids ] 
 
 isBlackListed :: SrcSpan -> TM Bool
 isBlackListed pos = TM $ \ env st -> 
-             case lookupFM (blackList env) pos of
+             case Map.lookup pos (blackList env) of
                Nothing -> (False,noFVs,st)
                Just () -> (True,noFVs,st)
 
@@ -646,7 +670,7 @@ allocTickBox boxLabel pos m | isGoodSrcSpan' pos =
   sameFileName pos 
     (do e <- m; return (L pos e)) $ do
   (fvs, e) <- getFreeVars m
-  TM $ \ env st ->
+  TM $ \ _env st ->
     let c = tickBoxCount st
         ids = occEnvElts fvs
         mes = mixEntries st
@@ -656,14 +680,14 @@ allocTickBox boxLabel pos m | isGoodSrcSpan' pos =
     , fvs
     , st {tickBoxCount=c+1,mixEntries=me:mes}
     )
-allocTickBox boxLabel pos m = do e <- m; return (L pos e)
+allocTickBox _boxLabel pos m = do e <- m; return (L pos e)
 
 -- the tick application inherits the source position of its
 -- expression argument to support nested box allocations 
 allocATickBox :: BoxLabel -> SrcSpan -> FreeVars -> TM (Maybe (Int,[Id]))
 allocATickBox boxLabel pos fvs | isGoodSrcSpan' pos = 
   sameFileName pos 
-    (return Nothing) $ TM $ \ env st ->
+    (return Nothing) $ TM $ \ _env st ->
   let me = (pos, map (nameOccName.idName) ids, boxLabel)
       c = tickBoxCount st
       mes = mixEntries st
@@ -672,32 +696,32 @@ allocATickBox boxLabel pos fvs | isGoodSrcSpan' pos =
      , noFVs
      , st {tickBoxCount=c+1, mixEntries=me:mes}
      )
-allocATickBox boxLabel pos fvs = return Nothing
-
-allocBinTickBox :: (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
-allocBinTickBox boxLabel (L pos e) | isGoodSrcSpan' pos = TM $ \ env st ->
+allocATickBox _boxLabel _pos _fvs = return Nothing
+
+allocBinTickBox :: (Bool -> BoxLabel) -> SrcSpan -> TM (HsExpr Id)
+                -> TM (LHsExpr Id)
+allocBinTickBox boxLabel pos m
+ | not opt_Hpc = allocTickBox (ExpBox False) pos m
+ | isGoodSrcSpan' pos =
+ do
+ e <- m
+ TM $ \ _env st ->
   let meT = (pos,[],boxLabel True)
       meF = (pos,[],boxLabel False)
       meE = (pos,[],ExpBox False)
       c = tickBoxCount st
       mes = mixEntries st
   in 
-     if opt_Hpc 
-        then ( L pos $ HsTick c [] $ L pos $ HsBinTick (c+1) (c+2) (L pos e)
+             ( L pos $ HsTick c [] $ L pos $ HsBinTick (c+1) (c+2) (L pos e)
            -- notice that F and T are reversed,
            -- because we are building the list in
            -- reverse...
              , noFVs
              , st {tickBoxCount=c+3 , mixEntries=meF:meT:meE:mes}
              )
-        else
-             ( L pos $ HsTick c [] $ L pos e
-             , noFVs
-             , st {tickBoxCount=c+1,mixEntries=meE:mes}
-             )
-
-allocBinTickBox boxLabel e = return e
+allocBinTickBox _boxLabel pos m = do e <- m; return (L pos e)
 
+isGoodSrcSpan' :: SrcSpan -> Bool
 isGoodSrcSpan' pos
    | not (isGoodSrcSpan pos) = False
    | start == end            = False
@@ -714,14 +738,13 @@ mkHpcPos pos
    start = srcSpanStart pos
    end   = srcSpanEnd pos
    hpcPos = toHpcPos ( srcLocLine start
-                    , srcLocCol start + 1
+                    , srcLocCol start
                     , srcLocLine end
-                    , srcLocCol end
+                    , srcLocCol end - 1
                     )
 
-noHpcPos = toHpcPos (0,0,0,0)
-
-hpcSrcSpan = mkGeneralSrcSpan (FSLIT("Haskell Program Coverage internals"))
+hpcSrcSpan :: SrcSpan
+hpcSrcSpan = mkGeneralSrcSpan (fsLit "Haskell Program Coverage internals")
 \end{code}