Orphan hashes are not being propagated correctly
In D2607, simonpj asked why we didn't also put class instances in the export hash. Why indeed. In the course of investigating, I discovered another bug in how we handle orphan recompilation.
Unfortunately, this bug needs two packages to manifest.
-- p/P.hs module P where instance Show (a -> b) where --instance Show (IO a) where -- q/Q.hs module Q where import P -- q/Q2.hs module Q2 where import Q
Put in some default Cabal files, with q depending on p, and then build the entire kaboodle. Then edit
p/P.hs to uncomment the second orphan instance. Rebuild.
ezyang@sabre:~/Dev/labs/orph$ cabal new-build q -w ghc-head In order, the following will be built (use -v for more details): - p-0.1.0.0 (lib) (file P.hs changed) - q-0.1.0.0 (lib) (dependency rebuilt) Preprocessing library p-0.1.0.0... [1 of 1] Compiling P ( P.hs, /srv/code/labs/orph/dist-newstyle/build/x86_64-linux/ghc-8.1.20161016/p-0.1.0.0/build/P.o ) P.hs:2:10: warning: [-Wmissing-methods] • No explicit implementation for either ‘showsPrec’ or ‘show’ • In the instance declaration for ‘Show (a -> b)’ P.hs:3:10: warning: [-Wmissing-methods] • No explicit implementation for either ‘showsPrec’ or ‘show’ • In the instance declaration for ‘Show (IO a)’ module Q2 where Preprocessing library q-0.1.0.0... [1 of 2] Compiling Q ( Q.hs, /srv/code/labs/orph/dist-newstyle/build/x86_64-linux/ghc-8.1.20161016/q-0.1.0.0/build/Q.o ) [P changed] ezyang@sabre:~/Dev/labs/orph$
Notice: Q2 never got rebuilt. This is wrong wrong wrong: P changed, and we need to rebuild Q2!
Here are the hashes for Q.hi before and after:
-- Before interface Q 80120161016 interface hash: 2ffc06a1552565a73c888110ab4cf8df ABI hash: b2768862866252ea5a63401d2aa05aaa export-list hash: 092acc280445a8bcc96904afb8b766b0 orphan hash: 693e9af84d3dfcc71e640e005bdc5e2e flag hash: f01bb78d3c47152bc5253f256b2a60d3 -- After interface Q 80120161016 interface hash: 009db9e5ecbe49e36b7bf38e02087e75 ABI hash: b2768862866252ea5a63401d2aa05aaa export-list hash: 092acc280445a8bcc96904afb8b766b0 orphan hash: 693e9af84d3dfcc71e640e005bdc5e2e flag hash: f01bb78d3c47152bc5253f256b2a60d3
The ABI hash didn't get updated.
At the moment, when we compute the export hash, we only consider the orphan hashes from the home package. Here's the comment justifying it:
-- the export hash of a module depends on the orphan hashes of the -- orphan modules below us in the dependency tree. This is the way -- that changes in orphans get propagated all the way up the -- dependency tree. We only care about orphan modules in the current -- package, because changes to orphans outside this package will be -- tracked by the usage on the ABI hash of package modules that we import.
It is true that we know to rebuild Q.hs when P.hs changes. But that is not much solace for Q2.hs...