[GHC] #13423: Exception to I/O hack in demand analyzer too broad
GHC
ghc-devs at haskell.org
Tue Mar 14 03:09:33 UTC 2017
#13423: Exception to I/O hack in demand analyzer too broad
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.4.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:
-------------------------------------+-------------------------------------
The I/O hack in the demand analyzer triggers only for expressions that are
not direct applications of primops (see `io_hack_reqd` in
`stranal/DmdAnal.hs`). This seems rather arbitrary, and can produce
surprising results. Consider
{{{#!hs
fish :: Int -> IORef Int -> IORef Int -> IO ()
fish n ref next = do
writeIORef ref n
writeIORef next n
x <- getLine
case readMaybe x of
Just True -> fish (n + 1) ref next
_ -> pure ()
}}}
If `next` is bottom, I would expect this to write `n` to `ref` and then
throw an exception. But we actually get something else. First, the demand
signature for `fish` ends up being
`Str=<L,U(U)><S(S),1*U(U)><S(S),1*U(U)><S,U>`, which seems wrong. Then, as
a result, worker/wrapper produces a wrapper that immediately unboxes both
`IORef`s, so this is operationally wrong.
Why do I think this is wrong? The story Haskell users are told, over and
over, is that evaluation is driven only by execution; that we never force
anything unless we need its value to determine the next `IO` action. That
principle is violated here.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13423>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list