Matthew Pickering pushed to branch wip/on-exception-annotate at Glasgow Haskell Compiler / GHC
Commits:
-
642000be
by Matthew Pickering at 2026-03-10T16:12:33+00:00
9 changed files:
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
- libraries/ghc-internal/src/GHC/Internal/IO.hs
- + testsuite/tests/exceptions/T26759.hs
- + testsuite/tests/exceptions/T26759.stderr
- + testsuite/tests/exceptions/T26759a.hs
- + testsuite/tests/exceptions/T26759a.stderr
- + testsuite/tests/exceptions/T26759a.stdout
- testsuite/tests/exceptions/all.T
Changes:
| ... | ... | @@ -27,6 +27,7 @@ |
| 27 | 27 | * Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
|
| 28 | 28 | * Hide implementation details when throwing exceptions in throw and throwSTM. ([CLC proposal #387](https://github.com/haskell/core-libraries-committee/issues/387))
|
| 29 | 29 | * Change `hIsReadable` and `hIsWritable` such that they always throw a respective exception when encountering a closed or semi-closed handle, not just in the case of a file handle. ([CLC proposal #371](github.com/haskell/core-libraries-committee/issues/371))
|
| 30 | + * Annotate `onException` continuation with `WhileHandling`. ([CLC Proposal #397](https://github.com/haskell/core-libraries-committee/issues/397))
|
|
| 30 | 31 | |
| 31 | 32 | ## 4.22.0.0 *TBA*
|
| 32 | 33 | * Shipped with GHC 9.14.1
|
| ... | ... | @@ -203,7 +203,7 @@ tryJust p a = catchJust p (Right `fmap` a) (return . Left) |
| 203 | 203 | -- exception raised by the computation.
|
| 204 | 204 | onException :: IO a -> IO b -> IO a
|
| 205 | 205 | onException io what = io `catchNoPropagate` \e -> do
|
| 206 | - _ <- what
|
|
| 206 | + _ <- annotateIO (whileHandling e) what
|
|
| 207 | 207 | rethrowIO (e :: ExceptionWithContext SomeException)
|
| 208 | 208 | |
| 209 | 209 | -----------------------------------------------------------------------------
|
| ... | ... | @@ -52,7 +52,7 @@ module GHC.Internal.IO ( |
| 52 | 52 | import GHC.Internal.Base
|
| 53 | 53 | import GHC.Internal.ST
|
| 54 | 54 | import GHC.Internal.Exception
|
| 55 | -import GHC.Internal.Exception.Type (NoBacktrace(..), WhileHandling(..), HasExceptionContext, ExceptionWithContext(..))
|
|
| 55 | +import GHC.Internal.Exception.Type (NoBacktrace(..), whileHandling, WhileHandling(..), HasExceptionContext, ExceptionWithContext(..))
|
|
| 56 | 56 | import GHC.Internal.Show
|
| 57 | 57 | import GHC.Internal.IO.Unsafe
|
| 58 | 58 | import GHC.Internal.Unsafe.Coerce ( unsafeCoerce )
|
| ... | ... | @@ -363,7 +363,7 @@ getMaskingState = IO $ \s -> |
| 363 | 363 | |
| 364 | 364 | onException :: IO a -> IO b -> IO a
|
| 365 | 365 | onException io what = io `catchExceptionNoPropagate` \e -> do
|
| 366 | - _ <- what
|
|
| 366 | + _ <- annotateIO (whileHandling e) what
|
|
| 367 | 367 | rethrowIO (e :: ExceptionWithContext SomeException)
|
| 368 | 368 | |
| 369 | 369 | -- | Executes an IO computation with asynchronous
|
| 1 | +import Control.Exception
|
|
| 2 | + |
|
| 3 | +run :: IO ()
|
|
| 4 | +run = failingAction `onException` failingCleanup
|
|
| 5 | + where
|
|
| 6 | + failingAction = throwIO (ErrorCall "outer failure")
|
|
| 7 | + failingCleanup = throwIO (ErrorCall "cleanup failure")
|
|
| 8 | + |
|
| 9 | +main :: IO ()
|
|
| 10 | +main = run |
| 1 | +T26759: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 2 | + |
|
| 3 | +cleanup failure
|
|
| 4 | + |
|
| 5 | +While handling outer failure
|
|
| 6 | + |
|
| 7 | +HasCallStack backtrace:
|
|
| 8 | + throwIO, called at T26759.hs:7:22 in main:Main
|
|
| 9 | + |
| 1 | +import Control.Exception
|
|
| 2 | + |
|
| 3 | +run :: IO ()
|
|
| 4 | +run = failingAction `onException` cleanup
|
|
| 5 | + where
|
|
| 6 | + failingAction = throwIO (ErrorCall "outer failure")
|
|
| 7 | + cleanup = putStrLn "cleanup"
|
|
| 8 | + |
|
| 9 | +main :: IO ()
|
|
| 10 | +main = run |
| 1 | +T26759a: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
|
|
| 2 | + |
|
| 3 | +outer failure
|
|
| 4 | + |
|
| 5 | +HasCallStack backtrace:
|
|
| 6 | + throwIO, called at T26759a.hs:6:21 in main:Main
|
|
| 7 | + |
| 1 | +cleanup |
| 1 | 1 | test('T25052', normal, compile_and_run, [''])
|
| 2 | - |
|
| 2 | +test('T26759', exit_code(1), compile_and_run, [''])
|
|
| 3 | +test('T26759a', exit_code(1), compile_and_run, ['']) |