Major patch to fix reporting of unused imports
[ghc-hetmet.git] / compiler / typecheck / TcRnMonad.lhs
index 396805f..dbe822a 100644 (file)
@@ -3,13 +3,6 @@
 %
 
 \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 TcRnMonad(
        module TcRnMonad,
        module TcRnTypes,
@@ -30,7 +23,6 @@ import TcType
 import InstEnv
 import FamInstEnv
 
-import Coercion
 import Var
 import Id
 import VarSet
@@ -44,15 +36,17 @@ import Bag
 import Outputable
 import UniqSupply
 import Unique
-import UniqFM
+import LazyUniqFM
 import DynFlags
 import StaticFlags
 import FastString
 import Panic
+import Util
+
 import System.IO
 import Data.IORef
-import Control.Exception
+import qualified Data.Set as Set
+import Control.Monad
 \end{code}
 
 
@@ -64,11 +58,6 @@ import Control.Exception
 %************************************************************************
 
 \begin{code}
-ioToTcRn :: IO r -> TcRn r
-ioToTcRn = ioToIOEnv
-\end{code}
-
-\begin{code}
 
 initTc :: HscEnv
        -> HscSource
@@ -82,11 +71,14 @@ initTc :: HscEnv
 initTc hsc_env hsc_src keep_rn_syntax mod do_this
  = do { errs_var     <- newIORef (emptyBag, emptyBag) ;
        tvs_var      <- newIORef emptyVarSet ;
-       type_env_var <- newIORef emptyNameEnv ;
        dfuns_var    <- newIORef emptyNameSet ;
        keep_var     <- newIORef emptyNameSet ;
+    used_rdrnames_var <- newIORef Set.empty ;
        th_var       <- newIORef False ;
        dfun_n_var   <- newIORef 1 ;
+       type_env_var <- case hsc_type_env_var hsc_env of {
+                           Just (_mod, te_var) -> return te_var ;
+                           Nothing             -> newIORef emptyNameEnv } ;
        let {
             maybe_rn_syntax empty_val
                | keep_rn_syntax = Just empty_val
@@ -97,7 +89,7 @@ initTc hsc_env hsc_src keep_rn_syntax mod do_this
                tcg_src       = hsc_src,
                tcg_rdr_env   = hsc_global_rdr_env hsc_env,
                tcg_fix_env   = emptyNameEnv,
-               tcg_field_env = emptyNameEnv,
+               tcg_field_env = RecFields emptyNameEnv emptyNameSet,
                tcg_default   = Nothing,
                tcg_type_env  = hsc_global_type_env hsc_env,
                tcg_type_env_var = type_env_var,
@@ -107,14 +99,16 @@ initTc hsc_env hsc_src keep_rn_syntax mod do_this
                tcg_th_used   = th_var,
                tcg_exports  = [],
                tcg_imports  = emptyImportAvails,
+        tcg_used_rdrnames = used_rdrnames_var,
                tcg_dus      = emptyDUs,
 
-                tcg_rn_imports = maybe_rn_syntax [],
+                tcg_rn_imports = [],
                 tcg_rn_exports = maybe_rn_syntax [],
                tcg_rn_decls   = maybe_rn_syntax emptyRnGroup,
 
                tcg_binds    = emptyLHsBinds,
-               tcg_deprecs  = NoDeprecs,
+               tcg_warns    = NoWarnings,
+               tcg_anns     = [],
                tcg_insts    = [],
                tcg_fam_insts= [],
                tcg_rules    = [],
@@ -127,14 +121,16 @@ initTc hsc_env hsc_src keep_rn_syntax mod do_this
             } ;
             lcl_env = TcLclEnv {
                tcl_errs       = errs_var,
-               tcl_loc        = mkGeneralSrcSpan FSLIT("Top level"),
+               tcl_loc        = mkGeneralSrcSpan (fsLit "Top level"),
                tcl_ctxt       = [],
                tcl_rdr        = emptyLocalRdrEnv,
                tcl_th_ctxt    = topStage,
                tcl_arrow_ctxt = NoArrowCtxt,
                tcl_env        = emptyNameEnv,
                tcl_tyvars     = tvs_var,
-               tcl_lie        = panic "initTc:LIE"     -- LIE only valid inside a getLIE
+               tcl_lie        = panic "initTc:LIE", -- only valid inside getLIE
+               tcl_tybinds    = panic "initTc:tybinds" 
+                                               -- only valid inside a getTyBinds
             } ;
        } ;
    
@@ -159,11 +155,10 @@ initTcPrintErrors -- Used from the interactive loop only
        :: HscEnv
        -> Module 
        -> TcM r
-       -> IO (Maybe r)
+       -> IO (Messages, Maybe r)
 initTcPrintErrors env mod todo = do
   (msgs, res) <- initTc env HsSrcFile False mod todo
-  printErrorsAndWarnings (hsc_dflags env) msgs
-  return res
+  return (msgs, res)
 \end{code}
 
 %************************************************************************
@@ -247,7 +242,8 @@ unsetOptM :: DynFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
 unsetOptM flag = updEnv (\ env@(Env { env_top = top }) ->
                         env { env_top = top { hsc_dflags = dopt_unset (hsc_dflags top) flag}} )
 
-ifOptM :: DynFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl ()    -- Do it flag is true
+-- | Do it flag is true
+ifOptM :: DynFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl ()
 ifOptM flag thing_inside = do { b <- doptM flag; 
                                if b then thing_inside else return () }
 
@@ -334,6 +330,10 @@ newSysLocalIds :: FastString -> [TcType] -> TcRnIf gbl lcl [TcId]
 newSysLocalIds fs tys
   = do { us <- newUniqueSupply
        ; return (zipWith (mkSysLocal fs) (uniqsFromSupply us) tys) }
+
+instance MonadUnique (IOEnv (Env gbl lcl)) where
+        getUniqueM = newUnique
+        getUniqueSupplyM = newUniqueSupply
 \end{code}
 
 
@@ -344,20 +344,20 @@ newSysLocalIds fs tys
 %************************************************************************
 
 \begin{code}
-traceTc, traceRn :: SDoc -> TcRn ()
+traceTc, traceRn, traceSplice :: SDoc -> TcRn ()
 traceRn      = traceOptTcRn Opt_D_dump_rn_trace
 traceTc      = traceOptTcRn Opt_D_dump_tc_trace
 traceSplice  = traceOptTcRn Opt_D_dump_splices
 
 
-traceIf :: SDoc -> TcRnIf m n ()       
+traceIf, traceHiDiffs :: SDoc -> TcRnIf m n ()
 traceIf      = traceOptIf Opt_D_dump_if_trace
 traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs
 
 
 traceOptIf :: DynFlag -> SDoc -> TcRnIf m n ()  -- No RdrEnv available, so qualify everything
 traceOptIf flag doc = ifOptM flag $
-                    ioToIOEnv (printForUser stderr alwaysQualify doc)
+                     liftIO (printForUser stderr alwaysQualify doc)
 
 traceOptTcRn :: DynFlag -> SDoc -> TcRn ()
 traceOptTcRn flag doc = ifOptM flag $ do
@@ -369,9 +369,13 @@ traceOptTcRn flag doc = ifOptM flag $ do
                        ; dumpTcRn real_doc }
 
 dumpTcRn :: SDoc -> TcRn ()
-dumpTcRn doc = do { rdr_env <- getGlobalRdrEnv ;
-                    dflags <- getDOpts ;
-                   ioToTcRn (printForUser stderr (mkPrintUnqualified dflags rdr_env) doc) }
+dumpTcRn doc = do { rdr_env <- getGlobalRdrEnv 
+                  ; dflags <- getDOpts 
+                  ; liftIO (printForUser stderr (mkPrintUnqualified dflags rdr_env) doc) }
+
+debugDumpTcRn :: SDoc -> TcRn ()
+debugDumpTcRn doc | opt_NoDebugOutput = return ()
+                  | otherwise         = dumpTcRn doc
 
 dumpOptTcRn :: DynFlag -> SDoc -> TcRn ()
 dumpOptTcRn flag doc = ifOptM flag (dumpTcRn doc)
@@ -397,6 +401,9 @@ tcIsHsBoot = do { env <- getGblEnv; return (isHsBoot (tcg_src env)) }
 getGlobalRdrEnv :: TcRn GlobalRdrEnv
 getGlobalRdrEnv = do { env <- getGblEnv; return (tcg_rdr_env env) }
 
+getRdrEnvs :: TcRn (GlobalRdrEnv, LocalRdrEnv)
+getRdrEnvs = do { (gbl,lcl) <- getEnvs; return (tcg_rdr_env gbl, tcl_rdr lcl) }
+
 getImports :: TcRn ImportAvails
 getImports = do { env <- getGblEnv; return (tcg_imports env) }
 
@@ -411,11 +418,6 @@ extendFixityEnv new_bit
 getRecFieldEnv :: TcRn RecFieldEnv
 getRecFieldEnv = do { env <- getGblEnv; return (tcg_field_env env) }
 
-extendRecFieldEnv :: RecFieldEnv -> RnM a -> RnM a
-extendRecFieldEnv new_bit
-  = updGblEnv (\env@(TcGblEnv { tcg_field_env = old_env }) -> 
-               env {tcg_field_env = old_env `plusNameEnv` new_bit})         
-
 getDeclaredDefaultTys :: TcRn (Maybe [Type])
 getDeclaredDefaultTys = do { env <- getGblEnv; return (tcg_default env) }
 \end{code}
@@ -463,9 +465,12 @@ getErrsVar = do { env <- getLclEnv; return (tcl_errs env) }
 setErrsVar :: TcRef Messages -> TcRn a -> TcRn a
 setErrsVar v = updLclEnv (\ env -> env { tcl_errs =  v })
 
-addErr :: Message -> TcRn ()
+addErr :: Message -> TcRn ()   -- Ignores the context stack
 addErr msg = do { loc <- getSrcSpanM ; addErrAt loc msg }
 
+failWith :: Message -> TcRn a
+failWith msg = addErr msg >> failM
+
 addLocErr :: Located e -> (e -> Message) -> TcRn ()
 addLocErr (L loc e) fn = addErrAt loc (fn e)
 
@@ -474,7 +479,7 @@ addErrAt loc msg = addLongErrAt loc msg empty
 
 addLongErrAt :: SrcSpan -> Message -> Message -> TcRn ()
 addLongErrAt loc msg extra
-  = do { traceTc (ptext SLIT("Adding error:") <+> (mkLocMessage loc (msg $$ extra))) ; 
+  = do { traceTc (ptext (sLit "Adding error:") <+> (mkLocMessage loc (msg $$ extra))) ;        
         errs_var <- getErrsVar ;
         rdr_env <- getGlobalRdrEnv ;
          dflags <- getDOpts ;
@@ -483,7 +488,7 @@ addLongErrAt loc msg extra
         writeMutVar errs_var (warns, errs `snocBag` err) }
 
 addErrs :: [(SrcSpan,Message)] -> TcRn ()
-addErrs msgs = mappM_ add msgs
+addErrs msgs = mapM_ add msgs
             where
               add (loc,msg) = addErrAt loc msg
 
@@ -500,21 +505,21 @@ addReportAt loc msg
         writeMutVar errs_var (warns `snocBag` warn, errs) }
 
 addWarn :: Message -> TcRn ()
-addWarn msg = addReport (ptext SLIT("Warning:") <+> msg)
+addWarn msg = addReport (ptext (sLit "Warning:") <+> msg)
 
 addWarnAt :: SrcSpan -> Message -> TcRn ()
-addWarnAt loc msg = addReportAt loc (ptext SLIT("Warning:") <+> msg)
+addWarnAt loc msg = addReportAt loc (ptext (sLit "Warning:") <+> msg)
 
 addLocWarn :: Located e -> (e -> Message) -> TcRn ()
 addLocWarn (L loc e) fn = addReportAt loc (fn e)
 
 checkErr :: Bool -> Message -> TcRn ()
 -- Add the error if the bool is False
-checkErr ok msg = checkM ok (addErr msg)
+checkErr ok msg = unless ok (addErr msg)
 
 warnIf :: Bool -> Message -> TcRn ()
 warnIf True  msg = addWarn msg
-warnIf False msg = return ()
+warnIf False _   = return ()
 
 addMessages :: Messages -> TcRn ()
 addMessages (m_warns, m_errs)
@@ -540,13 +545,13 @@ discardWarnings thing_inside
 
 
 \begin{code}
-try_m :: TcRn r -> TcRn (Either Exception r)
+try_m :: TcRn r -> TcRn (Either IOEnvFailure r)
 -- Does try_m, with a debug-trace on failure
 try_m thing 
   = do { mb_r <- tryM thing ;
         case mb_r of 
             Left exn -> do { traceTc (exn_msg exn); return mb_r }
-            Right r  -> return mb_r }
+            Right _  -> return mb_r }
   where
     exn_msg exn = text "tryTc/recoverM recovering from" <+> text (showException exn)
 
@@ -558,8 +563,21 @@ recoverM :: TcRn r         -- Recovery action; do this if the main one fails
 recoverM recover thing 
   = do { mb_res <- try_m thing ;
         case mb_res of
-          Left exn  -> recover
-          Right res -> returnM res }
+          Left _    -> recover
+          Right res -> return res }
+
+
+-----------------------
+mapAndRecoverM :: (a -> TcRn b) -> [a] -> TcRn [b]
+-- Drop elements of the input that fail, so the result
+-- list can be shorter than the argument list
+mapAndRecoverM _ []     = return []
+mapAndRecoverM f (x:xs) = do { mb_r <- try_m (f x)
+                            ; rs <- mapAndRecoverM f xs
+                            ; return (case mb_r of
+                                         Left _  -> rs
+                                         Right r -> r:rs) }
+                       
 
 -----------------------
 tryTc :: TcRn a -> TcRn (Messages, Maybe a)
@@ -573,7 +591,7 @@ tryTc m
        res  <- try_m (setErrsVar errs_var m) ; 
        msgs <- readMutVar errs_var ;
        return (msgs, case res of
-                           Left exn  -> Nothing
+                           Left _  -> Nothing
                            Right val -> Just val)
        -- The exception is always the IOEnv built-in
        -- in exception; see IOEnv.failM
@@ -633,7 +651,7 @@ checkNoErrs main
   = do { (msgs, mb_res) <- tryTcLIE main
        ; addMessages msgs
        ; case mb_res of
-           Nothing   -> failM
+           Nothing  -> failM
            Just val -> return val
        } 
 
@@ -671,7 +689,7 @@ setErrCtxt :: ErrCtxt -> TcM a -> TcM a
 setErrCtxt ctxt = updLclEnv (\ env -> env { tcl_ctxt = ctxt })
 
 addErrCtxt :: Message -> TcM a -> TcM a
-addErrCtxt msg = addErrCtxtM (\env -> returnM (env, msg))
+addErrCtxt msg = addErrCtxtM (\env -> return (env, msg))
 
 addErrCtxtM :: (TidyEnv -> TcM (TidyEnv, Message)) -> TcM a -> TcM a
 addErrCtxtM msg = updCtxt (\ msgs -> msg : msgs)
@@ -687,7 +705,7 @@ maybeAddErrCtxt (Just msg) thing_inside = addErrCtxt msg thing_inside
 maybeAddErrCtxt Nothing    thing_inside = thing_inside
 
 popErrCtxt :: TcM a -> TcM a
-popErrCtxt = updCtxt (\ msgs -> case msgs of { [] -> []; (m:ms) -> ms })
+popErrCtxt = updCtxt (\ msgs -> case msgs of { [] -> []; (_ : ms) -> ms })
 
 getInstLoc :: InstOrigin -> TcM InstLoc
 getInstLoc origin
@@ -698,7 +716,7 @@ addInstCtxt :: InstLoc -> TcM a -> TcM a
 -- Add the SrcSpan and context from the first Inst in the list
 --     (they all have similar locations)
 addInstCtxt (InstLoc _ src_loc ctxt) thing_inside
-  = setSrcSpan src_loc (updCtxt (\ old_ctxt -> ctxt) thing_inside)
+  = setSrcSpan src_loc (updCtxt (\_ -> ctxt) thing_inside)
 \end{code}
 
     The addErrTc functions add an error message, but do not cause failure.
@@ -711,7 +729,7 @@ addErrTc err_msg = do { env0 <- tcInitTidyEnv
                      ; addErrTcM (env0, err_msg) }
 
 addErrsTc :: [Message] -> TcM ()
-addErrsTc err_msgs = mappM_ addErrTc err_msgs
+addErrsTc err_msgs = mapM_ addErrTc err_msgs
 
 addErrTcM :: (TidyEnv, Message) -> TcM ()
 addErrTcM (tidy_env, err_msg)
@@ -732,7 +750,7 @@ failWithTcM local_and_msg
   = addErrTcM local_and_msg >> failM
 
 checkTc :: Bool -> Message -> TcM ()        -- Check that the boolean is true
-checkTc True  err = returnM ()
+checkTc True  _   = return ()
 checkTc False err = failWithTc err
 \end{code}
 
@@ -747,7 +765,7 @@ addWarnTcM :: (TidyEnv, Message) -> TcM ()
 addWarnTcM (env0, msg)
  = do { ctxt <- getErrCtxt ;
        ctxt_msgs <- do_ctxt env0 ctxt ;
-       addReport (vcat (ptext SLIT("Warning:") <+> msg : ctxt_to_use ctxt_msgs)) }
+       addReport (vcat (ptext (sLit "Warning:") <+> msg : ctxt_to_use ctxt_msgs)) }
 
 warnTc :: Bool -> Message -> TcM ()
 warnTc warn_if_true warn_msg
@@ -783,17 +801,22 @@ tcInitTidyEnv
        Other helper functions
 
 \begin{code}
+add_err_tcm :: TidyEnv -> Message -> SrcSpan
+            -> [TidyEnv -> TcM (TidyEnv, SDoc)]
+            -> TcM ()
 add_err_tcm tidy_env err_msg loc ctxt
  = do { ctxt_msgs <- do_ctxt tidy_env ctxt ;
        addLongErrAt loc err_msg (vcat (ctxt_to_use ctxt_msgs)) }
 
-do_ctxt tidy_env []
+do_ctxt :: TidyEnv -> [TidyEnv -> TcM (TidyEnv, SDoc)] -> TcM [SDoc]
+do_ctxt _ []
  = return []
 do_ctxt tidy_env (c:cs)
  = do {        (tidy_env', m) <- c tidy_env  ;
        ms             <- do_ctxt tidy_env' cs  ;
        return (m:ms) }
 
+ctxt_to_use :: [SDoc] -> [SDoc]
 ctxt_to_use ctxt | opt_PprStyle_Debug = ctxt
                 | otherwise          = take 3 ctxt
 \end{code}
@@ -802,14 +825,12 @@ debugTc is useful for monadic debugging code
 
 \begin{code}
 debugTc :: TcM () -> TcM ()
-#ifdef DEBUG
-debugTc thing = thing
-#else
-debugTc thing = return ()
-#endif
+debugTc thing
+ | debugIsOn = thing
+ | otherwise = return ()
 \end{code}
 
- %************************************************************************
+%************************************************************************
 %*                                                                     *
             Type constraints (the so-called LIE)
 %*                                                                     *
@@ -846,7 +867,7 @@ extendLIE inst
 
 extendLIEs :: [Inst] -> TcM ()
 extendLIEs [] 
-  = returnM ()
+  = return ()
 extendLIEs insts
   = do { lie_var <- getLIEVar ;
         lie <- readMutVar lie_var ;
@@ -867,6 +888,44 @@ setLclTypeEnv lcl_env thing_inside
 
 %************************************************************************
 %*                                                                     *
+            Meta type variable bindings
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+getTcTyVarBindsVar :: TcM (TcRef TcTyVarBinds)
+getTcTyVarBindsVar = do { env <- getLclEnv; return (tcl_tybinds env) }
+
+getTcTyVarBinds :: TcM a -> TcM (a, TcTyVarBinds)
+getTcTyVarBinds thing_inside
+  = do { tybinds_var <- newMutVar emptyBag
+       ; res <- updLclEnv (\ env -> env { tcl_tybinds = tybinds_var }) 
+                         thing_inside
+       ; tybinds <- readMutVar tybinds_var
+       ; return (res, tybinds) 
+       }
+
+bindMetaTyVar :: TcTyVar -> TcType -> TcM ()
+bindMetaTyVar tv ty
+  = do { ASSERTM2( do { details <- readMutVar (metaTvRef tv)
+                      ; return (isFlexi details) }, ppr tv )
+       ; tybinds_var <- getTcTyVarBindsVar
+       ; tybinds <- readMutVar tybinds_var
+       ; writeMutVar tybinds_var (tybinds `snocBag` TcTyVarBind tv ty) 
+       }
+
+getTcTyVarBindsRelation :: TcM [(TcTyVar, TcTyVarSet)]
+getTcTyVarBindsRelation
+  = do { tybinds_var <- getTcTyVarBindsVar
+       ; tybinds <- readMutVar tybinds_var
+       ; return $ map freeTvs (bagToList tybinds)
+       }
+  where
+    freeTvs (TcTyVarBind tv ty) = (tv, tyVarsOfType ty)
+\end{code}
+
+%************************************************************************
+%*                                                                     *
             Template Haskell context
 %*                                                                     *
 %************************************************************************
@@ -875,9 +934,11 @@ setLclTypeEnv lcl_env thing_inside
 recordThUse :: TcM ()
 recordThUse = do { env <- getGblEnv; writeMutVar (tcg_th_used env) True }
 
-keepAliveTc :: Name -> TcM ()          -- Record the name in the keep-alive set
-keepAliveTc n = do { env <- getGblEnv; 
-                  ; updMutVar (tcg_keep env) (`addOneToNameSet` n) }
+keepAliveTc :: Id -> TcM ()    -- Record the name in the keep-alive set
+keepAliveTc id 
+  | isLocalId id = do { env <- getGblEnv; 
+                     ; updMutVar (tcg_keep env) (`addOneToNameSet` idName id) }
+  | otherwise = return ()
 
 keepAliveSetTc :: NameSet -> TcM ()    -- Record the name in the keep-alive set
 keepAliveSetTc ns = do { env <- getGblEnv; 
@@ -931,7 +992,7 @@ initIfaceExtCore :: IfL a -> TcRn a
 initIfaceExtCore thing_inside
   = do  { tcg_env <- getGblEnv 
        ; let { mod = tcg_mod tcg_env
-             ; doc = ptext SLIT("External Core file for") <+> quotes (ppr mod)
+             ; doc = ptext (sLit "External Core file for") <+> quotes (ppr mod)
              ; if_env = IfGblEnv { 
                        if_rec_types = Just (mod, return (tcg_type_env tcg_env)) }
              ; if_lenv = mkIfLclEnv mod doc
@@ -942,9 +1003,11 @@ initIfaceCheck :: HscEnv -> IfG a -> IO a
 -- Used when checking the up-to-date-ness of the old Iface
 -- Initialise the environment with no useful info at all
 initIfaceCheck hsc_env do_this
- = do  { let gbl_env = IfGblEnv { if_rec_types = Nothing }
-       ; initTcRnIf 'i' hsc_env gbl_env () do_this
-    }
+ = do let rec_types = case hsc_type_env_var hsc_env of
+                         Just (mod,var) -> Just (mod, readMutVar var)
+                         Nothing        -> Nothing
+          gbl_env = IfGblEnv { if_rec_types = rec_types }
+      initTcRnIf 'i' hsc_env gbl_env () do_this
 
 initIfaceTc :: ModIface 
            -> (TcRef TypeEnv -> IfL a) -> TcRnIf gbl lcl a
@@ -959,7 +1022,7 @@ initIfaceTc iface do_this
     }
   where
     mod = mi_module iface
-    doc = ptext SLIT("The interface for") <+> quotes (ppr mod)
+    doc = ptext (sLit "The interface for") <+> quotes (ppr mod)
 
 initIfaceRules :: HscEnv -> ModGuts -> IfG a -> IO a
 -- Used when sucking in new Rules in SimplCore
@@ -989,7 +1052,7 @@ failIfM :: Message -> IfL a
 failIfM msg
   = do         { env <- getLclEnv
        ; let full_msg = (if_loc env <> colon) $$ nest 2 msg
-       ; ioToIOEnv (printErrs (full_msg defaultErrStyle))
+       ; liftIO (printErrs (full_msg defaultErrStyle))
        ; failM }
 
 --------------------
@@ -1024,7 +1087,7 @@ forkM_maybe doc thing_inside
                    ; return Nothing }
        }}
   where
-    print_errs sdoc = ioToIOEnv (printErrs (sdoc defaultErrStyle))
+    print_errs sdoc = liftIO (printErrs (sdoc defaultErrStyle))
 
 forkM :: SDoc -> IfL a -> IfL a
 forkM doc thing_inside