X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Futils%2FIOEnv.hs;fp=compiler%2Futils%2FIOEnv.hs;h=61345ca246aa41243a7849838f5864b4830d48be;hp=9332a8b36378c2631c31dbe86ea9389817d479a0;hb=f4ce543cff19b797d54d435dc7c804acdefca9c8;hpb=1f3a7730cd7f831344d2a3b74a0ce700c382e858 diff --git a/compiler/utils/IOEnv.hs b/compiler/utils/IOEnv.hs index 9332a8b..61345ca 100644 --- a/compiler/utils/IOEnv.hs +++ b/compiler/utils/IOEnv.hs @@ -12,6 +12,7 @@ module IOEnv ( -- Errors failM, failWithM, + IOEnvFailure(..), -- Getting at the environment getEnv, setEnv, updEnv, @@ -27,6 +28,7 @@ import Exception import Panic import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef ) +import Data.Typeable import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO ( fixIO ) import MonadUtils @@ -65,12 +67,18 @@ thenM_ :: IOEnv env a -> IOEnv env b -> IOEnv env b thenM_ (IOEnv m) f = IOEnv (\ env -> do { m env ; unIOEnv f env }) failM :: IOEnv env a -failM = IOEnv (\ _ -> ioError (userError "IOEnv failure")) +failM = IOEnv (\ _ -> throwIO IOEnvFailure) failWithM :: String -> IOEnv env a failWithM s = IOEnv (\ _ -> ioError (userError s)) +data IOEnvFailure = IOEnvFailure + deriving Typeable +instance Show IOEnvFailure where + show IOEnvFailure = "IOEnv failure" + +instance Exception IOEnvFailure ---------------------------------------------------------------------- -- Fundmantal combinators specific to the monad @@ -95,7 +103,7 @@ fixM f = IOEnv (\ env -> fixIO (\ r -> unIOEnv (f r) env)) --------------------------- -tryM :: IOEnv env r -> IOEnv env (Either IOException r) +tryM :: IOEnv env r -> IOEnv env (Either IOEnvFailure r) -- Reflect UserError exceptions (only) into IOEnv monad -- Other exceptions are not caught; they are simply propagated as exns -- @@ -103,7 +111,10 @@ tryM :: IOEnv env r -> IOEnv env (Either IOException r) -- to UserErrors. But, say, pattern-match failures in GHC itself should -- not be caught here, else they'll be reported as errors in the program -- begin compiled! -tryM (IOEnv thing) = IOEnv (\ env -> tryUser (thing env)) +tryM (IOEnv thing) = IOEnv (\ env -> tryIOEnvFailure (thing env)) + +tryIOEnvFailure :: IO a -> IO (Either IOEnvFailure a) +tryIOEnvFailure = try -- XXX We shouldn't be catching everything, e.g. timeouts tryAllM :: IOEnv env r -> IOEnv env (Either SomeException r)