Skip to content

Inlining prevents evaluation of ignored parts of unboxed tuples

Consider the following code:

{-# LANGUAGE MagicHash, UnboxedTuples #-}
import GHC.IO (IO (..))
import GHC.Prim

writeB :: MutableArray# RealWorld Char -> IO ()
writeB arr# =
    IO $ \s0# ->
        (# writeArray# arr# 0# 'B' s0#, () #)

inlineWriteB :: MutableArray# RealWorld Char -> ()
inlineWriteB arr# =
    case f realWorld# of
        (# _, x #) -> x
  where
    IO f = writeB arr#

test :: IO Char
test = IO $ \s0# ->
  case newArray# 1# 'A' s0# of
    (# s1#, arr# #) ->
      case seq# (inlineWriteB arr#) s1# of
        (# s2#, () #) ->
          readArray# arr# 0# s2#

main :: IO ()
main = test >>= print

I would expect this code to output the letter 'B'. When compiled without optimizations, that's exactly what it does. However, with optimizations turned on, it seems that it decides that, in inlineWriteB, the state value does not need to be evaluated, which results in the writeArray# call never occurring.

This affected me when working with the vector and primitive packages. I believe I have a workaround in place (see https://github.com/haskell/primitive/pull/11), but this should probably be fixed in GHC as well.

Trac metadata
Trac field Value
Version 7.8.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information