Make unsafeDupablePerformIO have a lazy demand
When a user writes code like:
unsafePerformIO $ do
let x = f x
writeIORef ref x
return x
We might expect that the write happens before we evaluate f x
.
Sadly this wasn't to case for reasons detailed in #19181 (closed).
We fix this by avoiding the strict demand by turning:
unsafeDupablePerformIO (IO m) = case runRW# m of (# _, a #) -> a
into
unsafeDupablePerformIO (IO m) = case runRW# m of (# _, a #) -> lazy a
This makes the above code lazy in x. And ensures the side effect of the
write happens before the evaluation of f x
. If a user wants the code
to be strict on the returned value he can simply use return $! x
.
This fixes #19181 (closed).
To get the "old" (current HEAD) behaviour back a user can simply use return $! instead of return.
But with this patch strictness should behave as it did in 8.10.