haskell-language-server
haskell-language-server copied to clipboard
Ormolu/Fourmolu incorrectly infers `GHC2021` in Stack projects
Summary: Formatting via HLS moves my qualified keywords as if I had the ImportQualifiedPost plugin enabled, which I do not. Interestingly, this bug only seems to occur in projects using GHC 9.2.5?
Note that I've tried the standalone ormolu (0.5.1) and this problem does not occur. I can't figure out how to check which version of ormolu my HLS is using, however...
Your environment
Which OS do you use?
Ubuntu 20.04
Which version of GHC do you use and how did you install it?
9.2.5, installed via stack.
NOTE: I tried this in an older project, using GHC 9.0.2 (also via stack), and the bug did NOT occur.
How is your project built (alternative: link to the project)?
stack
Which LSP client (editor/plugin) do you use?
Tried in neovim 0.8.2 and vs code 1.74.2 with same result.
Which version of HLS do you use and how did you install it?
HLS 1.9.0, via ghcup.
Have you configured HLS in any way (especially: a hie.yaml file)?
No extra configs
Steps to reproduce
- Verify that
ImportQualifiedPostis not enabled anywhere in the project - Add a qualified import
- Use HLS to format the file
Expected behaviour
The following import should remain as-is:
import qualified Data.Text as T
Actual behaviour
The import is altered, qualified is moved:
import Data.Text qualified as T
Debug information
N/A
Ah, I wonder if this is related to GHC2021! That includes ImportQualifiedPost.
From the docs:
GHC2021is used by GHC if neitherHaskell98norHaskell2010is turned on explicitly.
The only extension I have enabled explicitly in this project is OverloadedStrings. Does this mean that the extension is enabled implicitly? Though if that were the case, I would expect the project to build. However, after formatting the file:
$ stack build
kept-0.1.0.0: unregistering (local file changes: src/Parse.hs)
kept> build (lib + exe)
Preprocessing library for kept-0.1.0.0..
Building library for kept-0.1.0.0..
/mnt/backup/Programming/kept/src/Parse.hs:3:18: error:
Found ‘qualified’ in postpositive position.
To allow this, enable language extension 'ImportQualifiedPost'
|
3 | import Data.Text qualified as T
| ^^^^^^^^^
-- While building package kept-0.1.0.0 (scroll up to its section to see the error) using:
/home/ktf/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.6.3.0_ghc-9.2.5 --verbose=1 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.6.3.0 build lib:kept exe:kept --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
And add to this the fact that standalone ormolu does not make this formatting change. Very curious that the behavior would differ.
Happy to close this if it's not an HLS bug after all. Just documenting my findings here in case it is, and/or in case it helps others who come across this strange behavior.
Addendum:
After adding GHC2021 explicitly, the project builds. Also, with it explicitly enabled, standalone ormolu does move the qualified keyword in the same way as the HLS version.
Looks like there's some discrepancies -- not sure whether with HLS, ormolu, stack, or all of the above -- with the way the GHC2021 status is inferred.
I'm leaving it explicitly enabled, which seems to be the best choice anyway to avoid confusion.
I'll leave this issue open for now in case HLS is one of the offenders here, or any changes need to be made. But TBH, based on the GHC docs I linked above, HLS seems to be the only one doing the expected thing :smile:
Also came across https://github.com/haskell/haskell-language-server/issues/2927, which could be related.
I've been using Fourmolu and Ormolu (mostly the former, but the plugins are implemented very similarly) on GHC 9.2 for over half a year, and I've found that GHC2021 has been inferred when, and only when, I'd expect, including the default-language field being respected. Ormolu, on the command line, also correctly reads from default-language and default-extensions.
I don't use Stack though.
Actually, reading again, could you clarify what the current issue is? It sounds like HLS is doing nothing wrong, and the issue may be that Stack or Ormolu incorrectly fails to infer GHC2021? Do you have a default-language field?
Actually, reading again, could you clarify what the current issue is?
Sure thing, apologies. Now that I've poked around a bit more I understand the issue better and can summarize:
- My
default-languagewas set toHaskell2010. I did not have theImportQualifiedPostextension enabled, just to be clear. - When I formatted a source file (that contained
qualifiedimports) using ormolu (via HLS), thequalifiedkeywords were moved to the end, as if I were usingImportQualifiedPostorGHC2021. - With these changes -- i.e. after using the HLS to format a file -- my project would not build. (Which makes perfect sense, since I wasn't using
ImportQualifiedPostorGHC2021. But just noting as a sanity check.) - When I formatted that same source file with standalone ormolu, from the command-line, it didn't move my imports. (i.e. the behavior I would expect.) The issue only seems to occur with the version of ormolu that HLS is using.
It sounds like HLS is doing nothing wrong, and the issue may be that Stack or Ormolu incorrectly fails to infer
GHC2021?
I'm honestly not sure where this bug lies. Is there a way to check which version of ormolu HLS is using? I couldn't find it, if so. I'm only seeing the bug when using HLS, but it could still be an ormolu issue.
I don't think there's a Stack issue, though -- that was my own misreading of the GHC docs. Stack is doing the right thing, as far as I can tell.
By the way, a quick way to reproduce this is to just create a new stack project and add a qualified import:
$ stack new testing
$ cd testing
$ stack build # succeeds
Then open up, e.g., app/Main.hs, and change import Lib to import qualified Lib and format the file using the HLS. This moves qualified to the end. The build will now fail:
Found ‘qualified’ in postpositive position.
To allow this, enable language extension 'ImportQualifiedPost'
Note that the generated .cabal file explicitly sets Haskell2010 (and ImportQualifiedPost isn't enabled anywhere):
default-language: Haskell2010
Here's everything I've got installed, all via ghcup:
✔✔ ghc 9.2.5 recommended,base-4.16.4.0 hls-powered
✔✔ cabal 3.6.2.0 recommended
✔✔ hls 1.9.0.0 latest,recommended
✔✔ stack 2.9.1 recommended
✔✔ ghcup 0.1.19.0 latest,recommended
(Though of course the version of GHC that stack is using is the one from the LTS. Still 9.2.5 though.)
Thanks, can reproduce with Stack, and interestingly not with a similar Cabal skeleton project.
hello, has this been fixed or is there a recommended way to handle this? Thanks