Skip to content

Deal with fallout of Int{8,16,32}/Word{8,16,32}-related changes on GHC HEAD

Commit ghc@be5d74ca changed the types of several primitive data constructors. Before that commit, we had:

I8#  :: Int# -> Int8
I16# :: Int# -> Int16
I32# :: Int# -> Int32

W8#  :: Word# -> Word8
W16# :: Word# -> Word16
W32# :: Word# -> Word32

After that commit, we now have:

I8#  :: Int8#  -> Int8
I16# :: Int16# -> Int16
I32# :: Int32# -> Int32

W8#  :: Word8#  -> Word8
W16# :: Word16# -> Word16
W32# :: Word32# -> Word32

Unsurprisingly, this breaks a lot of code in the wild. Two of the more widely used libraries that are broken by this change include primitive and basement.

If we want to fix this now, one option is to sprinkle uses of {extend,narrow}{Int,Word}{8,16,32}# throughout the code to convert from {Int,Word}# to {Int,Word}{8,16,32}# and vice versa. (See ghc/packages/text@f1a2e141 for an example.) This leads to quite a lot of churn, however. Indeed, in some places I wonder if this churn is even justified. Here is an actual line of code that I found changing in the primitive library in order to fix a type error:

-indexByteArray# arr# i# = I8# (index8Array# arr# i#)
+indexByteArray# arr# i# = I8# (narrowInt8# (index8Array# arr# i#))

This is because the type of index8Array#, before and after commit ghc@be5d74ca, is:

indexInt8Array# :: ByteArray# -> Int# -> Int#

However, if this type reflected its intended purpose a little better:

indexInt8Array# :: ByteArray# -> Int# -> Int8#

Then I wouldn't need to change the line of code above at all, which would save me quite a bit of effort. @angerman indicated to me (in IRC correspondence) that such a change is in the works (I don't recall if there is a GHC issue open about this already), but it may take some time before it materializes. It may be best to just charge ahead and patch Hackage libraries in the meantime, which I have started to do in !130 (merged).