Skip to content

-fbyte-code-and-object-code does not overwrite the existing hi file

Summary

with -fbyte-code-and-object-code, GHC is supposed to make .hi files with serialized simplified core in extra decls field. But if there exists a .hi file from a previous compilation without the flag somehow, then the compilation with the flag keeps interpreting the module, but does not change the interface file.

This makes users confused since it triggers a big recompilation which does not go away. The only way to restore a normal recompilation behavior is to clean the build directory.

Steps to reproduce

A.hs

module A where

testA :: IO ()
testA = pure ()

B.hs

module B where

import A

testB :: IO ()
testB = testA
$ ghc A B
[1 of 2] Compiling A                ( A.hs, A.o )
[2 of 2] Compiling B                ( B.hs, B.o )

$ ghc A B -fbyte-code-and-object-code 
[1 of 2] Compiling A                ( A.hs, A.o, interpreted ) [Missing bytecode]
[2 of 2] Compiling B                ( B.hs, B.o, interpreted ) [Missing bytecode]

(change B)
$ ghc A B -fbyte-code-and-object-code 
[1 of 2] Compiling A                ( A.hs, A.o, interpreted ) [Missing bytecode]
[2 of 2] Compiling B                ( B.hs, B.o, interpreted ) [Source file changed]

A is being recompiled.

Expected behavior

In the second step, A.hi should be regenerated with simplified core. After cleaning *.hi, and recompile with the flag

$ ghc --show-iface A.hi
...
extra decls:
  $trModule = GHC.Types.Module $trModule2 $trModule4
  $trModule1 = "main"#
  $trModule2 = GHC.Types.TrNameS $trModule1
  $trModule3 = "A"#
  $trModule4 = GHC.Types.TrNameS $trModule3
  testA = GHC.Base.pure
            @GHC.Types.IO
            GHC.Base.$fApplicativeIO
            @()
            GHC.Tuple.Prim.()
...

Environment

  • GHC version used: 9.6.2, 9.8.1, 9.9.20231107 (master)
  • Operating System: macOS 14.1
  • System Architecture: AArch64
Edited by Ian-Woo Kim
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information