From 8fb34a0104498a5926ea8a907a9f3361bcfbe59b Mon Sep 17 00:00:00 2001 From: Edsko de Vries Date: Wed, 20 May 2026 08:30:06 +0200 Subject: [PATCH] Use `onException` in `withAsyncUsing` This is quite a central function in `async`; the pattern ```hs .. `catch` \e -> .. throwIO e ``` should be avoided in GHC >= 9.12, as it will add unnecessary `WhileHandling` annotations. There are low level functions which can be used when necessary (`catchNoPropagate`, `rethrowIO`), but in this particular case `onException` captures the same pattern, and _it_ has been [modified][1] in recent GHC to use these new primitives. The oldest version of GHC that `async.cabal` lists as supported is 7.0.4, even though it's not tested in CI. I verified that `onException` was already available [back then][2]. [1]: https://hackage.haskell.org/package/ghc-internal-9.1201.0/docs/src/GHC.Internal.Control.Exception.Base.html#onException [2]: https://hackage.haskell.org/package/base-4.3.0.0/docs/src/Control-Exception-Base.html#onException --- Control/Concurrent/Async/Internal.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Control/Concurrent/Async/Internal.hs b/Control/Concurrent/Async/Internal.hs index 00abf7f..4093a57 100644 --- a/Control/Concurrent/Async/Internal.hs +++ b/Control/Concurrent/Async/Internal.hs @@ -217,9 +217,7 @@ withAsyncUsing doFork action inner = do let action_plus = debugLabelMe >> action t <- doFork $ try (restore action_plus) >>= atomically . putTMVar var let a = Async t (readTMVar var) - r <- restore (inner a) `catchAll` \e -> do - uninterruptibleCancel a - throwIO e + r <- restore (inner a) `onException` uninterruptibleCancel a uninterruptibleCancel a return r