haskell / haskell/cabal

`cabal repl` causes reconfiguration in subsequent `cabal build`

Open
#11,623 8 comments 0 reactions 0 assignees View on GitHub
cabal-install: v2-build system can-workaround re: --with-repl re: multi-repl type: bug
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

**Describe the bug**
Alternating `cabal build local-pkg` and `cabal repl local-pkg` commands will cause `local-pkg` to be endlessly reconfigured.

**To Reproduce**
Pretty much any cabal project will work, e.g. this empty library:
Example project

`cabal.project`
```cabal
packages: .
```

`test.cabal`
```cabal
cabal-version: 3.0
name: test
version: 0
build-type: Simple

library
build-depends: base
default-language: Haskell2010
exposed-modules: Test
```

`Test.hs`
```hs
module Test where
```

Run:
```
$ cabal build test
Configuration is affected by the following files:
- cabal.project
Resolving dependencies...
Build profile: -w ghc-9.8.4 -O1
In order, the following will be built (use -v for more details):
- test-0 (lib) (first run)
Configuring library for test-0...
Preprocessing library for test-0...
Building library for test-0...
[1 of 1] Compiling Test ( Test.hs, dist-newstyle/build/x86_64-linux/ghc-9.8.4/test-0/build/Test.o, dist-newstyle/build/x86_64-linux/ghc-9.8.4/test-0/build/Test.dyn_o )

$ cabal repl test < /dev/null
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-9.8.4 -O1
In order, the following will be built (use -v for more details):
- test-0 (interactive) (lib) (configuration changed)
Configuring library for test-0...
Preprocessing library for test-0...
GHCi, version 9.8.4: https://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Test ( Test.hs, interpreted )
Ok, one module loaded.
ghci> Leaving GHCi.

$ cabal build test
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-9.8.4 -O1
In order, the following will be built (use -v for more details):
- test-0 (lib) (configuration changed)
Configuring library for test-0...
Preprocessing library for test-0...
Building library for test-0...

$ cabal repl test < /dev/null
Configuration is affected by the following files:
- cabal.project
Build profile: -w ghc-9.8.4 -O1
In order, the following will be built (use -v for more details):
- test-0 (interactive) (lib) (configuration changed)
Configuring library for test-0...
Preprocessing library for test-0...
GHCi, version 9.8.4: https://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Test ( Test.hs, interpreted )
Ok, one module loaded.
ghci> Leaving GHCi.
```

Note that after the initial build, in every command we get "configuration changed", followed by "Configuring library".

**Expected behavior**
The two commands should not de-configure each other.

**System information**
- Arch linux
- Cabal-3.16.1.0, GHC 9.8.4

**Additional context**
In my real workflow this alternation happens because:
- HLS does `cabal repl --with-repl .../hie-bios/repl-wrapper OpenedFile.hs` to capture GHC arguments,
- I do `cabal build all` in the terminal.

This means `cabal repl` has to reconfigure the package containing `OpenedFile.hs`, and `cabal build all` has to reconfigure all packages downstream of that file.

Another complication here is that HLS passes `--enable-multi-repl` and `--with-repl`, so actually `cabal repl` has to reconfigure all local packages upstream of `OpenedFile.hs`, and `cabal build` has to reconfigure *all* all local packages, which in my case takes a full minute.

`--enable-multi-repl` and `--with-repl` do add constraints to the solver (`Cabal >=3.11`, `Cabal >=3.15` respectively), and initially I thought that this causes reconfiguration. Running `cabal build all -v3 2>&1 | grep 'File monitor'` we see:
```
File monitor 'config' unchanged.
File monitor 'improved-plan' changed: monitor value changed
File monitor 'elaborated-plan' changed: monitor value changed
File monitor 'compiler' unchanged.
File monitor 'solver-plan' changed: monitor value changed
File monitor 'source-hashes' unchanged.
```
But having dumped and analyzed these files, I found that these extra constraints appear in the *input* part of the cache, which causes the cache to be recomputed, but the *output* of this recomputation is exactly the same. Indeed, my freeze file has `any.Cabal ==3.16.1.0` which is a stronger constraint than both of the above, meaning none of the plans actually change (I've verified this).

Also the reconfiguration happens without `--enable-multi-repl` nor `--with-repl`, where all file monitors report "unchanged".

I've done a bisect and e61b658de53449422693024a9ca820b0ee89860e (#8726) is the first bad commit.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.