diff options
author | David Feuer <david.feuer@gmail.com> | 2017-11-02 12:06:56 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-11-02 13:20:26 -0400 |
commit | b938576d151731b85314987fc550c17cfe824178 (patch) | |
tree | 3cda2f27bd490c45cfad3f231e1e0be183cb53a4 | |
parent | e0df569f7619dbef266139b9a6fa3ee9f632ea6e (diff) | |
download | haskell-b938576d151731b85314987fc550c17cfe824178.tar.gz |
Add custom exception for fixIO
Traditionally, `fixIO f` throws `BlockedIndefinitelyOnMVar` if
`f` is strict. This is not particularly friendly, since the
`MVar` in question is just part of the way `fixIO` happens to be
implemented. Instead, throw a new `FixIOException` with a better
explanation of the problem.
Reviewers: austin, hvr, bgamari
Subscribers: rwbarton, thomie
GHC Trac Issues: #14356
Differential Revision: https://phabricator.haskell.org/D4113
-rw-r--r-- | libraries/base/Control/Exception/Base.hs | 1 | ||||
-rw-r--r-- | libraries/base/GHC/IO/Exception.hs | 10 | ||||
-rw-r--r-- | libraries/base/System/IO.hs | 7 | ||||
-rw-r--r-- | testsuite/tests/mdo/should_fail/mdofail006.stderr | 2 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_compile/holes2.stderr | 2 |
5 files changed, 19 insertions, 3 deletions
diff --git a/libraries/base/Control/Exception/Base.hs b/libraries/base/Control/Exception/Base.hs index a15cc8ed32..d443159cb3 100644 --- a/libraries/base/Control/Exception/Base.hs +++ b/libraries/base/Control/Exception/Base.hs @@ -30,6 +30,7 @@ module Control.Exception.Base ( NonTermination(..), NestedAtomically(..), BlockedIndefinitelyOnMVar(..), + FixIOException (..), BlockedIndefinitelyOnSTM(..), AllocationLimitExceeded(..), CompactionFailed(..), diff --git a/libraries/base/GHC/IO/Exception.hs b/libraries/base/GHC/IO/Exception.hs index 9203f46828..020bc067df 100644 --- a/libraries/base/GHC/IO/Exception.hs +++ b/libraries/base/GHC/IO/Exception.hs @@ -33,6 +33,7 @@ module GHC.IO.Exception ( ArrayException(..), ExitCode(..), + FixIOException (..), ioException, ioError, @@ -268,6 +269,15 @@ instance Show ArrayException where . (if not (null s) then showString ": " . showString s else id) +-- | @since TODO +data FixIOException = FixIOException + +-- | @since TODO +instance Exception FixIOException + +instance Show FixIOException where + showsPrec _ FixIOException = showString "cyclic evaluation in fixIO" + -- ----------------------------------------------------------------------------- -- The ExitCode type diff --git a/libraries/base/System/IO.hs b/libraries/base/System/IO.hs index fde5bb66e5..68817247d2 100644 --- a/libraries/base/System/IO.hs +++ b/libraries/base/System/IO.hs @@ -400,10 +400,15 @@ withBinaryFile name mode = bracket (openBinaryFile name mode) hClose -- --------------------------------------------------------------------------- -- fixIO +-- | The implementation of 'mfix' for 'IO'. If the function passed +-- to 'fixIO' inspects its argument, the resulting action will throw +-- 'FixIOException'. fixIO :: (a -> IO a) -> IO a fixIO k = do m <- newEmptyMVar - ans <- unsafeDupableInterleaveIO (readMVar m) + ans <- unsafeDupableInterleaveIO + (readMVar m `catch` \BlockedIndefinitelyOnMVar -> + throwIO FixIOException) result <- k ans putMVar m result return result diff --git a/testsuite/tests/mdo/should_fail/mdofail006.stderr b/testsuite/tests/mdo/should_fail/mdofail006.stderr index ea186c0076..e2cf503df7 100644 --- a/testsuite/tests/mdo/should_fail/mdofail006.stderr +++ b/testsuite/tests/mdo/should_fail/mdofail006.stderr @@ -1 +1 @@ -mdofail006: thread blocked indefinitely in an MVar operation +mdofail006: cyclic evaluation in fixIO diff --git a/testsuite/tests/typecheck/should_compile/holes2.stderr b/testsuite/tests/typecheck/should_compile/holes2.stderr index d7484fa142..fd3073d377 100644 --- a/testsuite/tests/typecheck/should_compile/holes2.stderr +++ b/testsuite/tests/typecheck/should_compile/holes2.stderr @@ -9,7 +9,7 @@ holes2.hs:3:5: warning: [-Wdeferred-type-errors (in -Wdefault)] instance Show Ordering -- Defined in ‘GHC.Show’ instance Show Integer -- Defined in ‘GHC.Show’ ...plus 23 others - ...plus 61 instances involving out-of-scope types + ...plus 62 instances involving out-of-scope types (use -fprint-potential-instances to see them all) • In the expression: show _ In an equation for ‘f’: f = show _ |