Precise exceptions: `stToIO` and `ioToST` can circumvent analysis in Note [Which scrutinees may throw precise exceptions]
Summary
The analysis described in Note [Which scrutinees may throw precise exceptions]
is oblivious wrt. computations in forall s. ... State# s ...
, even though it triggers for its instance State# RealWorld#
.
This means we can circumvent the analysis by defining most of the code in ST s r
, parameterising over computations that are actually in IO
,
and then run the supposedly pure ST s r
computation with those impure IO
actions supplied as parameters.
Steps to reproduce:
Compile and run with -O:
import GHC.IO
import GHC.ST
foo :: Int -> ST s r -> ST s Int
foo a act = act >> (pure $! a+1)
{-# NOINLINE foo #-}
main = stToIO $ foo (error "Not OK") (ioToST (throwIO (mkUserError "OK")))
test: Not OK
Expected behavior
test: user error (OK)
Discussion
It is questionable whether this is actually desirable. Potentially, the performance of every morally pure ST s a
computation such as foo
might be affected for the worse: We may not ever use call-by-value for foo
, unless it forces a
before calling act
.
I'm inclined to simply ignore this issue.
(CC) @clyring and @simonpj with whom I discussed this issue today.