Open eltix opened 2 years ago
HLS tries to typecheck/index all files on startup by default (though this is configurable). However, this depends on us knowing all the targets which exist, which need to be enumerated by the hie-bios cradle. I think cabal and stack cradles do this by default. You should check that your cradle lists out all the targets (module names or file names) in the options that it passes to HLS, using something like hie-bios flags src/File.hs
Maybe we should have an option to load all components on start by default?
@wz1000 Thank you for your answer. We will investigate this further on our side and will either come back with more info or close the issue.
I can confirm that all the files and flags are correctly passed to HLS using a hie.yaml
file as simple as:
cradle:
bios:
shell: "generate_flags_for_project > $HIE_BIOS_OUTPUT"
The generate_flags_for_project
generate a static list of flags: it does not depend on the file being observed and always return the flags / files for the complete project.
Even when waiting for the end of the indexing
phase from HLS (It can take a few minutes), the different references from other files are not available.
However, as @eltix already described it, opening a file which contains a reference fix the reference informations. I also observed that removing the symbol we care about from export list of the module then adding it again does "update" the DB.
The problem is perfectly reproducible when the use of the symbol is in a Main
module and when you have multiples Main
module in the environment. I'm still trying to reproduce this in a different context.
In https://github.com/haskell/haskell-language-server/commit/89a3e627e6f6b9d5646811cad04c7e68334f80b9 I designed a reproduction.
There are two non-Main
modules: dirA/A.hs
and dirB/B.hs
which are named A
and B
.
Then C.hs
and D.hs
are Main
modules which reference a
and b
from A
and B
. Note that a
is also referenced in B
.
A.hs
and look for reference to a
, it will only find the references in B
and D
.C.hs
and go back to A.hs
and look for reference to a
, it will find one in B
,C
, but not D
anymore.D.hs
and go back to A.hs
and look for reference to a
. it will find one in B
, C
, and D
I observed the hiedb
file and it is interesting:
After opening A.hs
the first time, it shows a reference in Main
at line 13
.
hiedb -D ~/.cache/ghcide/1634d290c00070ae2b558ef43dc6d2a8855d6436-hls_repro_reverse_search-9.0.2-1.hiedb name-refs a
B:5:5-5:6
Main:13:10-13:11
A:3:1-3:2
But after opening C.hs
, the reference change:
hiedb -D ~/.cache/ghcide/1634d290c00070ae2b558ef43dc6d2a8855d6436-hls_repro_reverse_search-9.0.2-1.hiedb name-refs a
B:5:5-5:6
A:3:1-3:2
Main:5:10-5:11
My conclusion here is that references are stored in the db using module name, and if we have multiples modules with the same name, this leads to conflict.
Should this be considered a bug in HLS or a bug in the way we are using HLS?
Your environment
Which OS do you use?
Ubuntu 20.04
Which version of GHC do you use and how did you install it?
GHC 9.2.3
How is your project built (alternative: link to the project)?
Nix+bazel
Which LSP client (editor/plugin) do you use?
We're using
VSCode
with theHaskell
pluginSteps to reproduce
In any project, "Find all references" does not reference files that have not been indexed by HLS. From what we've empirically inferred, it seems that HLS only lists the references appearing in already indexed files and indexing is lazy. Files that have never been indexed (because they're leaves of the dependency tree and have never been opened in the editor) are off the radar. After opening said files, "Find all references" does list all the references. This kind of defeats the purpose of the feature since one has first to
Ctrl-Shift-F
the function of interest, open the search hits in the editor and then use the "Find all references". The fact that one cannot "trust" the result of "Find all references" because it depends on the history of opened files in the editor is a problem. It would be more accurate to call the feature "Find some references (warning: lazy search)" or something similar.Expected behaviour
One would expect "Find all references" to find all references
Actual behaviour
"Find all references" does not find all references.