haskell / haskell-ide-engine

The engine for haskell ide-integration. Not an IDE
BSD 3-Clause "New" or "Revised" License
2.38k stars 211 forks source link

HIE unnecessarily reloads modules #1691

Open expipiplus1 opened 4 years ago

expipiplus1 commented 4 years ago

I have created a minimal repro here: https://github.com/expipiplus1/hie-reload-example

The gist of it is, I have loaded a project in which module Foo depends on Bar. I make an edit to Foo and both Foo and Bar are reloaded. I would expect that only Foo would be reloaded as would happen in ghci using the :r command.

One can see Bar being reloaded here: https://github.com/expipiplus1/hie-reload-example/blob/master/hie.log#L113

This makes quite a difference in very large projects.

I was very surprised to see this, so perhaps I am driving things in an unusual way or doing something else wrong.

charlescrain commented 4 years ago

I'm also experiencing the same issue, if I save a my Main.hs, it reloads the entire library it depends on. This makes for a really long feedback loop.

fendor commented 4 years ago

@expipiplus1 Does it happen when you set an explicit component, too? E.g.

cradle:
  cabal:
    component: "lib:hie-reload-example"
fendor commented 4 years ago

Probably part of the problem is shown in line:

2020-03-11 10:37:23.385812562 [ThreadId 48] - setTargets: [("/home/j/projects/bugs/reload/src/Foo.hs","/run/user/1000/haskell-lsp17296/Foo.hs-00000--4428135201160501691.hs")]

The targets should contain Bar.hs

EDIT: flags obtained with hie-bios look fine:

$ hie-bios flags .\src\Foo.hs
Options: ["-fbuilding-cabal-package","-O0","-outputdir","D:\\Privat\\Documents\\programming\\haskell\\hie-reload-example
\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build","-odir","D:\\Privat\\Documents\\prog
ramming\\haskell\\hie-reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build",
"-hidir","D:\\Privat\\Documents\\programming\\haskell\\hie-reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6
.5\\hie-reload-example-0.0.0\\build","-stubdir","D:\\Privat\\Documents\\programming\\haskell\\hie-reload-example\\dist-n
ewstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build","-i","-iD:\\Privat\\Documents\\programming\\
haskell\\hie-reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build","-iD:\\Pr
ivat\\Documents\\programming\\haskell\\hie-reload-example\\src","-iD:\\Privat\\Documents\\programming\\haskell\\hie-relo
ad-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build\\autogen","-iD:\\Privat\\Do
cuments\\programming\\haskell\\hie-reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0
.0.0\\build\\global-autogen","-ID:\\Privat\\Documents\\programming\\haskell\\hie-reload-example\\dist-newstyle\\build\\x
86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build\\autogen","-ID:\\Privat\\Documents\\programming\\haskell\\hie-
reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build\\global-autogen","-ID:\
\Privat\\Documents\\programming\\haskell\\hie-reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reloa
d-example-0.0.0\\build","-IC:\\tools\\msys64\\mingw64\\include","-optP-include","-optPD:\\Privat\\Documents\\programming
\\haskell\\hie-reload-example\\dist-newstyle\\build\\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\build\\autogen
\\cabal_macros.h","-LC:\\tools\\msys64\\mingw64\\lib","-this-unit-id","hie-reload-example-0.0.0-inplace","-hide-all-pack
ages","-Wmissing-home-modules","-no-user-package-db","-package-db","C:\\Users\\Privat\\AppData\\Roaming\\cabal\\store\\g
hc-8.6.5\\package.db","-package-db","D:\\Privat\\Documents\\programming\\haskell\\hie-reload-example\\dist-newstyle\\pac
kagedb\\ghc-8.6.5","-package-db","D:\\Privat\\Documents\\programming\\haskell\\hie-reload-example\\dist-newstyle\\build\
\x86_64-windows\\ghc-8.6.5\\hie-reload-example-0.0.0\\package.conf.inplace","-package-id","base-4.12.0.0","-XHaskell2010
","Bar","Foo","Paths_hie_reload_example","-hide-all-packages"]
Dependencies: ["hie-reload-example.cabal","cabal.project"]
fendor commented 4 years ago

Looks like the problem that #1526 aimed to solve.

expipiplus1 commented 4 years ago

For anyone else finding this, #1526 isn't the whole solution.

From @fendor on IRC

it would require more investigation. The invocation is correct, but targets are a bit unexpected.

expipiplus1 commented 4 years ago

Seems to happen with explicit flags (with the bios cradle too). As far as I can tell #1526, seems to just change telemetry options (the important commit seems to have been reverted) which would explain why it made no difference, although nothing seems to change without that revert either.

Just to check, has this always been the behavior of HIE, reloading every module on every edit?

fendor commented 4 years ago

Reloading modules, yes, otherwise we cant tell which modules need changes after one of their module dependencies have changed. However, that should be fast, comparable to a :r in ghci (almost identical since it is the same mechanism). Actually, how fast/slow is it? I grep'd for occurrences of New cradle and that looked fine.

expipiplus1 commented 4 years ago

Ah, I was wrong, at least for my small test case. With #1526 (without the reverting commit) Bar.hs is not reloaded.

I still suffer from this in a larger project (with very slow reloading), perhaps this is due to

I can confirm that ghci with the same flags does not reload modules as eagerly.

Thanks for the generous help so far, @fendor

fendor commented 4 years ago
  • Use of Template Haskell
  • Use of hs-boot files

Yeah, both of these are not well supported and cause regular problems :(

expipiplus1 commented 4 years ago

right, that explains it, hopefully this will be better with HLS! Happy to have this closed if these issues are already mentioned elsewhere, not that it really matters much in the hie repo :)