Skip to content

Commit 50d5e31

Browse files
authored
Merge pull request #10105 from alt-romes/wip/romes/ghc24926
Fix recomp bug by invalidating cache on build exception
2 parents 0b0a31a + a9f2c3b commit 50d5e31

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

cabal-install/src/Distribution/Client/ProjectBuilding/UnpackedPackage.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ import qualified Data.ByteString.Lazy as LBS
9999
import qualified Data.ByteString.Lazy.Char8 as LBS.Char8
100100
import qualified Data.List.NonEmpty as NE
101101

102-
import Control.Exception (ErrorCall, Handler (..), SomeAsyncException, assert, catches)
102+
import Control.Exception (ErrorCall, Handler (..), SomeAsyncException, assert, catches, onException)
103103
import System.Directory (canonicalizePath, createDirectoryIfMissing, doesDirectoryExist, doesFileExist, removeFile)
104104
import System.FilePath (dropDrive, normalise, takeDirectory, (<.>), (</>))
105105
import System.IO (Handle, IOMode (AppendMode), withFile)
@@ -480,6 +480,10 @@ buildInplaceUnpackedPackage
480480
whenRebuild $ do
481481
timestamp <- beginUpdateFileMonitor
482482
runBuild
483+
-- Be sure to invalidate the cache if building throws an exception!
484+
-- If not, we'll abort execution with a stale recompilation cache.
485+
-- See ghc#24926 for an example of how this can go wrong.
486+
`onException` invalidatePackageRegFileMonitor packageFileMonitor
483487

484488
let listSimple =
485489
execRebuild (getSymbolicPath srcdir) (needElaboratedConfiguredPackage pkg)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Process (a)
2+
import Internal (Unused)
3+
4+
main :: IO ()
5+
main = a
6+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Test.Cabal.Prelude
2+
3+
-- See ghc#24926
4+
main = cabalTest $ do
5+
recordMode DoNotRecord $ do
6+
7+
root <- testTmpDir <$> getTestEnv
8+
9+
writeInternalOrig root
10+
cabal "test" []
11+
12+
liftIO $ writeFile (root ++ "/src/Internal.hs")
13+
" module Internal where;\
14+
15+
\ data Unused = Unused;"
16+
fails $ cabal "test" [] -- broken module on purpose
17+
18+
writeInternalOrig root
19+
out <- cabal' "test" [] -- shouldn't fail!
20+
21+
assertOutputDoesNotContain
22+
"<no location info>: error:" out
23+
assertOutputDoesNotContain
24+
"Cannot continue after interface file error" out
25+
26+
where
27+
28+
writeInternalOrig r = liftIO $ do
29+
writeFile (r ++ "/src/Internal.hs")
30+
" module Internal where;\
31+
32+
\ data Unused = Unused;\
33+
34+
\ b :: IO (); \
35+
\ b = pure ();"
36+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cabal-version: 3.0
2+
name: repro
3+
version: 0.1.0.0
4+
build-type: Simple
5+
6+
library
7+
default-language: Haskell2010
8+
exposed-modules:
9+
Internal
10+
Process
11+
build-depends: base
12+
hs-source-dirs: src
13+
14+
test-suite repro
15+
default-language: Haskell2010
16+
type: exitcode-stdio-1.0
17+
main-is: Repro.hs
18+
build-depends: base, repro
19+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Process where
2+
3+
import Internal
4+
5+
a :: IO ()
6+
a = b
7+

0 commit comments

Comments
 (0)