
#13380: raiseIO# result looks wrong -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Other Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- `primops.txt.pp` includes the following note:
`raiseIO#` needs to be a primop, because exceptions in the `IO` monad must be ''precise'' - we don't want the strictness analyser turning one kind of bottom into another, as it is allowed to do in pure code.
But we ''do'' want to know that it returns bottom after being applied to two arguments, so that this function is strict in `y` {{{#!hs f x y | x>0 = raiseIO blah | y>0 = return 1 | otherwise = return 2 }}}
I believe the "But we do" portion is, unfortunately, entirely wrong. From a user perspective, it is extremely strange to replace a precise exception with an imprecise one. That is, I strongly believe the above code should be considered ''lazy'' in `y`. The function `f` calculates an `IO` action; the value of `y` is only necessary to calculate that action if `x` is non- positive. We can, conservatively, say for certain that the second component of the result of `raiseIO#` (i.e., the "return value") is bottom. We can also say, given {{{#!hs case raiseIO# e s of (# s', r #) -> q }}} that `q` is dead (we could replace it by `(# s', undefined #)`). -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13380 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler