GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2023-12-13T16:29:09Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24175-fbyte-code-and-object-code does not overwrite the existing hi file2023-12-13T16:29:09ZIan-Woo Kim-fbyte-code-and-object-code does not overwrite the existing hi file## Summary
with -fbyte-code-and-object-code, GHC is supposed to make `.hi` files with serialized simplified core in `extra decls` field. But if there exists a `.hi` file from a previous compilation without the flag somehow, then the com...## Summary
with -fbyte-code-and-object-code, GHC is supposed to make `.hi` files with serialized simplified core in `extra decls` field. But if there exists a `.hi` file from a previous compilation without the flag somehow, then the compilation with the flag keeps interpreting the module, but does not change the interface file.
This makes users confused since it triggers a big recompilation which does not go away. The only way to restore a normal recompilation behavior is to clean the build directory.
## Steps to reproduce
A.hs
```
module A where
testA :: IO ()
testA = pure ()
```
B.hs
```
module B where
import A
testB :: IO ()
testB = testA
```
```
$ ghc A B
[1 of 2] Compiling A ( A.hs, A.o )
[2 of 2] Compiling B ( B.hs, B.o )
$ ghc A B -fbyte-code-and-object-code
[1 of 2] Compiling A ( A.hs, A.o, interpreted ) [Missing bytecode]
[2 of 2] Compiling B ( B.hs, B.o, interpreted ) [Missing bytecode]
(change B)
$ ghc A B -fbyte-code-and-object-code
[1 of 2] Compiling A ( A.hs, A.o, interpreted ) [Missing bytecode]
[2 of 2] Compiling B ( B.hs, B.o, interpreted ) [Source file changed]
```
A is being recompiled.
## Expected behavior
In the second step, `A.hi` should be regenerated with simplified core.
After cleaning `*.hi`, and recompile with the flag
```
$ ghc --show-iface A.hi
...
extra decls:
$trModule = GHC.Types.Module $trModule2 $trModule4
$trModule1 = "main"#
$trModule2 = GHC.Types.TrNameS $trModule1
$trModule3 = "A"#
$trModule4 = GHC.Types.TrNameS $trModule3
testA = GHC.Base.pure
@GHC.Types.IO
GHC.Base.$fApplicativeIO
@()
GHC.Tuple.Prim.()
...
```
## Environment
* GHC version used: 9.6.2, 9.8.1, 9.9.20231107 (master)
* Operating System: macOS 14.1
* System Architecture: AArch649.8.2Ian-Woo KimIan-Woo Kimhttps://gitlab.haskell.org/ghc/ghc/-/issues/23912Add -fforce-relink flag to force relinking2024-01-15T10:03:01ZMatthew PickeringAdd -fforce-relink flag to force relinkingDue to bugs like #23724 it could be useful to override the relinking checker. The only way to do this at the moment is to use `-fforce-recomp`, which is a very big hammer.
It would be useful to provide a flag which just causes the linki...Due to bugs like #23724 it could be useful to override the relinking checker. The only way to do this at the moment is to use `-fforce-recomp`, which is a very big hammer.
It would be useful to provide a flag which just causes the linking step to always happen if there are any more issues in this area.https://gitlab.haskell.org/ghc/ghc/-/issues/23724Linking recompilation checking only checks modifiation time of direct package...2024-02-20T14:06:41ZMatthew PickeringLinking recompilation checking only checks modifiation time of direct package dependenciesSee: https://discourse.haskell.org/t/problem-with-ghcs-recompilation-checker/7079/
The issue is that we only check the direct package dependencies in `linkingNeeded`, but ultimately the transitive closure of needed packages is passed to...See: https://discourse.haskell.org/t/problem-with-ghcs-recompilation-checker/7079/
The issue is that we only check the direct package dependencies in `linkingNeeded`, but ultimately the transitive closure of needed packages is passed to the C compiler when asked to perform the linking.
```
lib_times
(2023-07-25T09:49:41.400941163Z,
[2023-07-25T09:24:36.646963579Z, 2023-07-25T09:33:13.17672616Z],
[True, True],
[Just /home/matt/ghc-clean/_build/stage1/lib/../lib/x86_64-linux-ghc-9.9.20230725/base-4.18.0.0-inplace/libHSbase-4.18.0.0-inplace.a,
Just /home/matt/ghc-recomp-test/dist-newstyle/build/x86_64-linux/ghc-9.9.20230725/packageB-0.1.0.0/noopt/build/libHSpackageB-0.1.0.0-inplace.a])
```
```
/nix/store/823ccn93siyv5n61nkpf3syr2zi93i9d-gcc-wrapper-12.2.0/bin/cc '-fuse-ld=gold' -o /home/matt/ghc-recomp-test/dist-newstyle/build/x86_64-linux/ghc-9.9.20230725/packageB-0.1.0.0/x/progB/noopt/build/progB/progB -lm -no-pie -Wl,--gc-sections /home/matt/ghc-recomp-test/dist-newstyle/build/x86_64-linux/ghc-9.9.20230725/packageB-0.1.0.0/x/progB/noopt/build/progB/progB-tmp/Main.o -L/home/matt/ghc-recomp-test/dist-newstyle/build/x86_64-linux/ghc-9.9.20230725/packageB-0.1.0.0/noopt/build -L/home/matt/ghc-recomp-test/dist-newstyle/build/x86_64-linux/ghc-9.9.20230725/packageA-0.1.0.0/noopt/build -L/home/matt/ghc-clean/_build/stage1/lib/../lib/x86_64-linux-ghc-9.9.20230725/base-4.18.0.0-inplace -L/home/matt/ghc-clean/_build/stage1/lib/../lib/x86_64-linux-ghc-9.9.20230725/ghc-bignum-1.3-inplace -L/home/matt/ghc-clean/_build/stage1/lib/../lib/x86_64-linux-ghc-9.9.20230725/ghc-prim-0.10.0-inplace -L/home/matt/ghc-clean/_build/stage1/lib/../lib/x86_64-linux-ghc-9.9.20230725/rts-1.0.2 /run/user/1000/ghc3659324_0/ghc_4.o /run/user/1000/ghc3659324_0/ghc_7.o -Wl,-u,base_GHCziTopHandler_runIO_closure -Wl,-u,base_GHCziTopHandler_runNonIO_closure -Wl,-u,ghczmprim_GHCziTupleziPrim_Z0T_closure -Wl,-u,ghczmprim_GHCziTypes_True_closure -Wl,-u,ghczmprim_GHCziTypes_False_closure -Wl,-u,base_GHCziPack_unpackCString_closure -Wl,-u,base_GHCziWeakziFinalizze_runFinalizzerBatch_closure -Wl,-u,base_GHCziIOziException_stackOverflow_closure -Wl,-u,base_GHCziIOziException_heapOverflow_closure -Wl,-u,base_GHCziIOziException_allocationLimitExceeded_closure -Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnSTM_closure -Wl,-u,base_GHCziIOziException_cannotCompactFunction_closure -Wl,-u,base_GHCziIOziException_cannotCompactPinned_closure -Wl,-u,base_GHCziIOziException_cannotCompactMutable_closure -Wl,-u,base_GHCziIOPort_doubleReadException_closure -Wl,-u,base_ControlziExceptionziBase_nonTermination_closure -Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure -Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure -Wl,-u,base_GHCziConcziSync_runSparks_closure -Wl,-u,base_GHCziConcziIO_ensureIOManagerIsRunning_closure -Wl,-u,base_GHCziConcziIO_interruptIOManager_closure -Wl,-u,base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure -Wl,-u,base_GHCziConcziSignal_runHandlersPtr_closure -Wl,-u,base_GHCziTopHandler_flushStdHandles_closure -Wl,-u,base_GHCziTopHandler_runMainIO_closure -Wl,-u,ghczmprim_GHCziTypes_Czh_con_info -Wl,-u,ghczmprim_GHCziTypes_Izh_con_info -Wl,-u,ghczmprim_GHCziTypes_Fzh_con_info -Wl,-u,ghczmprim_GHCziTypes_Dzh_con_info -Wl,-u,ghczmprim_GHCziTypes_Wzh_con_info -Wl,-u,base_GHCziPtr_Ptr_con_info -Wl,-u,base_GHCziPtr_FunPtr_con_info -Wl,-u,base_GHCziInt_I8zh_con_info -Wl,-u,base_GHCziInt_I16zh_con_info -Wl,-u,base_GHCziInt_I32zh_con_info -Wl,-u,base_GHCziInt_I64zh_con_info -Wl,-u,base_GHCziWord_W8zh_con_info -Wl,-u,base_GHCziWord_W16zh_con_info -Wl,-u,base_GHCziWord_W32zh_con_info -Wl,-u,base_GHCziWord_W64zh_con_info -Wl,-u,base_GHCziStable_StablePtr_con_info -Wl,-u,hs_atomic_add8 -Wl,-u,hs_atomic_add16 -Wl,-u,hs_atomic_add32 -Wl,-u,hs_atomic_add64 -Wl,-u,hs_atomic_sub8 -Wl,-u,hs_atomic_sub16 -Wl,-u,hs_atomic_sub32 -Wl,-u,hs_atomic_sub64 -Wl,-u,hs_atomic_and8 -Wl,-u,hs_atomic_and16 -Wl,-u,hs_atomic_and32 -Wl,-u,hs_atomic_and64 -Wl,-u,hs_atomic_nand8 -Wl,-u,hs_atomic_nand16 -Wl,-u,hs_atomic_nand32 -Wl,-u,hs_atomic_nand64 -Wl,-u,hs_atomic_or8 -Wl,-u,hs_atomic_or16 -Wl,-u,hs_atomic_or32 -Wl,-u,hs_atomic_or64 -Wl,-u,hs_atomic_xor8 -Wl,-u,hs_atomic_xor16 -Wl,-u,hs_atomic_xor32 -Wl,-u,hs_atomic_xor64 -Wl,-u,hs_cmpxchg8 -Wl,-u,hs_cmpxchg16 -Wl,-u,hs_cmpxchg32 -Wl,-u,hs_cmpxchg64 -Wl,-u,hs_xchg8 -Wl,-u,hs_xchg16 -Wl,-u,hs_xchg32 -Wl,-u,hs_xchg64 -Wl,-u,hs_atomicread8 -Wl,-u,hs_atomicread16 -Wl,-u,hs_atomicread32 -Wl,-u,hs_atomicread64 -Wl,-u,hs_atomicwrite8 -Wl,-u,hs_atomicwrite16 -Wl,-u,hs_atomicwrite32 -Wl,-u,hs_atomicwrite64 -Wl,-u,base_GHCziStackziCloneStack_StackSnapshot_closure -lHSpackageB-0.1.0.0-inplace -lHSpackageA-0.1.0.0-inplace -lHSbase-4.18.0.0-inplace -lHSghc-bignum-1.3-inplace -lHSghc-prim-0.10.0-inplace -lHSrts-1.0.2 -lCffi -lgmp -lc -lm -lc -lm -lrt -ldl
```Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/23369Many compiler flags affecting code generation are not accounted for in recomp...2023-09-19T06:12:19ZBen GamariMany compiler flags affecting code generation are not accounted for in recompilation checkingCurrently there are a number of flags which may affect program behavior but are not considered by the recompilation checker. Specifically:
* `-feager-blackholing`, which can affect the probability of multiple thunk entry and may improv...Currently there are a number of flags which may affect program behavior but are not considered by the recompilation checker. Specifically:
* `-feager-blackholing`, which can affect the probability of multiple thunk entry and may improve deadlock detection
* `-fexcess-precision`, which can affect floating point arithmetic
* `-fdicts-strict`, which can affect program divergence behavior when `UndecidableInstances` is in use (https://gitlab.haskell.org/ghc/ghc/-/issues/22549)
* `-fpedantic-bottoms`, which can affect program divergence
* `-fomit-yields`, which can affect concurrent program behavior (https://gitlab.haskell.org/ghc/ghc/-/issues/15975)
* `-finfo-table-map`, which affects debugging information
* `-fdistinct-constructor-tables`, which affects debugging information
* `-fcatch-nonexhaustive-cases`, which may cause programs that would otherwise segfault to fail with a more sensible error (#20601)
* `-fno-typeable-binds`, which affects which bindings are generated
* `-fexpose-all-unfoldings`, which affects interface file content
While some of these are admittedly debugging flags, it would be best (that is, less surprising) if recompilation checking accounted for them.
However, we do need to be careful here to avoid regressing #13604, which asks that, when `-fignore-optim-changes` is use, the user be able to adjust optimisation level without recompilation.https://gitlab.haskell.org/ghc/ghc/-/issues/23013JS: recompilation avoidance doesn't always work for TH2023-06-21T16:05:12ZSylvain HenryJS: recompilation avoidance doesn't always work for THThe JS interpreter introduce in !9779 maintains its own link state (it doesn't use object/library granularity as the native linked, but a "block" granularity).
As such it doesn't use/update `LoaderState` at all, breaking the recompilati...The JS interpreter introduce in !9779 maintains its own link state (it doesn't use object/library granularity as the native linked, but a "block" granularity).
As such it doesn't use/update `LoaderState` at all, breaking the recompilation avoidance check for TH.
Fixing the impedance mismatch will require some refactoring, that's why it hasn't been done in the inital MR https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9779 adding TH support.
Failing tests that have been disabled:
- recomp009
- recompTH
- T20604
- th-new-test
Related to https://gitlab.haskell.org/ghc/ghc/-/issues/20604Sylvain HenrySylvain Henryhttps://gitlab.haskell.org/ghc/ghc/-/issues/22779GHCI always reloads hs-boot file2023-01-25T09:46:34ZGuillaume BouchardGHCI always reloads hs-boot file## Summary
ghci `:reload` seems to always reload `.hs-boot` files even if they had no changes since last reload
## Steps to reproduce
Looks like it is reproducible with any setup containing `hs-boot` files. Open `ghci`, load a file wi...## Summary
ghci `:reload` seems to always reload `.hs-boot` files even if they had no changes since last reload
## Steps to reproduce
Looks like it is reproducible with any setup containing `hs-boot` files. Open `ghci`, load a file with `:load`, then `:reload` and see that hs boots are reloaded.
Here is a simple reproducer with ghc 9.4.4:
file `Bar.hs`:
```haskell
module Bar where
import Foo
```
file `Bar.hs-boot`:
```haskell
module Bar where
```
file `Foo.hs`:
```haskell
module Foo where
import {-# SOURCE #-} Bar
```
Start `ghci` and run `:load` followed by multiples `:reload`:
```
GHCi, version 9.4.4: https://www.haskell.org/ghc/ :? for help
ghci> :l Bar.hs
[1 of 3] Compiling Bar[boot] ( Bar.hs-boot, interpreted )
[2 of 3] Compiling Foo ( Foo.hs, interpreted )
[3 of 3] Compiling Bar ( Bar.hs, interpreted )
Ok, three modules loaded.
ghci> :reload
[1 of 3] Compiling Bar[boot] ( Bar.hs-boot, interpreted ) [Missing object file]
Ok, three modules loaded.
ghci> :reload
[1 of 3] Compiling Bar[boot] ( Bar.hs-boot, interpreted ) [Missing object file]
Ok, three modules loaded.
ghci> :reload
[1 of 3] Compiling Bar[boot] ( Bar.hs-boot, interpreted ) [Missing object file]
Ok, three modules loaded.
```
Everytime the `Bar.hs-boot` file seems to be reloaded with the `Missing object file` reason.
## Expected behavior
It should not reload if the file did not change, looks like wasted time. I suspect that some long reload time I'm observing with haskell-language-server may be caused by this.
## Environment
* GHC version used: GHC 9.4.4.
Note that GHC 9.2.4 does not seem impacted, or at least, it does not show the debug messages:
```
GHCi, version 9.2.4: https://www.haskell.org/ghc/ :? for help
ghci> :l Bar.hs
[1 of 3] Compiling Bar[boot] ( Bar.hs-boot, interpreted )
[2 of 3] Compiling Foo ( Foo.hs, interpreted )
[3 of 3] Compiling Bar ( Bar.hs, interpreted )
Ok, three modules loaded.
ghci> :r
Ok, three modules loaded.
```
Optional:
* Operating System:
* System Architecture:Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/22679Recompilation checking: ModSummary cache leads to incorrect results in multip...2023-07-18T07:32:48ZMatthew PickeringRecompilation checking: ModSummary cache leads to incorrect results in multiple home unit scenariosThe `ModSumary` cache assumes that each file maps to one `Module`. With MHUs, this isn't true, each file can
be used multiple times, as long as it is only used within one unit once.
One may question whether it is a good idea to allow t...The `ModSumary` cache assumes that each file maps to one `Module`. With MHUs, this isn't true, each file can
be used multiple times, as long as it is only used within one unit once.
One may question whether it is a good idea to allow the same file to be compiled multiple times within one session. However, this is how people have set-up their testsuites in cabal for generations (so internal code can be used for testing), therefore it's better to allow it whilst it doesn't cause any issues.
Therefore we just need to update the key of the cache to also contain a UnitId and we're all good.
This can lead to quite confusing errors on reload in GHCi (when the cache is used).9.4.5Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/22677Spurious recompilation in GHCi due to incorrect pruning logic2023-04-11T11:15:17ZMatthew PickeringSpurious recompilation in GHCi due to incorrect pruning logicThe `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true:
* In normal compilation, the same module name can appear for a file and it's boot file.
* In multiple home unit compilation ...The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true:
* In normal compilation, the same module name can appear for a file and it's boot file.
* In multiple home unit compilation the same ModuleName can appear in different units
The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`.9.4.5Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/22675Recompilation checking broken in two ways with multiple home units2023-07-18T07:32:47ZMatthew PickeringRecompilation checking broken in two ways with multiple home units* Course-grained dependency tracking is used if a dependency comes from a different home unit. We should use the fine-grained case.
* UsageHomeModuleInterface doesn't contain a unit id so we don't know which home unit the dependency has ...* Course-grained dependency tracking is used if a dependency comes from a different home unit. We should use the fine-grained case.
* UsageHomeModuleInterface doesn't contain a unit id so we don't know which home unit the dependency has been calculated on which can lead to looking up information in the wrong interface files.9.4.5Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/22632Passing -threaded does not cause relinking2022-12-20T15:48:28ZJade LovelacePassing -threaded does not cause relinking## Summary
I was investigating a bug in `hs-opentelemetry` which was impeded by a recompilation checker bug that did not consider `-threaded` while deciding to link again, so I was getting old builds even though I changed the configurat...## Summary
I was investigating a bug in `hs-opentelemetry` which was impeded by a recompilation checker bug that did not consider `-threaded` while deciding to link again, so I was getting old builds even though I changed the configuration.
## Steps to reproduce
GhcBug.hs:
```haskell
module GhcBug where
import Control.Concurrent
main = putStrLn . show $ rtsSupportsBoundThreads
```
```
» ghc -main-is GhcBug GhcBug.hs && ./GhcBug
[1 of 2] Compiling GhcBug ( GhcBug.hs, GhcBug.o ) [Flags changed]
[2 of 2] Linking GhcBug
False
» ghc -threaded -main-is GhcBug GhcBug.hs && ./GhcBug
False
» ghc -fforce-recomp -threaded -main-is GhcBug GhcBug.hs && ./GhcBug
[1 of 2] Compiling GhcBug ( GhcBug.hs, GhcBug.o )
[2 of 2] Linking GhcBug [Objects changed]
True
```
## Expected behavior
I expect that the `-threaded` flag should tickle the recompilation checker and force the program to be relinked to the correct runtime.
## Environment
* GHC version used: 9.4.3 from Nixpkgs
Optional:
* Operating System: macOS
* System Architecture: aarch64https://gitlab.haskell.org/ghc/ghc/-/issues/22266Source shown in error messages can be wrong if file changes during compilation2024-02-21T13:50:13ZMichael Peyton JonesSource shown in error messages can be wrong if file changes during compilation## Summary
Sometimes the source shown in an error message can be wrong (too new) if the file is changed during compilation.
Example:
```
src/PlutusTx/AssocMap.hs:242:55: error: ...## Summary
Sometimes the source shown in an error message can be wrong (too new) if the file is changed during compilation.
Example:
```
src/PlutusTx/AssocMap.hs:242:55: error:
• Expecting two more arguments to ‘Map’
Expected a type, but ‘Map’ has kind ‘* -> * -> *’
• In the fourth argument of ‘PlutusTx.LiftU’, namely ‘Map’
In the stand-alone deriving instance for
‘PlutusTx.LiftU name uni fun Map’
|
242 | deriving newtype instance PlutusTx.LiftU name uni fun (Map k v)
| ^^^
```
I added the `k` and `v` parameters while the compilation was happening.
You can see that the source is wrong (it contains `k` and `v`), and caret (and the highlight) is in the wrong place (corresponding to the old source, I guess). I think the error is using the source location from the file at the _start_ of compilation, but reading the file back when the error is _reported_ to make the final message.
This is a bit of an edge case so it's probably not worth that much effort to fix!
## Steps to reproduce
1. Start compiling a file with an error in.
2. Edit the line with the error in before compilation finishes.
3. Observe that the wrong source appears.
## Expected behavior
I think the most reasonable behaviour is to show the source as it was when compilation began. This may require reading it in at that point and saving it until error reporting is done.
## Environment
* GHC version used: 8.10.7https://gitlab.haskell.org/ghc/ghc/-/issues/22234Backpack insufficiently thins interfaces when recompiling2022-09-29T22:46:28ZMatthew PickeringBackpack insufficiently thins interfaces when recompiling
The backpack test bkp44 started failing in the implementaiton of !8995, which provides stronger determinism guarantees for when interface files are loaded. It turns out that this revealed a latent issue in the recompilation checking log...
The backpack test bkp44 started failing in the implementaiton of !8995, which provides stronger determinism guarantees for when interface files are loaded. It turns out that this revealed a latent issue in the recompilation checking logic of backpack.
Here is a modified version of bkp44 which works with cabal - [bkp44-b.zip](/uploads/cd9d315fc1c9d8c7c4af229f940a93a6/bkp44-b.zip)
For reference, the equivalent `.bkp`:
```haskell
unit p where
signature A where
data T
signature B where
import A
y :: T
unit q where
dependency signature p[A=<C>,B=<D>]
signature C () where
signature D () where
```
The first time you build `bkp44-b`, the build works fine.
If you modify `B.hsig` to add anything, say `e :: Bool`, and run `cabal build` again, then you get a recompilation error:
```
Resolving dependencies...
Build profile: -w ghc-9.2.2 -O1
In order, the following will be built (use -v for more details):
- bkp44-b-0.1.0.0 (lib:p) (configuration changed)
- bkp44-b-0.1.0.0 (lib:q) (configuration changed)
Configuring library 'p' for bkp44-b-0.1.0.0..
Preprocessing library 'p' for bkp44-b-0.1.0.0..
Building library 'p' instantiated with
A = <A>
B = <B>
for bkp44-b-0.1.0.0..
Configuring library 'q' for bkp44-b-0.1.0.0..
Preprocessing library 'q' for bkp44-b-0.1.0.0..
Building library 'q' instantiated with
C = <C>
D = <D>
for bkp44-b-0.1.0.0..
<no location info>: error:
The identifier T does not exist in the signature for <C>
(Try adding it to the export list in that hsig file.)
```
If you turn on `-ddump-if-trace`, then you see `B.hi` is loaded to check if the hash is the same as before.
```
Reading interface for bkp44-b-0.1.0.0-inplace-p:B;
reason: need version info for B
readIFace /home/matt/Downloads/bkp44b/dist-newstyle/build/x86_64-linux/ghc-9.2.2/bkp44-b-0.1.0.0/l/p/build/p/B.hi
```
and then the error comes from `computeInterface` which attempts to rename the interface for `B` because `B` is instantiated to `D`.
In order to properly thin the module you need to know the exports of module `D` and apply that before the renaming happens (so we don't try to rename `y` and hence `T`, which are not part of the thinning). However it's not clear when loading the interface to check the hash of B how to determine what the exports of D are.. we haven't committed to compiling D yet and don't know if the interface is up to date.https://gitlab.haskell.org/ghc/ghc/-/issues/22188Add flag to omit self-recompilation avoidance information from interface files2023-09-07T10:36:56ZMatthew PickeringAdd flag to omit self-recompilation avoidance information from interface filesInterface files contain two kinds of information
1. The "ABI hash" which records when the externally visible interface has change (ie a new function, a decl has changed etc). This is used by modules which import the interface to determi...Interface files contain two kinds of information
1. The "ABI hash" which records when the externally visible interface has change (ie a new function, a decl has changed etc). This is used by modules which import the interface to determine whether the module has changed since last time we looked at it.
2. Other information which determines if we try to recompile the module, whether we need to recompile it or not. For example, information about the source hash of the module, what the module imports, what files the module depends on, what flags the module was compiled with.
The proposal is to add a flag which omits (2) from an interface file for the situation where you know you will never attempt to recompile a module. For example, if you are building a package for distribution. The motivation is that this reduces the surface area for interface file non-determinism to sneak into the build. See #10424 for a workaround for an issue to do with information for (2).9.10.1Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/21907GHC not noticing it should produce some new binary artifacts2022-07-25T09:21:21ZArtem PelenitsynGHC not noticing it should produce some new binary artifacts## Summary
Compile a binary (e.g. exectable) with no explicit flags, then compile again with `-dynamic-too`: you'd expect to have `*dyn*` files in the directory but there is none!
## Steps to reproduce
```
❯ cat Main.hs ...## Summary
Compile a binary (e.g. exectable) with no explicit flags, then compile again with `-dynamic-too`: you'd expect to have `*dyn*` files in the directory but there is none!
## Steps to reproduce
```
❯ cat Main.hs module Main where
main = pure ()
❯ ghc Main.hs [1 of 1] Compiling Main ( Main.hs, Main.o )
Linking Main ...
❯ ll .rwxrwxr-x 10M artem 22 Jul 21:52 Main
.rw-rw-r-- 646 artem 22 Jul 21:52 Main.hi
.rw-rw-r-- 33 artem 22 Jul 20:36 Main.hs
.rw-rw-r-- 2.8k artem 22 Jul 21:52 Main.o
❯ ghc Main.hs -dynamic-too 1 (0.088s) < 21:52:31
❯ ll .rwxrwxr-x 10M artem 22 Jul 21:52 Main
.rw-rw-r-- 646 artem 22 Jul 21:52 Main.hi
.rw-rw-r-- 33 artem 22 Jul 20:36 Main.hs
.rw-rw-r-- 2.8k artem 22 Jul 21:52 Main.o
```
## Expected behavior
I expect `*dyn*` files to materialize.
## Environment
* GHC version used: 9.2.3
Optional:
* Operating System: Linux
* System Architecture: x86_64
## Discussion
Apparently, this was discussed on Cabal bug tracker long ago: https://github.com/haskell/cabal/issues/4635
I looked at the ~"recompilation checking" label but didn't see anything relevant.https://gitlab.haskell.org/ghc/ghc/-/issues/21543`flagRecompile` is unreliable, because modifying a function doesn't necessari...2022-05-10T17:41:00ZZiyang Liuunsafefixio@gmail.com`flagRecompile` is unreliable, because modifying a function doesn't necessarily modify its fingerprintI ran into the following problem:
1. Module `Foo` contains a function `foo`. In `Foo.hi`, `foo` has no unfolding (because of the lack of `INLINABLE`, or `NOINLINE`, or `foo` is too large)
2. One modifies `Foo.foo`. Now `foo` is a differ...I ran into the following problem:
1. Module `Foo` contains a function `foo`. In `Foo.hi`, `foo` has no unfolding (because of the lack of `INLINABLE`, or `NOINLINE`, or `foo` is too large)
2. One modifies `Foo.foo`. Now `foo` is a different function, but its fingerprint in `Foo.hi` remains the same (this is not always the case, but it is sometimes).
3. There's a GHC plugin which depends on `Foo.foo`, and whose `pluginRecompile` is `flagRecompile`.
4. The plugin does not re-run after modifying `foo` because its fingerprint remains the same, even though its behavior has now changed.
So it seems 2 is the culprit. Is it possible to compute the fingerprint of a function from its definition, which ensures a different definition always has a different fingerprint?Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/21067Fat Interface Files2022-10-11T18:16:27ZMatthew PickeringFat Interface FilesThis is a new ticket which is related to #10871, the motivation is different here.
A "fat" interface file is a file which stores the core program at the end of simplification. The file can be read and deserialised so that compilation ca...This is a new ticket which is related to #10871, the motivation is different here.
A "fat" interface file is a file which stores the core program at the end of simplification. The file can be read and deserialised so that compilation can resume from this point and the core can be translated into STG and hence Bytecode.
We are motivated for two reasons
1. Faster GHCi startup time when using bytecode interpreter. You no longer have to typecheck and simplify every module every time you start GHCi.
2. If you can interpret everything (even package modules) makes TH evaluation much more resilient to ABI changes.
(Secret reason 3), if we distribute these files for all dependencies then you can generate code which passes types at runtime (as needed for a good implementation of typed template haskell)
A draft MR is in !7502https://gitlab.haskell.org/ghc/ghc/-/issues/20624There are no tests which test recompilation checking for the link step2021-11-10T16:43:57ZMatthew PickeringThere are no tests which test recompilation checking for the link stepThere aren't any tests which test the recompilation logic for the link step in --make mode. How do I know? I changed the output of this step and no tests needed to be updated.There aren't any tests which test the recompilation logic for the link step in --make mode. How do I know? I changed the output of this step and no tests needed to be updated.Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/20604New recompilation avoidance scheme is broken2023-02-21T12:45:07ZZubinNew recompilation avoidance scheme is brokenThe recompilation avoidance scheme introduced in the driver refactor (25977ab542a30df4ae71d9699d015bcdd1ab7cfb, !5661) is quite broken.
```haskell
-- | Find object files corresponding to the transitive closure of given home
-- modules a...The recompilation avoidance scheme introduced in the driver refactor (25977ab542a30df4ae71d9699d015bcdd1ab7cfb, !5661) is quite broken.
```haskell
-- | Find object files corresponding to the transitive closure of given home
-- modules and direct object files for pkg dependencies
mkObjectUsage :: PackageIfaceTable -> HscEnv -> ModuleNameWithIsBoot -> IO [Usage]
mkObjectUsage pit hsc_env mnwib = do
case hsc_interp hsc_env of
Just interp -> do
mps <- getLoaderState interp
case mps of
Just ps -> do
let ls = fromMaybe [] $ Map.lookup mnwib (module_deps ps)
ds = hs_objs_loaded ps
concat <$> sequence (map linkableToUsage ls ++ map librarySpecToUsage ds)
Nothing -> return []
Nothing -> return []
```
In particular, it records the hashes of all the objects that appear in the `LoaderState` at the time the `Usages` for the module is calculated.
This captures a lot of spurious dependencies:
- If a module doesn't use any splices, then we don't need to depend on any of the object code for its dependencies
- The object files for libraries that were loaded at any point previously (maybe due to other modules) are marked as dependencies due to `hs_objs_loaded`
This is not correct - we need to track package dependencies per module also
- `module_deps` can also contain spurious elements. If GHCi is being used, then `module_deps` will contain all the linkables needed by any expression in the module. However, we only want to track the linkables needed by *splice expressions*.
In addition to this, adding object file hashes to the interface file breaks interface file determinism. We should only record object file hashes if TH splices (or plugins) were used, since it is very hard to guarantee interface file determinism in the presence of those anyway.
Here is a small program demonstrating some of the issues:
```haskell
{-# LANGUAGE TemplateHaskell #-}
module A where
x = $([| True |])
```
```haskell
module A1 where
import A
```
```bash
$ ghc A1.hs
[1 of 2] Compiling A ( A.hs, A.o )
[2 of 2] Compiling A1 ( A1.hs, A1.o )
$ ghc --show-iface A1.hi | grep addDependentFile
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/ghc-boot-th-9.3/HSghc-boot-th-9.3.o" 6df4b8028fd47cd291fea78438a8250b
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/template-haskell-2.18.0.0/HStemplate-haskell-2.18.0.0.o" da4fd244da67d45d8e94a312ac792aaf
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/pretty-1.1.3.6/HSpretty-1.1.3.6.o" 9670d3caeb961caf44e1ac46788079b1
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/deepseq-1.4.4.0/HSdeepseq-1.4.4.0.o" 0aac1c4af6e53e59b3f75af35bd4aab0
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/array-0.5.4.0/HSarray-0.5.4.0.o" a3a8757cd570e6f05c6f199e690cb024
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/base-4.16.0.0/HSbase-4.16.0.0.o" 02b5d686cb9c79360c6e0f0dad4f774c
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/ghc-bignum-1.2/HSghc-bignum-1.2.o" 7760f8c24acb1873f013b367e1ab6e07
addDependentFile "/home/zubin/ghc/_build_devel2/stage1/lib/../lib/x86_64-linux-ghc-9.3.20211011/ghc-prim-0.8.0/HSghc-prim-0.8.0.o" 9fa874d534ef0fad8ea8cca54ffbdaf1
$ rm A1.hi
$ ghc A1.hs
[2 of 2] Compiling A1 ( A1.hs, A1.o )
$ ghc --show-iface A1.hi | grep addDependentFile
$ echo $? # no matches
1
```9.4.1Matthew PickeringZubinMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/20597Reloading in ghci fails to pick-up new files2021-11-05T12:09:03ZMatthew PickeringReloading in ghci fails to pick-up new filesIf I start with a directory structure like this:
```
.
└── b
└── B.hs
```
And start GHCi
```
ghci -i -i. -ib B
GHCi, version 8.10.2: https://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling B ( b/B.hs, interpret...If I start with a directory structure like this:
```
.
└── b
└── B.hs
```
And start GHCi
```
ghci -i -i. -ib B
GHCi, version 8.10.2: https://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling B ( b/B.hs, interpreted )
Ok, one module loaded.
```
Then create a new file in the root,
```
.
├── b
│ └── B.hs
└── B.hs
```
Then reloading doesn't load the new file.
```
*B> :r
Ok, one module loaded.
```
Is this a bug or not? Either way, there's no test for this behavior as I disabled the feature on my branch and no relevant tests fail.https://gitlab.haskell.org/ghc/ghc/-/issues/20522Backpack puts information in the EPS that depends on the HPT, causing issues ...2022-02-23T20:02:02Zsheafsam.derbyshire@gmail.comBackpack puts information in the EPS that depends on the HPT, causing issues with recompilationI've noticed a strange interaction of Backpack with `GHCi`. For readability I'm giving the test case as a `.bkp`, but note that as `--backpack` isn't supported by `GHCi`, the actual test case uses cabal.
```haskell
unit p where
sign...I've noticed a strange interaction of Backpack with `GHCi`. For readability I'm giving the test case as a `.bkp`, but note that as `--backpack` isn't supported by `GHCi`, the actual test case uses cabal.
```haskell
unit p where
signature H where
data S1
data S2
module A where
import H
data T = T S1 S2
unit q where
dependency p[H=<H2>] (A as A2)
module L where
data S1 = MkS1
signature H2(S1(MkS1), S2) where
import L
data S2
module B where
import A2
import H2
t = T :: S1 -> S2 -> T
```
When processing `q`, we instantiate `p` with `H = H2` and add it to the EPS, even though it refers to `L` and `H2` which are in the HPT. This is a problem, as the EPS is supposed to only contain stable information, whereas the HPT can be updated; any change to the HPT will not be reflected in the EPS and thus will refer to out of date information.
To demonstrate this, we can load everything in GHCi, change `H2` and reload. (Recall: using cabal, not `--backpack` mode which doesn't work with `GHCi`.)
```
[1 of 2] Compiling H[sig] ( p\H.hsig, nothing )
[2 of 2] Compiling A ( p\A.hs, nothing )
[1 of 1] Instantiating bkp10-0-inplace-p
[1 of 4] Compiling H2[sig] ( q\H2.hsig, nothing )
[2 of 4] Instantiating bkp10-0-inplace-p
[3 of 4] Compiling B ( q\B.hs, nothing )
[4 of 4] Compiling L ( q\L.hs, nothing )
Ok, three modules loaded.
now I change H2 so that S1 is defined in H2 instead of imported from L
ghci> :r
[2 of 4] Compiling H2[sig] ( q\H2.hsig, nothing ) [Source file changed]
[3 of 4] Instantiating bkp10-0-inplace-p
[4 of 4] Compiling B ( q\B.hs, nothing ) [H2 changed]
q\B.hs:4:9: error:
* Couldn't match type `{H2.S1}' with `S1'
Expected: S1 -> S2 -> T
Actual: {H2.S1} -> S2 -> T
NB: `S1' is defined at q\L.hs:3:3-16
`{H2.S1}' is defined at q\H2.hsig:3:5-11
if I quit and restart, it works:
[1 of 1] Instantiating bkp10-0-inplace-p
[3 of 4] Instantiating bkp10-0-inplace-p
[4 of 4] Compiling B ( q\B.hs, nothing ) [H2 changed]
Ok, three modules loaded.
```