Dependency interface change not detected.
I have two modules: Main and Library. Library is a dependency of Main. Library has two data definitions: A and B, which are co-dependent. Main calls a value called info of type A, declared in Library, and prints it.
main.hs:
module Main where
import Library
main = putStrLn $ show info
library.hs:
module Library where
data A = ARecu B | ABase String deriving (Show)
data B = BRecu A | BBase Int deriving (Show)
info :: B
info = BBase 1
I compile with the command ghc -o main library.hs main.hs
and then run ./main
. Everything works fine.
The problem is when I rewrite info to a value of type B, as follows:
main.hs:
module Main where
import Library
main = putStrLn $ show info
library.hs:
module Library where
data A = ARecu B | ABase String deriving (Show)
data B = BRecu A | BBase Int deriving (Show)
info :: A
info = ABase "Hello"
After recompiling with ghc -o main library.hs main.hs
, and then running ./main
, trash is printed, or a segfault happens, basically just undefined behavior.
Observations
When I recompile, only Library is recompiled, not Main. This doesn't make sense. Since the interface of a dependency of Main changed, it should also recompile. I suspect something's wrong with ghc's dependency manager, since it should infer Main has to be recompiled.
Since Main isn't recompiled, it's trying to call a Show instance of type A over a type B. This causes the undefined behavior.
Weirdly enough, this bug only happens when I use co-dependent data, like A and B. If I take that away, say:
data A = ARecu B | ABase String deriving (Show)
data B = BBase Int deriving (Show)
recompilation now works fine. Main is recompiled, and everything runs as it should. Maybe the bug is somewhere near there.