Skip to content

Make unsafeDupablePerformIO have a lazy demand

Andreas Klebinger requested to merge wip/andreask/runRW_fix into master

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.

Edited by Andreas Klebinger

Merge request reports