Start to actually use extensible exceptions
[ghc-base.git] / Control / Exception.hs
1 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Control.Exception
5 -- Copyright   :  (c) The University of Glasgow 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  libraries@haskell.org
9 -- Stability   :  experimental
10 -- Portability :  non-portable (extended exceptions)
11 --
12 -- This module provides support for raising and catching both built-in
13 -- and user-defined exceptions.
14 --
15 -- In addition to exceptions thrown by 'IO' operations, exceptions may
16 -- be thrown by pure code (imprecise exceptions) or by external events
17 -- (asynchronous exceptions), but may only be caught in the 'IO' monad.
18 -- For more details, see:
19 --
20 --  * /A semantics for imprecise exceptions/, by Simon Peyton Jones,
21 --    Alastair Reid, Tony Hoare, Simon Marlow, Fergus Henderson,
22 --    in /PLDI'99/.
23 --
24 --  * /Asynchronous exceptions in Haskell/, by Simon Marlow, Simon Peyton
25 --    Jones, Andy Moran and John Reppy, in /PLDI'01/.
26 --
27 -----------------------------------------------------------------------------
28
29 module Control.Exception (
30
31         -- * The Exception type
32         SomeException(..),
33         Exception(..),          -- instance Eq, Ord, Show, Typeable
34         IOException,            -- instance Eq, Ord, Show, Typeable
35         ArithException(..),     -- instance Eq, Ord, Show, Typeable
36         ArrayException(..),     -- instance Eq, Ord, Show, Typeable
37         AssertionFailed(..),
38         AsyncException(..),     -- instance Eq, Ord, Show, Typeable
39         NonTermination(..), nonTermination,
40         BlockedOnDeadMVar(..),
41         BlockedIndefinitely(..),
42         NestedAtomically(..), nestedAtomically,
43         Deadlock(..),
44         NoMethodError(..),
45         PatternMatchFail(..),
46         RecConError(..),
47         RecSelError(..),
48         RecUpdError(..),
49
50         -- * Throwing exceptions
51         throwIO,        -- :: Exception -> IO a
52         throw,          -- :: Exception -> a
53         ioError,        -- :: IOError -> IO a
54 #ifdef __GLASGOW_HASKELL__
55         throwTo,        -- :: ThreadId -> Exception -> a
56 #endif
57
58         -- * Catching Exceptions
59
60         -- |There are several functions for catching and examining
61         -- exceptions; all of them may only be used from within the
62         -- 'IO' monad.
63
64         -- ** The @catch@ functions
65         catch,     -- :: IO a -> (Exception -> IO a) -> IO a
66         catches, Handler(..),
67         catchAny,
68         catchJust, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
69
70         -- ** The @handle@ functions
71         handle,    -- :: (Exception -> IO a) -> IO a -> IO a
72         handleAny,
73         handleJust,-- :: (Exception -> Maybe b) -> (b -> IO a) -> IO a -> IO a
74
75         -- ** The @try@ functions
76         try,       -- :: IO a -> IO (Either Exception a)
77         tryJust,   -- :: (Exception -> Maybe b) -> a    -> IO (Either b a)
78         ignoreExceptions,
79
80         -- ** The @evaluate@ function
81         evaluate,  -- :: a -> IO a
82
83         -- ** The @mapException@ function
84         mapException,           -- :: (Exception -> Exception) -> a -> a
85
86         -- * Asynchronous Exceptions
87
88         -- $async
89
90         -- ** Asynchronous exception control
91
92         -- |The following two functions allow a thread to control delivery of
93         -- asynchronous exceptions during a critical region.
94
95         block,          -- :: IO a -> IO a
96         unblock,        -- :: IO a -> IO a
97         blocked,        -- :: IO Bool
98
99         -- *** Applying @block@ to an exception handler
100
101         -- $block_handler
102
103         -- *** Interruptible operations
104
105         -- $interruptible
106
107         -- * Assertions
108
109         assert,         -- :: Bool -> a -> a
110
111         -- * Utilities
112
113         bracket,        -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
114         bracket_,       -- :: IO a -> IO b -> IO c -> IO ()
115         bracketOnError,
116
117         finally,        -- :: IO a -> IO b -> IO a
118
119         recSelError, recConError, irrefutPatError, runtimeError,
120         nonExhaustiveGuardsError, patError, noMethodBindingError,
121
122 #ifdef __GLASGOW_HASKELL__
123         setUncaughtExceptionHandler,      -- :: (Exception -> IO ()) -> IO ()
124         getUncaughtExceptionHandler       -- :: IO (Exception -> IO ())
125 #endif
126   ) where
127
128 #ifdef __GLASGOW_HASKELL__
129 import GHC.Base
130 import {-# SOURCE #-} GHC.Handle
131 import GHC.List
132 import GHC.Num
133 import GHC.Show
134 import GHC.IOBase as ExceptionBase
135 import GHC.Exception hiding ( Exception )
136 import {-# SOURCE #-} GHC.Conc         ( ThreadId(ThreadId) )
137 import Foreign.C.String ( CString, withCString )
138 #endif
139
140 #ifdef __HUGS__
141 import Hugs.Exception   as ExceptionBase
142 #endif
143
144 import Data.Dynamic
145 import Data.Either
146 import Data.Maybe
147
148 #ifdef __NHC__
149 import qualified System.IO.Error as H'98 (catch)
150 import System.IO.Error (ioError)
151 import IO              (bracket)
152 import DIOError         -- defn of IOError type
153 import System          (ExitCode())
154
155 -- minimum needed for nhc98 to pretend it has Exceptions
156 data Exception   = IOException    IOException
157                  | ArithException ArithException
158                  | ArrayException ArrayException
159                  | AsyncException AsyncException
160                  | ExitException  ExitCode
161                  deriving Show
162 type IOException = IOError
163 data ArithException
164 data ArrayException
165 data AsyncException
166 instance Show ArithException
167 instance Show ArrayException
168 instance Show AsyncException
169
170 catch    :: IO a -> (Exception -> IO a) -> IO a
171 a `catch` b = a `H'98.catch` (b . IOException)
172
173 throwIO  :: Exception -> IO a
174 throwIO (IOException e) = ioError e
175 throwIO _               = ioError (UserError "Control.Exception.throwIO"
176                                              "unknown exception")
177 throw    :: Exception -> a
178 throw     = unsafePerformIO . throwIO
179
180 evaluate :: a -> IO a
181 evaluate x = x `seq` return x
182
183 assert :: Bool -> a -> a
184 assert True  x = x
185 assert False _ = throw (IOException (UserError "" "Assertion failed"))
186 #endif
187
188 #ifndef __GLASGOW_HASKELL__
189 -- Dummy definitions for implementations lacking asynchonous exceptions
190
191 block   :: IO a -> IO a
192 block    = id
193 unblock :: IO a -> IO a
194 unblock  = id
195 blocked :: IO Bool
196 blocked  = return False
197 #endif
198
199 -----------------------------------------------------------------------------
200 -- Catching exceptions
201
202 -- |This is the simplest of the exception-catching functions.  It
203 -- takes a single argument, runs it, and if an exception is raised
204 -- the \"handler\" is executed, with the value of the exception passed as an
205 -- argument.  Otherwise, the result is returned as normal.  For example:
206 --
207 -- >   catch (openFile f ReadMode) 
208 -- >       (\e -> hPutStr stderr ("Couldn't open "++f++": " ++ show e))
209 --
210 -- For catching exceptions in pure (non-'IO') expressions, see the
211 -- function 'evaluate'.
212 --
213 -- Note that due to Haskell\'s unspecified evaluation order, an
214 -- expression may return one of several possible exceptions: consider
215 -- the expression @error \"urk\" + 1 \`div\` 0@.  Does
216 -- 'catch' execute the handler passing
217 -- @ErrorCall \"urk\"@, or @ArithError DivideByZero@?
218 --
219 -- The answer is \"either\": 'catch' makes a
220 -- non-deterministic choice about which exception to catch.  If you
221 -- call it again, you might get a different exception back.  This is
222 -- ok, because 'catch' is an 'IO' computation.
223 --
224 -- Note that 'catch' catches all types of exceptions, and is generally
225 -- used for \"cleaning up\" before passing on the exception using
226 -- 'throwIO'.  It is not good practice to discard the exception and
227 -- continue, without first checking the type of the exception (it
228 -- might be a 'ThreadKilled', for example).  In this case it is usually better
229 -- to use 'catchJust' and select the kinds of exceptions to catch.
230 --
231 -- Also note that the "Prelude" also exports a function called
232 -- 'Prelude.catch' with a similar type to 'Control.Exception.catch',
233 -- except that the "Prelude" version only catches the IO and user
234 -- families of exceptions (as required by Haskell 98).  
235 --
236 -- We recommend either hiding the "Prelude" version of 'Prelude.catch'
237 -- when importing "Control.Exception": 
238 --
239 -- > import Prelude hiding (catch)
240 --
241 -- or importing "Control.Exception" qualified, to avoid name-clashes:
242 --
243 -- > import qualified Control.Exception as C
244 --
245 -- and then using @C.catch@
246 --
247 #ifndef __NHC__
248 catch   :: Exception e
249         => IO a         -- ^ The computation to run
250         -> (e -> IO a)  -- ^ Handler to invoke if an exception is raised
251         -> IO a
252 catch = ExceptionBase.catchException
253
254 catches :: IO a -> [Handler a] -> IO a
255 catches io handlers = io `catch` catchesHandler handlers
256
257 catchesHandler :: [Handler a] -> SomeException -> IO a
258 catchesHandler handlers e = foldr tryHandler (throw e) handlers
259     where tryHandler (Handler handler) res
260               = case fromException e of
261                 Just e' -> handler e'
262                 Nothing -> res
263
264 data Handler a = forall e . Exception e => Handler (e -> IO a)
265 #endif
266 -- | The function 'catchJust' is like 'catch', but it takes an extra
267 -- argument which is an /exception predicate/, a function which
268 -- selects which type of exceptions we\'re interested in.
269 --
270 -- >   result <- catchJust errorCalls thing_to_try handler
271 --
272 -- Any other exceptions which are not matched by the predicate
273 -- are re-raised, and may be caught by an enclosing
274 -- 'catch' or 'catchJust'.
275 catchJust
276         :: Exception e
277         => (e -> Maybe b)         -- ^ Predicate to select exceptions
278         -> IO a                   -- ^ Computation to run
279         -> (b -> IO a)            -- ^ Handler
280         -> IO a
281 catchJust p a handler = catch a handler'
282   where handler' e = case p e of 
283                         Nothing -> throw e
284                         Just b  -> handler b
285
286 -- | A version of 'catch' with the arguments swapped around; useful in
287 -- situations where the code for the handler is shorter.  For example:
288 --
289 -- >   do handle (\e -> exitWith (ExitFailure 1)) $
290 -- >      ...
291 handle     :: Exception e => (e -> IO a) -> IO a -> IO a
292 handle     =  flip catch
293
294 handleAny  :: (forall e . Exception e => e -> IO a) -> IO a -> IO a
295 handleAny  =  flip catchAny
296
297 -- | A version of 'catchJust' with the arguments swapped around (see
298 -- 'handle').
299 handleJust :: Exception e => (e -> Maybe b) -> (b -> IO a) -> IO a -> IO a
300 handleJust p =  flip (catchJust p)
301
302 -----------------------------------------------------------------------------
303 -- 'mapException'
304
305 -- | This function maps one exception into another as proposed in the
306 -- paper \"A semantics for imprecise exceptions\".
307
308 -- Notice that the usage of 'unsafePerformIO' is safe here.
309
310 mapException :: Exception e => (e -> e) -> a -> a
311 mapException f v = unsafePerformIO (catch (evaluate v)
312                                           (\x -> throw (f x)))
313
314 -----------------------------------------------------------------------------
315 -- 'try' and variations.
316
317 -- | Similar to 'catch', but returns an 'Either' result which is
318 -- @('Right' a)@ if no exception was raised, or @('Left' e)@ if an
319 -- exception was raised and its value is @e@.
320 --
321 -- >  try a = catch (Right `liftM` a) (return . Left)
322 --
323 -- Note: as with 'catch', it is only polite to use this variant if you intend
324 -- to re-throw the exception after performing whatever cleanup is needed.
325 -- Otherwise, 'tryJust' is generally considered to be better.
326 --
327 -- Also note that "System.IO.Error" also exports a function called
328 -- 'System.IO.Error.try' with a similar type to 'Control.Exception.try',
329 -- except that it catches only the IO and user families of exceptions
330 -- (as required by the Haskell 98 @IO@ module).
331
332 try :: Exception e => IO a -> IO (Either e a)
333 try a = catch (a >>= \ v -> return (Right v)) (\e -> return (Left e))
334
335 -- | A variant of 'try' that takes an exception predicate to select
336 -- which exceptions are caught (c.f. 'catchJust').  If the exception
337 -- does not match the predicate, it is re-thrown.
338 tryJust :: Exception e => (e -> Maybe b) -> IO a -> IO (Either b a)
339 tryJust p a = do
340   r <- try a
341   case r of
342         Right v -> return (Right v)
343         Left  e -> case p e of
344                         Nothing -> throw e
345                         Just b  -> return (Left b)
346
347 ignoreExceptions :: IO () -> IO ()
348 ignoreExceptions io = io `catchAny` \_ -> return ()
349
350 -----------------------------------------------------------------------------
351 -- Some Useful Functions
352
353 -- | When you want to acquire a resource, do some work with it, and
354 -- then release the resource, it is a good idea to use 'bracket',
355 -- because 'bracket' will install the necessary exception handler to
356 -- release the resource in the event that an exception is raised
357 -- during the computation.  If an exception is raised, then 'bracket' will 
358 -- re-raise the exception (after performing the release).
359 --
360 -- A common example is opening a file:
361 --
362 -- > bracket
363 -- >   (openFile "filename" ReadMode)
364 -- >   (hClose)
365 -- >   (\handle -> do { ... })
366 --
367 -- The arguments to 'bracket' are in this order so that we can partially apply 
368 -- it, e.g.:
369 --
370 -- > withFile name mode = bracket (openFile name mode) hClose
371 --
372 #ifndef __NHC__
373 bracket 
374         :: IO a         -- ^ computation to run first (\"acquire resource\")
375         -> (a -> IO b)  -- ^ computation to run last (\"release resource\")
376         -> (a -> IO c)  -- ^ computation to run in-between
377         -> IO c         -- returns the value from the in-between computation
378 bracket before after thing =
379   block (do
380     a <- before 
381     r <- catchAny
382            (unblock (thing a))
383            (\e -> do { after a; throw e })
384     after a
385     return r
386  )
387 #endif
388
389 -- | A specialised variant of 'bracket' with just a computation to run
390 -- afterward.
391 -- 
392 finally :: IO a         -- ^ computation to run first
393         -> IO b         -- ^ computation to run afterward (even if an exception 
394                         -- was raised)
395         -> IO a         -- returns the value from the first computation
396 a `finally` sequel =
397   block (do
398     r <- catchAny
399              (unblock a)
400              (\e -> do { sequel; throw e })
401     sequel
402     return r
403   )
404
405 -- | A variant of 'bracket' where the return value from the first computation
406 -- is not required.
407 bracket_ :: IO a -> IO b -> IO c -> IO c
408 bracket_ before after thing = bracket before (const after) (const thing)
409
410 -- | Like bracket, but only performs the final action if there was an 
411 -- exception raised by the in-between computation.
412 bracketOnError
413         :: IO a         -- ^ computation to run first (\"acquire resource\")
414         -> (a -> IO b)  -- ^ computation to run last (\"release resource\")
415         -> (a -> IO c)  -- ^ computation to run in-between
416         -> IO c         -- returns the value from the in-between computation
417 bracketOnError before after thing =
418   block (do
419     a <- before 
420     catchAny
421         (unblock (thing a))
422         (\e -> do { after a; throw e })
423  )
424
425 -- -----------------------------------------------------------------------------
426 -- Asynchronous exceptions
427
428 {- $async
429
430  #AsynchronousExceptions# Asynchronous exceptions are so-called because they arise due to
431 external influences, and can be raised at any point during execution.
432 'StackOverflow' and 'HeapOverflow' are two examples of
433 system-generated asynchronous exceptions.
434
435 The primary source of asynchronous exceptions, however, is
436 'throwTo':
437
438 >  throwTo :: ThreadId -> Exception -> IO ()
439
440 'throwTo' (also 'throwDynTo' and 'Control.Concurrent.killThread') allows one
441 running thread to raise an arbitrary exception in another thread.  The
442 exception is therefore asynchronous with respect to the target thread,
443 which could be doing anything at the time it receives the exception.
444 Great care should be taken with asynchronous exceptions; it is all too
445 easy to introduce race conditions by the over zealous use of
446 'throwTo'.
447 -}
448
449 {- $block_handler
450 There\'s an implied 'block' around every exception handler in a call
451 to one of the 'catch' family of functions.  This is because that is
452 what you want most of the time - it eliminates a common race condition
453 in starting an exception handler, because there may be no exception
454 handler on the stack to handle another exception if one arrives
455 immediately.  If asynchronous exceptions are blocked on entering the
456 handler, though, we have time to install a new exception handler
457 before being interrupted.  If this weren\'t the default, one would have
458 to write something like
459
460 >      block (
461 >           catch (unblock (...))
462 >                      (\e -> handler)
463 >      )
464
465 If you need to unblock asynchronous exceptions again in the exception
466 handler, just use 'unblock' as normal.
467
468 Note that 'try' and friends /do not/ have a similar default, because
469 there is no exception handler in this case.  If you want to use 'try'
470 in an asynchronous-exception-safe way, you will need to use
471 'block'.
472 -}
473
474 {- $interruptible
475
476 Some operations are /interruptible/, which means that they can receive
477 asynchronous exceptions even in the scope of a 'block'.  Any function
478 which may itself block is defined as interruptible; this includes
479 'Control.Concurrent.MVar.takeMVar'
480 (but not 'Control.Concurrent.MVar.tryTakeMVar'),
481 and most operations which perform
482 some I\/O with the outside world.  The reason for having
483 interruptible operations is so that we can write things like
484
485 >      block (
486 >         a <- takeMVar m
487 >         catch (unblock (...))
488 >               (\e -> ...)
489 >      )
490
491 if the 'Control.Concurrent.MVar.takeMVar' was not interruptible,
492 then this particular
493 combination could lead to deadlock, because the thread itself would be
494 blocked in a state where it can\'t receive any asynchronous exceptions.
495 With 'Control.Concurrent.MVar.takeMVar' interruptible, however, we can be
496 safe in the knowledge that the thread can receive exceptions right up
497 until the point when the 'Control.Concurrent.MVar.takeMVar' succeeds.
498 Similar arguments apply for other interruptible operations like
499 'System.IO.openFile'.
500 -}
501
502 #if !(__GLASGOW_HASKELL__ || __NHC__)
503 assert :: Bool -> a -> a
504 assert True x = x
505 assert False _ = throw (AssertionFailed "")
506 #endif
507
508
509 #ifdef __GLASGOW_HASKELL__
510 {-# NOINLINE uncaughtExceptionHandler #-}
511 uncaughtExceptionHandler :: IORef (SomeException -> IO ())
512 uncaughtExceptionHandler = unsafePerformIO (newIORef defaultHandler)
513    where
514       defaultHandler :: SomeException -> IO ()
515       defaultHandler se@(SomeException ex) = do
516          (hFlush stdout) `catchAny` (\ _ -> return ())
517          let msg = case cast ex of
518                Just Deadlock -> "no threads to run:  infinite loop or deadlock?"
519                _ -> case cast ex of
520                     Just (ErrorCall s) -> s
521                     _                  -> showsPrec 0 se ""
522          withCString "%s" $ \cfmt ->
523           withCString msg $ \cmsg ->
524             errorBelch cfmt cmsg
525
526 -- don't use errorBelch() directly, because we cannot call varargs functions
527 -- using the FFI.
528 foreign import ccall unsafe "HsBase.h errorBelch2"
529    errorBelch :: CString -> CString -> IO ()
530
531 setUncaughtExceptionHandler :: (SomeException -> IO ()) -> IO ()
532 setUncaughtExceptionHandler = writeIORef uncaughtExceptionHandler
533
534 getUncaughtExceptionHandler :: IO (SomeException -> IO ())
535 getUncaughtExceptionHandler = readIORef uncaughtExceptionHandler
536 #endif
537
538 recSelError, recConError, irrefutPatError, runtimeError,
539              nonExhaustiveGuardsError, patError, noMethodBindingError
540         :: Addr# -> a   -- All take a UTF8-encoded C string
541
542 recSelError              s = throw (RecSelError (unpackCStringUtf8# s)) -- No location info unfortunately
543 runtimeError             s = error (unpackCStringUtf8# s)               -- No location info unfortunately
544
545 nonExhaustiveGuardsError s = throw (PatternMatchFail (untangle s "Non-exhaustive guards in"))
546 irrefutPatError          s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern"))
547 recConError              s = throw (RecConError      (untangle s "Missing field in record construction"))
548 noMethodBindingError     s = throw (NoMethodError    (untangle s "No instance nor default method for class operation"))
549 patError                 s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in"))
550
551 -----
552
553 data PatternMatchFail = PatternMatchFail String
554     deriving Typeable
555
556 instance Exception PatternMatchFail
557
558 instance Show PatternMatchFail where
559     showsPrec _ (PatternMatchFail err) = showString err
560
561 -----
562
563 data RecSelError = RecSelError String
564     deriving Typeable
565
566 instance Exception RecSelError
567
568 instance Show RecSelError where
569     showsPrec _ (RecSelError err) = showString err
570
571 -----
572
573 data RecConError = RecConError String
574     deriving Typeable
575
576 instance Exception RecConError
577
578 instance Show RecConError where
579     showsPrec _ (RecConError err) = showString err
580
581 -----
582
583 data RecUpdError = RecUpdError String
584     deriving Typeable
585
586 instance Exception RecUpdError
587
588 instance Show RecUpdError where
589     showsPrec _ (RecUpdError err) = showString err
590
591 -----
592
593 data NoMethodError = NoMethodError String
594     deriving Typeable
595
596 instance Exception NoMethodError
597
598 instance Show NoMethodError where
599     showsPrec _ (NoMethodError err) = showString err
600
601 -----
602
603 data AssertionFailed = AssertionFailed String
604     deriving Typeable
605
606 instance Exception AssertionFailed
607
608 instance Show AssertionFailed where
609     showsPrec _ (AssertionFailed err) = showString err
610
611 -----
612
613 data NonTermination = NonTermination
614     deriving Typeable
615
616 instance Exception NonTermination
617
618 instance Show NonTermination where
619     showsPrec _ NonTermination = showString "<<loop>>"
620
621 -- GHC's RTS calls this
622 nonTermination :: SomeException
623 nonTermination = toException NonTermination
624
625 -----
626
627 data Deadlock = Deadlock
628     deriving Typeable
629
630 instance Exception Deadlock
631
632 instance Show Deadlock where
633     showsPrec _ Deadlock = showString "<<deadlock>>"
634
635 -----
636
637 data NestedAtomically = NestedAtomically
638     deriving Typeable
639
640 instance Exception NestedAtomically
641
642 instance Show NestedAtomically where
643     showsPrec _ NestedAtomically = showString "Control.Concurrent.STM.atomically was nested"
644
645 -- GHC's RTS calls this
646 nestedAtomically :: SomeException
647 nestedAtomically = toException NestedAtomically
648
649 -----
650
651 instance Exception Dynamic
652
653 -----
654
655 assertError :: Addr# -> Bool -> a -> a
656 assertError str pred v
657   | pred      = v
658   | otherwise = throw (AssertionFailed (untangle str "Assertion failed"))
659
660 {-
661 (untangle coded message) expects "coded" to be of the form
662         "location|details"
663 It prints
664         location message details
665 -}
666 untangle :: Addr# -> String -> String
667 untangle coded message
668   =  location
669   ++ ": " 
670   ++ message
671   ++ details
672   ++ "\n"
673   where
674     coded_str = unpackCStringUtf8# coded
675
676     (location, details)
677       = case (span not_bar coded_str) of { (loc, rest) ->
678         case rest of
679           ('|':det) -> (loc, ' ' : det)
680           _         -> (loc, "")
681         }
682     not_bar c = c /= '|'
683
684 -- XXX From GHC.Conc
685 throwTo :: Exception e => ThreadId -> e -> IO ()
686 throwTo (ThreadId id) ex = IO $ \ s ->
687    case (killThread# id (toException ex) s) of s1 -> (# s1, () #)
688