Support for module thinning/renaming on command line
In #8407 (closed), we added the capability for packages to reexport modules from other packages. This ticket is for the dual operation: during the compilation of a module, rather than being forced dump all of the exposed modules of package foo when I say
-package foo, I should be able to selectively pick which modules I make visible (thinning) and rename them, if I like. For now, the proposed syntax is for all package flags, I can now write
-package "foo (A as B, C)".
This feature has special implications for how the package database hiding/showing works. Currently, if I write
-package foo-0.1, this will automatically go ahead and un-expose any other packages named
foo that I may have loaded. But if I write
-package foo-0.1 (Foo as Foo1) -package foo-0.2 (Foo as Foo2), I probably didn't actually want to hide the old instance of
foo-0.1 when I exposed
foo-0.2. More generally, rather than thinking of package configuration as flipping exposed/not-exposed bits on and off of an in-memory package database, we would rather think of it as setting up a mapping of module names to their implementations, and only reporting a conflict when there is an inconsistent module mapping.
Since this is a change of behavior, I propose two sets of semantics, controlled by a flag
-backpack (but really, I mostly care about the second set). Flag naming can be negotiated.
In the **absence** of
-backpack, thinning/renaming works by modifying the exposed/reexported module fields of the matched packages in the database. However, the old hiding behavior still applies, so this functionality would primarily be useful if two separate packages exported a module with the same name, and you still wanted to use both of them. So, the original example would not do what you want, but
-package mtl (Control.Monad.Trans as MtlTrans) -package transformers (Control.Monad.Trans as TransformersTrans) would DTRT.
- *With** the
-backpackflag, no auto-hiding of packages occurs (this affects flags with thinning and renaming). Furthermore, the package database is cleared, as would be done with
-hide-all-packages. We replace the old resolution algorithm with the new one, which processes each flag one-by-one while building a module mapping, picking a package which is consistent with the currently selected set of packages. This consistency is done by looking at the current module mapping and ensuring all of the modules the package would bring into scope are consistent with the modules we have already. Both example shown before would work; furthermore,
-package foo -package foowould also continue to work, since
foo's exports are consistent with itself. However,
-package foo-0.1 -package foo-0.2would be rejected (whereas now it is accepted.)