-
Notifications
You must be signed in to change notification settings - Fork 841
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
Recompilation checking issue with multiple packages, --fast and TH #6248
Comments
Ok interestingly with GHC 9.2.8 this is broken with both cabal-install and stack, but it seems to be fixed for cabal-install with GHC 9.4 |
The difference seems to be that with GHC 9.4 we have |
@TeofilC, thanks for reporting. I hope to get to your reproducer over the next few days. |
@TeofilC, I am confused. Looking at the steps in the
Package {-# LANGUAGE TemplateHaskell #-}
module Lib
( someFunc
) where
import qualified LibA
import Language.Haskell.TH.Syntax
someFunc :: String
someFunc = $( runIO (print LibA.someFunc) >> lift LibA.someFunc ) On Windows, step [4] fails as expected - because
|
I don't understand the relevance of |
Oh I think the quoting works differently on Windows?
Indeed the passing |
@TeofilC, I see. I misunderstood because I am not familar with |
@TeofilC, so, if the steps are (correcting my understanding):
On Windows, this works fine. Step [4] is:
What are you experiencing, that differs? (EDIT: I've tried it with and without |
Yes that's right. Though [5] is only necessary to get us back to the inital state. I'm expecting [4] to lead to lib-B recompiling, since the TH splice uses LibA.someFunc. |
On rereading your output I see that it is recompiling for you. It doesn't do that for me on Linux |
Actually, I think the EDIT: I've added an executable to package module Main (main) where
import Lib
main :: IO ()
main = putStrLn someFunc executables:
bTest:
source-dirs: app
main: Main.hs
dependencies:
- lib-B With
Without
This behaviour reminds me of something, somewhere else. I'll see if I can put my finger on it. |
I think I might have broken this reproducer when minimising. When trying it again with GHC 9.4.6 I don't seem to get this behaviour. I'll take another look at it |
The executable stuff sounds like #6193 |
What this reminds me of is this: https://discourse.haskell.org/t/problem-with-ghcs-recompilation-checker/7079 |
After further digging I've managed to refine a reproducer that actually works. The key thing is that the test suite doesn't get unregistered by [3] since that build invocation doesn't get passed While this does concern an executable, I think this is a distinct issue since the logs show we don't even compile the module after the change, so it's not merely a linking thing. And I can reproduce it on GHC 9.2.8. |
I see the problem. After 'dirty' A is re-built, B does not recognise that A is still 'dirty' compared to the last time that B was built. |
I don't think this is anything to do with Template Haskell or
module LibA ( someFuncA ) where
someFuncA :: IO ()
someFuncA = putStrLn "someFuncA"
module LibB ( someFuncB ) where
import LibA
someFuncB = do
someFuncA
putStrLn "someFuncB" |
What appears to distinguish this issue from closed #2904 (closed, fixed and still fixed) is that it is an executable in package B (including a test-suite) that depends on package A when there is no library in package B that depends on package A. So a route to fixing it may be to examine the 'cure' for #2904, which was #3047 (Aggressive unregister). |
My current hypothesis is that this is because, it seems: I am not sure if that is a Stack bug or a Cabal bug, put perhaps this Cabal issue is relevant: haskell/cabal#8434. However, -- | Determine which packages to unregister based on the given tasks and
-- already registered local packages.
mkUnregisterLocal ::
Map PackageName Task
-- ^ Tasks
-> Map PackageName Text
-- ^ Reasons why packages are dirty and must be rebuilt
-> [DumpPackage]
-- ^ Local package database dump
-> Bool
-- ^ If true, we're doing a special initialBuildSteps build - don't
-- unregister target packages.
-> Map GhcPkgId (PackageIdentifier, Text)
mkUnregisterLocal tasks dirtyReason localDumpPkgs initialBuildSteps =
-- We'll take multiple passes through the local packages. This will allow us
-- to detect that a package should be unregistered, as well as all packages
-- directly or transitively depending on it.
loop Map.empty localDumpPkgs
...
go :: DumpPackage -> State UnregisterState ()
go dp = do
us <- get
case maybeUnregisterReason (usToUnregister us) ident mParentLibId deps of
...
where
gid = dpGhcPkgId dp
ident = dpPackageIdent dp
mParentLibId = dpParentLibIdent dp
deps = dpDepends dp -- <<<< If this is missing the dependency, it can't get unregistered |
@TeofilC, I think I know what the cause of the problem is: an installed GHC package does not capture non-library stanza dependencies. That means that there is a workaround, for now, albeit an 'ugly' one: either (a) include a 'dummy' library stanza in the package with a |
Thanks Ill try that! |
Summary
We noticed that some of our tests that used TH were sometimes not recompiling with stack. This led to stale test results.
I've managed to extract the following reproducer.
NB: this is reproducible with GHC 9.2.8 so it's not related to the recompilation changes in 9.4.
Steps to reproduce
Clone this repository https://github.com/TeofilC/stack-recomp-checking-issue.
Then run
./repro.sh
This does the following:
Expected
I would expect the file to recompile even with --fast and cabal-install does this correctly, so it seems like this is a bug in stack rather than GHC/Cabal.
Actual
The file doesn't recompile.
I couldn't attach the verbose log as its too long, but should be easy to generate from the reproducer.
Stack version
Method of installation
nix
Platform
WSL2 x86_64
The text was updated successfully, but these errors were encountered: