packages feed

exceptions 0.10.6 → 0.10.7

raw patch · 3 files changed

+67/−33 lines, 3 filesdep −call-stackdep ~template-haskellPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: call-stack

Dependency ranges changed: template-haskell

API changes (from Hackage documentation)

- Control.Monad.Catch: bracket :: (HasCallStack, MonadMask m) => m a -> (a -> m c) -> (a -> m b) -> m b
+ Control.Monad.Catch: bracket :: HasCallStack => MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b
- Control.Monad.Catch: bracketOnError :: (HasCallStack, MonadMask m) => m a -> (a -> m c) -> (a -> m b) -> m b
+ Control.Monad.Catch: bracketOnError :: HasCallStack => MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b
- Control.Monad.Catch: bracket_ :: (HasCallStack, MonadMask m) => m a -> m c -> m b -> m b
+ Control.Monad.Catch: bracket_ :: HasCallStack => MonadMask m => m a -> m c -> m b -> m b
- Control.Monad.Catch: catch :: (MonadCatch m, HasCallStack, Exception e) => m a -> (e -> m a) -> m a
+ Control.Monad.Catch: catch :: (MonadCatch m, HasCallStack) => Exception e => m a -> (e -> m a) -> m a
- Control.Monad.Catch: catchAll :: (HasCallStack, MonadCatch m) => m a -> (SomeException -> m a) -> m a
+ Control.Monad.Catch: catchAll :: HasCallStack => MonadCatch m => m a -> (SomeException -> m a) -> m a
- Control.Monad.Catch: catchIOError :: (HasCallStack, MonadCatch m) => m a -> (IOError -> m a) -> m a
+ Control.Monad.Catch: catchIOError :: HasCallStack => MonadCatch m => m a -> (IOError -> m a) -> m a
- Control.Monad.Catch: catchIf :: (HasCallStack, MonadCatch m, Exception e) => (e -> Bool) -> m a -> (e -> m a) -> m a
+ Control.Monad.Catch: catchIf :: HasCallStack => (MonadCatch m, Exception e) => (e -> Bool) -> m a -> (e -> m a) -> m a
- Control.Monad.Catch: catchJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
+ Control.Monad.Catch: catchJust :: HasCallStack => (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
- Control.Monad.Catch: catches :: (HasCallStack, Foldable f, MonadCatch m) => m a -> f (Handler m a) -> m a
+ Control.Monad.Catch: catches :: HasCallStack => (Foldable f, MonadCatch m) => m a -> f (Handler m a) -> m a
- Control.Monad.Catch: finally :: (HasCallStack, MonadMask m) => m a -> m b -> m a
+ Control.Monad.Catch: finally :: HasCallStack => MonadMask m => m a -> m b -> m a
- Control.Monad.Catch: handle :: (HasCallStack, MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
+ Control.Monad.Catch: handle :: HasCallStack => (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
- Control.Monad.Catch: handleAll :: (HasCallStack, MonadCatch m) => (SomeException -> m a) -> m a -> m a
+ Control.Monad.Catch: handleAll :: HasCallStack => MonadCatch m => (SomeException -> m a) -> m a -> m a
- Control.Monad.Catch: handleIOError :: (HasCallStack, MonadCatch m) => (IOError -> m a) -> m a -> m a
+ Control.Monad.Catch: handleIOError :: HasCallStack => MonadCatch m => (IOError -> m a) -> m a -> m a
- Control.Monad.Catch: handleIf :: (HasCallStack, MonadCatch m, Exception e) => (e -> Bool) -> (e -> m a) -> m a -> m a
+ Control.Monad.Catch: handleIf :: HasCallStack => (MonadCatch m, Exception e) => (e -> Bool) -> (e -> m a) -> m a -> m a
- Control.Monad.Catch: handleJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
+ Control.Monad.Catch: handleJust :: HasCallStack => (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
- Control.Monad.Catch: mask_ :: (HasCallStack, MonadMask m) => m a -> m a
+ Control.Monad.Catch: mask_ :: HasCallStack => MonadMask m => m a -> m a
- Control.Monad.Catch: onError :: (HasCallStack, MonadMask m) => m a -> m b -> m a
+ Control.Monad.Catch: onError :: HasCallStack => MonadMask m => m a -> m b -> m a
- Control.Monad.Catch: onException :: (HasCallStack, MonadCatch m) => m a -> m b -> m a
+ Control.Monad.Catch: onException :: HasCallStack => MonadCatch m => m a -> m b -> m a
- Control.Monad.Catch: throwM :: (MonadThrow m, HasCallStack, Exception e) => e -> m a
+ Control.Monad.Catch: throwM :: (MonadThrow m, HasCallStack) => Exception e => e -> m a
- Control.Monad.Catch: try :: (HasCallStack, MonadCatch m, Exception e) => m a -> m (Either e a)
+ Control.Monad.Catch: try :: HasCallStack => (MonadCatch m, Exception e) => m a -> m (Either e a)
- Control.Monad.Catch: tryJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
+ Control.Monad.Catch: tryJust :: HasCallStack => (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
- Control.Monad.Catch: uninterruptibleMask_ :: (HasCallStack, MonadMask m) => m a -> m a
+ Control.Monad.Catch: uninterruptibleMask_ :: HasCallStack => MonadMask m => m a -> m a

Files

CHANGELOG.markdown view
@@ -1,3 +1,16 @@+0.10.7 [2022.12.04]
+-------------------
+* On pre-8.0 GHCs, drop the `call-stack` dependency. This dependency was
+  introduced in `exceptions-0.10.6`, but it induced breakage in libraries
+  that derived instances of `MonadThrow`, `MonadCatch`, or `MonadMask` for
+  newtypes without first enabling `ConstraintKinds` and `FlexibleContexts`.
+  (Later versions of GHC do not require these language extensions for derived
+  instances, so only old GHCs were affected.) To avoid breakage, `exceptions`
+  no longer uses `HasCallStack` constraints on pre-8.0 versions of GHC.
+
+  Note that `exceptions` still uses `HasCallStack` constraints on GHC 8.0 and
+  later, and as a result, these versions of GHC are unaffected by this change.
+
 0.10.6 [2022.11.30]
 -------------------
 * The class methods and functions in `Control.Monad.Catch` now have
exceptions.cabal view
@@ -1,6 +1,6 @@ name:          exceptions
 category:      Control, Exceptions, Monad
-version:       0.10.6
+version:       0.10.7
 cabal-version: >= 1.10
 license:       BSD3
 license-file:  LICENSE
@@ -51,8 +51,7 @@     mtl                        >= 2.0      && < 2.4
 
   if !impl(ghc >= 8.0)
-    build-depends: call-stack  >= 0.1      && < 0.5,
-                   fail        == 4.9.*
+    build-depends: fail        == 4.9.*
 
   if flag(transformers-0-4)
     build-depends:
src/Control/Monad/Catch.hs view
@@ -1,7 +1,5 @@-{-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -121,8 +119,6 @@ 
 #if __GLASGOW_HASKELL__ >= 800
 import GHC.Stack (HasCallStack, withFrozenCallStack)
-#else
-import Data.CallStack (HasCallStack)
 #endif
 
 #if !(MIN_VERSION_transformers(0,6,0))
@@ -130,7 +126,33 @@ import Control.Monad.Trans.List (ListT(..), runListT)
 #endif
 
-#if __GLASGOW_HASKELL__ < 800
+-- We use the following bit of CPP to enable the use of HasCallStack
+-- constraints without breaking the build for pre-8.0 GHCs, which did not
+-- provide GHC.Stack. We are careful to always write constraints like this:
+--
+--   HAS_CALL_STACK => MonadThrow m => ...
+--
+-- Instead of like this:
+--
+--   (HAS_CALL_STACK, MonadThrow e) => ...
+--
+-- The latter is equivalent to (() :: Constraint, MonadThrow e) => ..., which
+-- requires ConstraintKinds. More importantly, it's slightly less efficient,
+-- since it requires passing an empty constraint tuple dictionary around.
+--
+-- Note that we do /not/ depend on the call-stack compatibility library to
+-- provide HasCallStack on older GHCs. We tried this at one point, but we
+-- discovered that downstream libraries failed to build because combining
+-- call-stack with GeneralizedNewtypeDeriving on older GHCs would require the
+-- use of ConstraintKinds/FlexibleContexts, which downstream libraries did not
+-- enable. (See #91.) The CPP approach that we use now, while somewhat clunky,
+-- avoids these issues by not requiring any additional language extensions for
+-- downstream users.
+#if __GLASGOW_HASKELL__ >= 800
+# define HAS_CALL_STACK HasCallStack
+#else
+# define HAS_CALL_STACK ()
+
 withFrozenCallStack :: a -> a
 withFrozenCallStack a = a
 #endif
@@ -156,7 +178,7 @@   -- Should satisfy the law:
   --
   -- > throwM e >> f = throwM e
-  throwM :: (HasCallStack, Exception e) => e -> m a
+  throwM :: HAS_CALL_STACK => Exception e => e -> m a
 
 -- | A class for monads which allow exceptions to be caught, in particular
 -- exceptions which were thrown by 'throwM'.
@@ -176,7 +198,7 @@   -- action. Note that type of the type of the argument to the handler will
   -- constrain which exceptions are caught. See "Control.Exception"'s
   -- 'ControlException.catch'.
-  catch :: (HasCallStack, Exception e) => m a -> (e -> m a) -> m a
+  catch :: HAS_CALL_STACK => Exception e => m a -> (e -> m a) -> m a
 
 -- | A class for monads which provide for the ability to account for
 -- all possible exit points from a computation, and to mask
@@ -217,7 +239,7 @@   -- | Runs an action with asynchronous exceptions disabled. The action is
   -- provided a method for restoring the async. environment to what it was
   -- at the 'mask' call. See "Control.Exception"'s 'ControlException.mask'.
-  mask :: HasCallStack => ((forall a. m a -> m a) -> m b) -> m b
+  mask :: HAS_CALL_STACK => ((forall a. m a -> m a) -> m b) -> m b
 
   -- | Like 'mask', but the masked computation is not interruptible (see
   -- "Control.Exception"'s 'ControlException.uninterruptibleMask'. WARNING:
@@ -225,7 +247,7 @@   -- AND you can guarantee the interruptible operation will only block for a
   -- short period of time. Otherwise you render the program/thread unresponsive
   -- and/or unkillable.
-  uninterruptibleMask :: HasCallStack => ((forall a. m a -> m a) -> m b) -> m b
+  uninterruptibleMask :: HAS_CALL_STACK => ((forall a. m a -> m a) -> m b) -> m b
 
   -- | A generalized version of 'bracket' which uses 'ExitCase' to distinguish
   -- the different exit cases, and returns the values of both the 'use' and
@@ -318,7 +340,7 @@   --
   -- @since 0.9.0
   generalBracket
-    :: HasCallStack
+    :: HAS_CALL_STACK
     => m a
     -- ^ acquire some resource
     -> (a -> ExitCase b -> m c)
@@ -747,12 +769,12 @@ ------------------------------------------------------------------------------
 
 -- | Like 'mask', but does not pass a @restore@ action to the argument.
-mask_ :: (HasCallStack, MonadMask m) => m a -> m a
+mask_ :: HAS_CALL_STACK => MonadMask m => m a -> m a
 mask_ io = withFrozenCallStack (\f -> mask (\x -> f x)) (\_ -> io)
 
 -- | Like 'uninterruptibleMask', but does not pass a @restore@ action to the
 -- argument.
-uninterruptibleMask_ :: (HasCallStack, MonadMask m) => m a -> m a
+uninterruptibleMask_ :: HAS_CALL_STACK => MonadMask m => m a -> m a
 uninterruptibleMask_ io = withFrozenCallStack (\f -> uninterruptibleMask (\x -> f x)) (\_ -> io)
 
 -- | Catches all exceptions, and somewhat defeats the purpose of the extensible
@@ -760,57 +782,57 @@ --
 -- /NOTE/ This catches all /exceptions/, but if the monad supports other ways of
 -- aborting the computation, those other kinds of errors will not be caught.
-catchAll :: (HasCallStack, MonadCatch m) => m a -> (SomeException -> m a) -> m a
+catchAll :: HAS_CALL_STACK => MonadCatch m => m a -> (SomeException -> m a) -> m a
 catchAll = withFrozenCallStack catch
 
 -- | Catch all 'IOError' (eqv. 'IOException') exceptions. Still somewhat too
 -- general, but better than using 'catchAll'. See 'catchIf' for an easy way
 -- of catching specific 'IOError's based on the predicates in "System.IO.Error".
-catchIOError :: (HasCallStack, MonadCatch m) => m a -> (IOError -> m a) -> m a
+catchIOError :: HAS_CALL_STACK => MonadCatch m => m a -> (IOError -> m a) -> m a
 catchIOError = withFrozenCallStack catch
 
 -- | Catch exceptions only if they pass some predicate. Often useful with the
 -- predicates for testing 'IOError' values in "System.IO.Error".
-catchIf :: (HasCallStack, MonadCatch m, Exception e) =>
+catchIf :: HAS_CALL_STACK => (MonadCatch m, Exception e) =>
     (e -> Bool) -> m a -> (e -> m a) -> m a
 catchIf f a b = withFrozenCallStack catch a (\e -> if f e then b e else throwM e)
 
 -- | A more generalized way of determining which exceptions to catch at
 -- run time.
-catchJust :: (HasCallStack, MonadCatch m, Exception e) =>
+catchJust :: HAS_CALL_STACK => (MonadCatch m, Exception e) =>
     (e -> Maybe b) -> m a -> (b -> m a) -> m a
 catchJust f a b = withFrozenCallStack catch a (\e -> maybe (throwM e) b $ f e)
 
 -- | Flipped 'catch'. See "Control.Exception"'s 'ControlException.handle'.
-handle :: (HasCallStack, MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
+handle :: HAS_CALL_STACK => (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
 handle = flip (withFrozenCallStack catch)
 {-# INLINE handle #-}
 
 -- | Flipped 'catchIOError'
-handleIOError :: (HasCallStack, MonadCatch m) => (IOError -> m a) -> m a -> m a
+handleIOError :: HAS_CALL_STACK => MonadCatch m => (IOError -> m a) -> m a -> m a
 handleIOError = withFrozenCallStack handle
 
 -- | Flipped 'catchAll'
-handleAll :: (HasCallStack, MonadCatch m) => (SomeException -> m a) -> m a -> m a
+handleAll :: HAS_CALL_STACK => MonadCatch m => (SomeException -> m a) -> m a -> m a
 handleAll = withFrozenCallStack handle
 
 -- | Flipped 'catchIf'
-handleIf :: (HasCallStack, MonadCatch m, Exception e) => (e -> Bool) -> (e -> m a) -> m a -> m a
+handleIf :: HAS_CALL_STACK => (MonadCatch m, Exception e) => (e -> Bool) -> (e -> m a) -> m a -> m a
 handleIf f = flip (withFrozenCallStack catchIf f)
 
 -- | Flipped 'catchJust'. See "Control.Exception"'s 'ControlException.handleJust'.
-handleJust :: (HasCallStack, MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
+handleJust :: HAS_CALL_STACK => (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
 handleJust f = flip (withFrozenCallStack catchJust f)
 {-# INLINE handleJust #-}
 
 -- | Similar to 'catch', but returns an 'Either' result. See "Control.Exception"'s
 -- 'Control.Exception.try'.
-try :: (HasCallStack, MonadCatch m, Exception e) => m a -> m (Either e a)
+try :: HAS_CALL_STACK => (MonadCatch m, Exception e) => m a -> m (Either e a)
 try a = withFrozenCallStack catch (Right `liftM` a) (return . Left)
 
 -- | A variant of 'try' that takes an exception predicate to select
 -- which exceptions are caught. See "Control.Exception"'s 'ControlException.tryJust'
-tryJust :: (HasCallStack, MonadCatch m, Exception e) =>
+tryJust :: HAS_CALL_STACK => (MonadCatch m, Exception e) =>
     (e -> Maybe b) -> m a -> m (Either b a)
 tryJust f a = withFrozenCallStack catch (Right `liftM` a) (\e -> maybe (throwM e) (return . Left) (f e))
 
@@ -821,7 +843,7 @@   fmap f (Handler h) = Handler (liftM f . h)
 
 -- | Catches different sorts of exceptions. See "Control.Exception"'s 'ControlException.catches'
-catches :: (HasCallStack, Foldable f, MonadCatch m) => m a -> f (Handler m a) -> m a
+catches :: HAS_CALL_STACK => (Foldable f, MonadCatch m) => m a -> f (Handler m a) -> m a
 catches a hs = withFrozenCallStack catch a handler
   where
     handler e = foldr probe (throwM e) hs
@@ -834,7 +856,7 @@ -- /NOTE/ The action is only run if an /exception/ is thrown. If the monad
 -- supports other ways of aborting the computation, the action won't run if
 -- those other kinds of errors are thrown. See 'onError'.
-onException :: (HasCallStack, MonadCatch m) => m a -> m b -> m a
+onException :: HAS_CALL_STACK => MonadCatch m => m a -> m b -> m a
 onException action handler = withFrozenCallStack catchAll action (\e -> handler >> throwM e)
 
 -- | Run an action only if an error is thrown in the main action. Unlike
@@ -848,7 +870,7 @@ -- except that 'onError' has a more constrained type.
 --
 -- @since 0.10.0
-onError :: (HasCallStack, MonadMask m) => m a -> m b -> m a
+onError :: HAS_CALL_STACK => MonadMask m => m a -> m b -> m a
 onError action handler = withFrozenCallStack bracketOnError (return ()) (const handler) (const action)
 
 -- | Generalized abstracted pattern of safe resource acquisition and release
@@ -864,24 +886,24 @@ -- signature from "Control.Exception"), and is often more convenient to use. By
 -- contrast, 'generalBracket' is more expressive, allowing us to implement
 -- other functions like 'bracketOnError'.
-bracket :: (HasCallStack, MonadMask m) => m a -> (a -> m c) -> (a -> m b) -> m b
+bracket :: HAS_CALL_STACK => MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b
 bracket acquire release = liftM fst . withFrozenCallStack generalBracket
   acquire
   (\a _exitCase -> release a)
 
 -- | Version of 'bracket' without any value being passed to the second and
 -- third actions.
-bracket_ :: (HasCallStack, MonadMask m) => m a -> m c -> m b -> m b
+bracket_ :: HAS_CALL_STACK => MonadMask m => m a -> m c -> m b -> m b
 bracket_ before after action = withFrozenCallStack bracket before (const after) (const action)
 
 -- | Perform an action with a finalizer action that is run, even if an
 -- error occurs.
-finally :: (HasCallStack, MonadMask m) => m a -> m b -> m a
+finally :: HAS_CALL_STACK => MonadMask m => m a -> m b -> m a
 finally action finalizer = withFrozenCallStack bracket_ (return ()) finalizer action
 
 -- | Like 'bracket', but only performs the final action if an error is
 -- thrown by the in-between computation.
-bracketOnError :: (HasCallStack, MonadMask m) => m a -> (a -> m c) -> (a -> m b) -> m b
+bracketOnError :: HAS_CALL_STACK => MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b
 bracketOnError acquire release = liftM fst . withFrozenCallStack generalBracket
   acquire
   (\a exitCase -> case exitCase of