Backpack insufficiently thins interfaces when recompiling
The backpack test bkp44 started failing in the implementaiton of !8995 (closed), which provides stronger determinism guarantees for when interface files are loaded. It turns out that this revealed a latent issue in the recompilation checking logic of backpack.
Here is a modified version of bkp44 which works with cabal - bkp44-b.zip
For reference, the equivalent .bkp
:
unit p where
signature A where
data T
signature B where
import A
y :: T
unit q where
dependency signature p[A=<C>,B=<D>]
signature C () where
signature D () where
The first time you build bkp44-b
, the build works fine.
If you modify B.hsig
to add anything, say e :: Bool
, and run cabal build
again, then you get a recompilation error:
Resolving dependencies...
Build profile: -w ghc-9.2.2 -O1
In order, the following will be built (use -v for more details):
- bkp44-b-0.1.0.0 (lib:p) (configuration changed)
- bkp44-b-0.1.0.0 (lib:q) (configuration changed)
Configuring library 'p' for bkp44-b-0.1.0.0..
Preprocessing library 'p' for bkp44-b-0.1.0.0..
Building library 'p' instantiated with
A = <A>
B = <B>
for bkp44-b-0.1.0.0..
Configuring library 'q' for bkp44-b-0.1.0.0..
Preprocessing library 'q' for bkp44-b-0.1.0.0..
Building library 'q' instantiated with
C = <C>
D = <D>
for bkp44-b-0.1.0.0..
<no location info>: error:
The identifier T does not exist in the signature for <C>
(Try adding it to the export list in that hsig file.)
If you turn on -ddump-if-trace
, then you see B.hi
is loaded to check if the hash is the same as before.
Reading interface for bkp44-b-0.1.0.0-inplace-p:B;
reason: need version info for B
readIFace /home/matt/Downloads/bkp44b/dist-newstyle/build/x86_64-linux/ghc-9.2.2/bkp44-b-0.1.0.0/l/p/build/p/B.hi
and then the error comes from computeInterface
which attempts to rename the interface for B
because B
is instantiated to D
.
In order to properly thin the module you need to know the exports of module D
and apply that before the renaming happens (so we don't try to rename y
and hence T
, which are not part of the thinning). However it's not clear when loading the interface to check the hash of B how to determine what the exports of D are.. we haven't committed to compiling D yet and don't know if the interface is up to date.