recompilation can fail to recheck type family instance consistency
Suppose I have two modules I1
and I2
that define instances for the same type family and I have a module M
consisting solely of
module M where
import I1
import I2
When GHC compiles M
it checks that the type family instances of I1
are consistent with those from I2
. Then it writes out M.hi
which is treated as a certificate that the type family instances of I1
and I2
are compatible:
How do we know which pairs of modules have already been checked? Any pair of
modules where both modules occur in the `HscTypes.dep_finsts' set (of the
`HscTypes.Dependencies') of one of our directly imported modules must have
already been checked. Everything else, we check now. (So that we can be
certain that the modules in our `HscTypes.dep_finsts' are consistent.)
That means in particular that another module that imports M
doesn't have to check family instance consistency between I1
and I2
. (Imagine I1
and I2
are two internal modules of a library and M
is its top-level interface that just re-exports things.)
Now suppose I edit I2
in a way that makes its type family instances no longer consistent with those of I1
, then recompile I2
and then M
in one-shot mode. Since M
did not really use anything from I2
, ghc concludes that recompilation of M
is not required. But now the M.hi
file is incorrect as a certificate that I1
and I2
have consistent instances and a consumer of M
would be able to see the inconsistency even if it uses parts of I1
and I2
that changed.
Two possible ways to address this:
- Since
M.hi
represents a certificate of consistency betweenI1
andI2
,M
should be considered to "use" the family instances so that it is recompiled when the instances change. - When determining which pairs of modules we don't need to check for consistency in FamInst, we take some interface hash into account to make sure that the versions of (in this case)
I1
andI2
that were checked for consistency when we compiledM
are the same ones that we are importing in our client ofM
.
I think we might want both of these, but especially the second one. This might ideally involve adding a "type family instances hash" to the interface file if it doesn't already exist.
Trac metadata
Trac field | Value |
---|---|
Version | 8.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |