
#13099: recompilation can fail to recheck type family instance consistency -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- 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 {{{#!hs 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: 1. Since `M.hi` represents a certificate of consistency between `I1` and `I2`, `M` should be considered to "use" the family instances so that it is recompiled when the instances change. 2. 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` and `I2` that were checked for consistency when we compiled `M` are the same ones that we are importing in our client of `M`. 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. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13099 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler