Thunk is incorrectly updated on async exception in GHCi
The following program produces different results depending on whether it is compiled or interpreted:
import Control.Concurrent
import Control.Exception
import System.IO.Unsafe
main :: IO ()
main = do
let io_thunk = unsafePerformIO $ threadDelay 1000000 *> pure ()
eval_thread <- forkIO (evaluate io_thunk *> pure ())
threadDelay 500000
killThread eval_thread
print io_thunk
When compiled, the program prints ()
, but when interpreted, it terminates with an exception:
$ ghc A.hs
[1 of 2] Compiling Main ( A.hs, A.o )
[2 of 2] Linking A
$ ./A
()
$ ghc --run A.hs
<interactive>: thread killed
It seems like io_thunk
is somehow being incorrectly overwritten as if the async exception were in fact raised synchronously.