Why doesn't HLS under emacs lsp use the GHC it was compiled with?

In my .emacs file I have configured lsp to use the 9.0.2 version of HLS.

(custom-set-variables
'(lsp-haskell-server-path "haskell-language-server-9.0.2~2.4.0.0")
)

I have ghc-9.0.2 installed, but my default GHC is set, by ghcup, to be ghc-9.4.7. That is, the ghc in my path is a symlink to ghc-9.4.7. This causes emacs to say

ghcide compiled against GHC 9.4.7 but currently using 9.0.2. This is unsupported, ghcide must be compiled with the same GHC version as the project.

But why? ghc-9.0.2 is right there in my path. Can HLS really not find it? Does HLS always use ghc from PATH? That seems pretty inflexible to me. Is this configuration considered invalid?

Have you set with-compiler in your cabal.project file? If so, I think we should probably honour that. Otherwise I don’t think we have any particular reason to know that the user has installed a GHC version on the path with that name. It’s a convention you happen to use. Similarly, if you run cabal build it will just use ghc.

1 Like

I haven’t set with-compiler, no.

Otherwise I don’t think we have any particular reason to know that the user has installed a GHC version on the path with that name

I suppose not. In which case, am I setting up lsp incorrectly? It never makes sense to use a version of HLS that differs from the ghc that it will pick. Should I just be using haskell-language-server-wrapper-2.4.0.0, and allow it to pick, as per What is haskell-language-server? — haskell-language-server 2.4.0.0 documentation?

Yes, this is a large part of what the wrapper is for. It means we can work out what GHC your project us using and then launch the right HLS. What you have written in your config amounts to a promise that you are using a particular GHC everywhere, which it seems that you aren’t.

If you don’t want to use the wrapper, an alternative is to use direnv/dir-locals to ensure you have a matching GHC/HLS pair in any given project (this is usually what nix users do).

1 Like

I see. I was trying to be “helpful” by specifying a specific version of HLS, but it turns out that’s not what I was supposed to be doing at all. I’ll just use the wrapper. Thanks Michael!

ghcup run --hls recommended --ghc recommended -- emacs .

1 Like

Very nice!