[GHC] #10723: Make declarations in signatures "weakly bound" until they are used
GHC
ghc-devs at haskell.org
Sat Aug 1 06:19:32 UTC 2015
#10723: Make declarations in signatures "weakly bound" until they are used
-------------------------------------+-------------------------------------
Reporter: ezyang | Owner: ezyang
Type: feature | Status: new
request |
Priority: normal | Milestone:
Component: Package | Version: 7.11
system |
Keywords: backpack | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Revisions: |
-------------------------------------+-------------------------------------
Suppose you are the author of a library in a Backpack world, and you
publish a signature package which defines the entire public facing
interface of your library. The library `foo` which uses of your library
decides to `include` the signature package for convenience, but actually
only uses a small portion of the API.
Later, you make a BC-breaking change in one part of the library and
release a new signature package. The library `bar` which uses your
library includes this NEW signature package, using a different portion of
the API which was unaffected by the by the BC change.
Now, a hapless user tries to use `foo` and `bar`, but Backpack complains
that the requirements are not compatible.
What's the problem here? The practice of writing reusable signature
packages for people to use caused the requirements of `foo` and `bar` to
become too large, since they included a lot of junk that these libraries
didn't actually use. It would be far better if you could `include` a
signature package, but only "require" the bits of it that you actually
used!
How can we achieve this?
1. We augment the `ModIface` of signature merges (#10690) to record
whether or not a declaration was (transitively) used or not by some
module. Used declarations must be filled, but unused ones are treated
more flexibly: if they are merged with a different, incompatible but used
requirement, they disappear, and we don't check if an implementing module
actually implemented the declaration. (If two unused incompatible
requirements are merged, we just erase the name.)
2. How do we compute the usage info? I think it will have to be done
during shaping (which runs the renamer). We only need to annotate each
declaration a signature with the transitive set of names from other
signatures that it has used--this can be incrementally computed. (It's not
necessary to annotate declarations in modules, since they are always
assumed to use holes). Then whenever a declaration from a signature is
used in a module, we mark its transitive set as used. This information
can then be used later when constructing the merged `ModIface` which
represents the "public requirement" of the package.
So, for example, a package containing only signatures would contain all
unused declarations (however, they may start being used by a package which
includes them). Any unused declaration which isn't mixed with another
incompatible declaration can be imported (causing it to be used), but we
will complain if you try to use a name and we can't tell which declaration
to use.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10723>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list