Description
Describe the bug
tl;dr: If your project depends on a package that has a custom-setup
with bounds Cabal < X.Y.Z
, you cannot use Cabal-X.Y.Z
in your library (or other things might break since its behaviour in this situation is really not defined).
What's going on: Since not all dependencies of a project are going to be linked together (think of exe-depends and custom-setup), cabal-install-solver has the notion of "constraint scopes". I.e. the constraints for the dependencies of each exe-depends and each custom-setup will be solved independently (I am not sure about what happens with executables).
This means that the plan might contain different versions of a same package (used in two different scopes). Haskell.nix is oblivious to this and assumes, in multiple points, that there's only one version of each package in the plan. In the scenario above, even if plan.json says that your package needs Cabal-X.Y.Z as a dependency, haskell.nix might use an earlier version.
Two examples are 1) plan-nix format
packages = {
Cabal.revision = import ./cabal-files/Cabal.nix;
...
and 2) the modules options
modules = [{ packages.somepackage... }];
Notes from @hamishmack
If the plan.json has multiple versions of the a package (or multiple different configurations), haskell.nix is not very smart. I think we might have done something to make it choose the most recent version, but that is not the right thing to do. We should really use the ids from the plan.json as the keys in haskell.nix (so depends should list them instead). That would go part way to solving the problem, but it still makes it hard to know how things like modules = [{ packages.somepackage... }]; would work. We can't expect the package id there (since we won't know what it is). We might have to have to map them to the IDs. Then for an even more complete solution we would perhaps want some way to specify the version (or other attributes in those paths. modules = [{ packages.somepackage-1.0... }]; ).
Notes form @andreabedini
cabal has a syntax to refer to packages in a scope (e.g.
pretty-simple:setup.Cabal-syntax
), we should consider using the same syntax. The unqualified package name could still refer to the package across all scopes (I think this is cabal's interpretation).