For various package reorganization purposes, especially for possibly turning base into a shim package that re-exports some modules from more specialized packages, good support for module re-exports would be nice.
I wrote up a design spec at ModuleReexports; this bug is to track the progress.
Trac metadata
Trac field
Value
Version
7.6.3
Type
FeatureRequest
TypeOfFailure
OtherFailure
Priority
normal
Resolution
Unresolved
Component
Package system
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
I’ll open appropriate tickets against Cabal and haddock if there is consensus that the proposal is useful and the syntax and semantics are agreed on – currently, this is just a draft.
Hello nomeata, are you still working on this? This is on the hotpath for Backpack implementation work so I will probably go ahead and implement this if you are not working on it.
Here is an annoying problem for implementing this functionality.
Module reexports should roughly be analogous to how we deal with type/declaration reexports at the Haskell source level. To briefly overview how that mechanism works, we have a phase of compilation called "renaming", which takes all identifiers and figures out what true names they refer to. This is done by consulting the hi files associated with imported modules, which record the original name of any identifiers they export.
By analogy, the installed package information file is like an "hi" file, and we would like it to store a pointer to the original name of the module (in this case, the InstalledPackageId and original module name, if renaming is allowed.)
However, there is trouble in paradise. Entries in the InstalledPackageDb are created by the Cabal library; however, the Cabal library has no knowledge about module resolution (it only looks at the dependencies to do dependency resolution): all of this logic is in GHC proper (Packages and Finder). So at the time Cabal is writing the installed package info, it would need to consult GHC in order to figure out where modules actually came from! This seems like a design smell.
The alternative is to do module resolution in GHC. Here, we augment the creation of our module map (when processing -package flags) so that when we see a reexport, we consult the existing map and insert a pointer to precisely the original import. If the packages are passed to us in topologically sorted order (which Cabal seems to do today), then we only pay the cost of a single map lookup for every reexported module we encounter. The downside is that this mechanism is now no longer symmetric with original names.
Suppose a module Foo is defined by package a, and reexported by package b. I misspell my import and attempt to import module Fooo (sic). Clearly, when I give the list of corrections, I should only report Foo once. Now, suppose I have another module Foo defined by package c, so in our message we want to report that the module was found in multiple packages. In this case, we want to say "it was found in multiple packages: a (reexported by b), c" (and not just "a, c")
When we validate an entry in the installed package database, should we check if the reexported modules truly exist in the original package? Depending on what representation we have in the package database, this may not even be well defined. In any case, dependency validation should pick up most shenanigans.
In some functions, including packageDbModules from the GHC API, we asked to provide a Module for a re-exported module. Should the module returned be resolved to the original exporter, or still be the original name of the module?
SPJ thought of a good way around the implementation problem: we should implement a "mini" module finder in ghc-pkg, which simply takes all of the dependencies listed in the package, and reads their entries in order to resolve a module reexport. We hold the invariant that reexports in the installed package database point to the original name, so once we find the relevant entry, we know the original name.
We really ought to switch to something like cpphs (which we can tweak to be better aware of Haskell syntax) for milestone:7.10.1 than having to keep in mind that there's now a 2nd cpp out there with slightly different semantics which keeps breaking builds... :-/
commit 9487305393307d5eb34069c5821c11bb98b5ec90Author: Edward Z. Yang <ezyang@cs.stanford.edu>Date: Sat Jul 26 10:41:28 2014 +0100 Fix build on OS X due to macro-like string in comment Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>