Visibility: handle multiple units with the same name
authorMichael Peyton Jones <me@michaelpj.com>
Wed, 13 Mar 2019 11:46:56 +0000 (11:46 +0000)
committerBen Gamari <ben@smart-cactus.org>
Sun, 23 Jun 2019 17:27:12 +0000 (13:27 -0400)
commit856cdb9d53242afe7ad2d15c3841427f83d55773
tree21c75d48be7a2f91ec9a52608a51f0e1d35aee4a
parent7c9c129ef2f688c878f21af11d3a4195744bc1e6
Visibility: handle multiple units with the same name

Fixes #16228. The included test case is adapted from the reproduction in
the issue, and fails without this patch.

------

We compute an initial visilibity mapping for units based on what is
present in the package databases. To seed this, we compute a set of all
the package configs to add visibilities for.

However, this set was keyed off the unit's *package name*. This is
correct, since we compare packages across databases by version. However,
we would only ever consider a single, most-preferable unit from the
database in which it was found.

The effect of this was that only one of the libraries in a Cabal package
would be added to this initial set. This would cause attempts to use
modules from the omitted libraries to fail, claiming that the package
was hidden (even though `ghc-pkg` would correctly show it as visible).

A solution is to do the selection of the most preferable packages
separately, and then be sure to consider exposing all units in the
same package in the same package db. We can do this by picking a
most-preferable unit for each package name, and then considering
exposing all units that are equi-preferable with that unit.

------

Why wasn't this bug apparent to all people trying to use sub-libraries
in Cabal? The answer is that Cabal explicitly passes `-package` and
`-package-id` flags for all the packages it wants to use, rather than
relying on the state of the package database. So this bug only really
affects people who are trying to use package databases produced by Cabal
outside of Cabal itself.

One particular example of this is the way that the
Nixpkgs Haskell infrastructure provides wrapped GHCs: typically these
are equipped with a package database containing all the needed
package dependencies, and the user is not expected to pass
`-package` flags explicitly.

(cherry picked from commit 8a20bfc21da6a47087c8069f92691629eb47951d)
compiler/main/Packages.hs
testsuite/tests/cabal/cabal10/Makefile [new file with mode: 0644]
testsuite/tests/cabal/cabal10/Setup.hs [new file with mode: 0644]
testsuite/tests/cabal/cabal10/Use.hs [new file with mode: 0644]
testsuite/tests/cabal/cabal10/all.T [new file with mode: 0644]
testsuite/tests/cabal/cabal10/cabal10.stdout [new file with mode: 0644]
testsuite/tests/cabal/cabal10/internal-lib.cabal [new file with mode: 0644]
testsuite/tests/cabal/cabal10/src/TestLib.hs [new file with mode: 0644]