-
Notifications
You must be signed in to change notification settings - Fork 843
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unnecessary rebuild in circular dep causes issues #6327
Comments
This sounds similar to #3130. |
Yeah, it's similar to #3130 in that the root cause is an old package and new package are both being used. But it's slightly different in that one solutiom to #3130 is "invalidate more, cause a rebuild", but that would actually cause a circular build in this case, as rebuilding my-test-utils would invalidate my-lib, which would force rebuilding my-test-utils. The better solution for this issue is actually the opposite of #3130: avoid rebuilding the library when it was already built and only build the test-suite the second time around. |
Is this something to do with the solution to #2904? That is, I understand that Stack rebuilds more than it would like to because Cabal does not assign unique ids to packages based on their contents. |
#2904 seems to be the same as #3130, no? That is, it seems like the resolution of that ticket is "unregister more", where I want "unregister less". One comment in the other issue says "the package ID should change when the contents of the package change", but that's not what's happening in this issue. Here, the source code of the package hasnt changed, but Stack is still rebuilding. As I mentioned in the description, #2904 and #3130 both are solvable by |
Adding output from
|
Overview
At a high level, Stack allows packages to have circular dependencies if it's linearizable at the component level (Cabal flat out rejects to build this situation). However, Stack will fail to recognize that it can reuse the first library and rebuild, causing the second library to be using an old version of the first library.
This is similar to #3130 in that both issues stem from a library still using an old version of a dependent library. But in #3130, the problem is Stack not rebuilding enough, and in this issue, the problem is Stack rebuilds unnecessarily. In fact, #3130 is not an issue if you
stack clean
before every build, but this issue is still present even from a clean build.Problems
In all of the situations below, we have the following project:
This creates a dependency chain that looks like:
When running a
stack test
, Stack will do the following:my-lib:lib
my-test-utils:lib
againstmy-lib:lib (1)
my-lib:lib
my-lib:test-suite
againstmy-test-utils:lib
andmy-lib:lib (2)
Problem 1: compilation error with old data type
In this minimal repro, we can see that
my-test-utils
is still using the old library'sFoo
data type (as exposed by thefoo
function), as GHC complains that you're trying to compare an oldFoo
type with a newFoo
type.Expected
Works
Actual
Problem 2: surprising behavior with global IORef
This situation is the original problem I ran into, and it was surprising because it actually compiles successfully (unlike problem 1), but it has surprising behavior at runtime: the global IORef is actually initialized twice, once for
my-lib:lib (1)
and once formy-lib:lib (2)
. SowriteRefFromTestUtils
actually sets a different IORef than the one read fromreadRefFromLib
.Expected
Actual
The text was updated successfully, but these errors were encountered: