+-- helper type for simplifying the type casting logic below
+data Caster = forall e . New.Exception e => Caster (e -> Exception)
+
+instance New.Exception Exception where
+ -- We need to collect all the sorts of exceptions that used to be
+ -- bundled up into the Exception type, and rebundle them for
+ -- legacy handlers.
+ fromException exc0 = foldr tryCast Nothing casters where
+ tryCast (Caster f) e = case fromException exc0 of
+ Just exc -> Just (f exc)
+ _ -> e
+ casters =
+ [Caster (\exc -> ArithException exc),
+ Caster (\exc -> ArrayException exc),
+ Caster (\(New.AssertionFailed err) -> AssertionFailed err),
+ Caster (\exc -> AsyncException exc),
+ Caster (\New.BlockedIndefinitelyOnMVar -> BlockedOnDeadMVar),
+ Caster (\New.BlockedIndefinitelyOnSTM -> BlockedIndefinitely),
+ Caster (\New.NestedAtomically -> NestedAtomically),
+ Caster (\New.Deadlock -> Deadlock),
+ Caster (\exc -> DynException exc),
+ Caster (\(New.ErrorCall err) -> ErrorCall err),
+ Caster (\exc -> ExitException exc),
+ Caster (\exc -> IOException exc),
+ Caster (\(New.NoMethodError err) -> NoMethodError err),
+ Caster (\New.NonTermination -> NonTermination),
+ Caster (\(New.PatternMatchFail err) -> PatternMatchFail err),
+ Caster (\(New.RecConError err) -> RecConError err),
+ Caster (\(New.RecSelError err) -> RecSelError err),
+ Caster (\(New.RecUpdError err) -> RecUpdError err),
+ -- Anything else gets taken as a Dynamic exception. It's
+ -- important that we put all exceptions into the old Exception
+ -- type somehow, or throwing a new exception wouldn't cause
+ -- the cleanup code for bracket, finally etc to happen.
+ Caster (\exc -> DynException (toDyn (exc :: New.SomeException)))]
+
+ -- Unbundle exceptions.
+ toException (ArithException exc) = toException exc
+ toException (ArrayException exc) = toException exc
+ toException (AssertionFailed err) = toException (New.AssertionFailed err)
+ toException (AsyncException exc) = toException exc
+ toException BlockedOnDeadMVar = toException New.BlockedIndefinitelyOnMVar
+ toException BlockedIndefinitely = toException New.BlockedIndefinitelyOnSTM
+ toException NestedAtomically = toException New.NestedAtomically
+ toException Deadlock = toException New.Deadlock
+ -- If a dynamic exception is a SomeException then resurrect it, so
+ -- that bracket, catch+throw etc rethrow the same exception even
+ -- when the exception is in the new style.
+ -- If it's not a SomeException, then just throw the Dynamic.
+ toException (DynException exc) = case fromDynamic exc of
+ Just exc' -> exc'
+ Nothing -> toException exc
+ toException (ErrorCall err) = toException (New.ErrorCall err)
+ toException (ExitException exc) = toException exc
+ toException (IOException exc) = toException exc
+ toException (NoMethodError err) = toException (New.NoMethodError err)
+ toException NonTermination = toException New.NonTermination
+ toException (PatternMatchFail err) = toException (New.PatternMatchFail err)
+ toException (RecConError err) = toException (New.RecConError err)
+ toException (RecSelError err) = toException (New.RecSelError err)
+ toException (RecUpdError err) = toException (New.RecUpdError err)