-- _result in scope at any time.
let result_fs = FSLIT("_result")
result_name = mkInternalName (getUnique result_fs)
- (mkVarOccFS result_fs) (srcSpanStart span)
+ (mkVarOccFS result_fs) span
result_id = Id.mkLocalId result_name result_ty
-- for each Id we're about to bind in the local envt:
mkNewId :: OccName -> Id -> IO Id
mkNewId occ id = do
let uniq = idUnique id
- loc = nameSrcLoc (idName id)
+ loc = nameSrcSpan (idName id)
name = mkInternalName uniq occ loc
ty = idType id
new_id = Id.mkGlobalId VanillaGlobal name ty (idInfo id)
resume = ic_resume ic
case resume of
[] -> return False
- _:rs -> do
+ r:rs -> do
writeIORef ref hsc_env{ hsc_IC = ic { ic_resume = rs } }
+ abandon_ r
return True
abandonAll :: Session -> IO Bool
let ic = hsc_IC hsc_env
resume = ic_resume ic
case resume of
- [] -> return False
- _:rs -> do
+ [] -> return False
+ rs -> do
writeIORef ref hsc_env{ hsc_IC = ic { ic_resume = [] } }
+ mapM_ abandon_ rs
return True
+-- when abandoning a computation we have to
+-- (a) kill the thread with an async exception, so that the
+-- computation itself is stopped, and
+-- (b) fill in the MVar. This step is necessary because any
+-- thunks that were under evaluation will now be updated
+-- with the partial computation, which still ends in takeMVar,
+-- so any attempt to evaluate one of these thunks will block
+-- unless we fill in the MVar.
+-- See test break010.
+abandon_ :: Resume -> IO ()
+abandon_ r = do
+ killThread (resumeThreadId r)
+ putMVar (resumeBreakMVar r) ()
+
-- -----------------------------------------------------------------------------
-- Bounded list, optimised for repeated cons