From 47e446c74eb726d30fdc51a4352cdc1903b75754 Mon Sep 17 00:00:00 2001 From: sof Date: Sat, 16 May 1998 20:01:18 +0000 Subject: [PATCH] [project @ 1998-05-16 20:01:18 by sof] unsafeInterleaveIO: handle I/O failure a little bit more gracefully --- ghc/lib/std/PrelUnsafe.lhs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/ghc/lib/std/PrelUnsafe.lhs b/ghc/lib/std/PrelUnsafe.lhs index 775582c..d85c639 100644 --- a/ghc/lib/std/PrelUnsafe.lhs +++ b/ghc/lib/std/PrelUnsafe.lhs @@ -5,7 +5,25 @@ \section[PrelUnsafe]{Module @PrelUnsafe@} These functions have their own module because we definitely don't want -them to be inlined. +them to be inlined. The reason is that we may end up turning an action +into a constant when it is not: + + new :: IORef Int + new = + let + foo = unsafePerformIO getNextValue + in + newIORef foo + +If unsafePerformIO is inlined here, the application of getNextValue to the realWorld# +token might be floated out, leaving us with + + foo' = getNextValue realWorld# + + new :: IORef Int + new = newIORef foo' + +which is not what we want. \begin{code} {-# OPTIONS -fno-implicit-prelude #-} @@ -40,11 +58,15 @@ unsafePerformIO (IO m) unsafeInterleaveIO :: IO a -> IO a unsafeInterleaveIO (IO m) = IO ( \ s -> let - IOok _ r = m s + res = + case m s of + IOok _ r -> r + IOfail _ e -> error ("unsafeInterleaveIO: I/O error: " ++ show e ++ "\n") in - IOok s r) + IOok s res + ) + -{-# GENERATE_SPECS _trace a #-} trace :: String -> a -> a trace string expr = unsafePerformIO ( @@ -55,4 +77,3 @@ trace string expr where sTDERR = (``stderr'' :: Addr) \end{code} - -- 1.7.10.4