Post type-checking interface files
Motivation
#14095 proposes we parallelize ghc --make
to start type-checking downstream modules as soon as upstream ones are type checked (as opposed to fully compiled).
But, just doing this for ghc --make
would be yet more drifting apart between the batch and one-shot modes, which is bad because it just increases a very hard to test surface area, and because it unfairly puts ghc --make
alternatives at a disadvantage. [N.B. The ghc --make
code is also quite hairy and the alternatives are in many case more principled implementation which we ought to foster as potential ghc --make
replacements.]
We need file to convey the bare minimum interface of a module that's enough to type-check downstream modules.
Proposal
I think it would be good to write hi-tc
modules in all cases with this information. We already write a regular interface file after type checking for backpack and hs-boot files, during which we can write a sort of "bare minimum" interface file similar to what is doing with no optimization. This would, at a bare minimum, be doing that in all cases. @bgamari points out in !2603 (comment 253208) in however that writing a file twice in one ghc --make
invocation has loads of issues, especially on windows where it cannot be done atomicly.
The better alternative is to just write a different file. This avoids all the race conditions and unportability traps, while also working for build systems which don't do enough sandboxing for file mutation to be transformed into something better. Also, there is already a notion of a ModIface
vs PartialModIface
, which we also may someday wish to expose in the form of multiple files on disk.
Comparison to "fat" or extended dinterface files
#10871 proposes "fat" interface files, containing enough core to resume compilation. !1740 (closed) proposes arbitrary extra information in interface files. This proposal complements writing down more information, as those processes enable. Most build systems don't support "intermediate" build projects in that no dependency consumes the output of a build step until it terminates. In that case, to take advantage of the parallelism #14095 we'd want to write down both the interface, to enable downstream type checking as soon as possible, and module implementation, to be able to resume compilation were we left off in a downstream build step. Crucially, it is still good to keep those in separate files so the downstream modules aren't needlessly rebuilt when the implementation, but not interface, of the upstream module is rebuilt.