Description
Here is an hls branch with a broken test case (only runs on ghc-9.2):
https://github.com/lf-/haskell-language-server/tree/hlint-flags-bug
and the commit, for convenience: lf-@8a90d27
The issue happens in this source:
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedRecordDot #-}
module Foo (Node(..)) where
data Node = Node
{
label :: ()
}
instance Semigroup Node where
n1 <> n2 = Node
{ label = n1.label <> n2.label
-- ^^^ this is a parse error because "label" is undocumentedly a reserved word when -XForeignFunctionInterface is enabled (which it is by default)
}
The bug is that hls' hlint plugin will trigger parse errors, even if the hlint.yaml has -XNoForeignFunctionInterface
in it, and also even if the cradle provides it.
It is "fixable" in a project by "haskell.plugin.hlint.config.flags": ["-XNoForeignFunctionInterface"]
.
The cause of this bug is that the disabled language extensions are not correctly propagated to hlint when hlint is called: only enabled extensions are propagated:
haskell-language-server/plugins/hls-hlint-plugin/src/Ide/Plugin/Hlint.hs
Lines 318 to 321 in 1bc1def
Unfortunately, actually retrieving disabled extensions is significantly frustrated by OnOff (https://hackage.haskell.org/package/ghc-9.2.4/docs/src/GHC.Driver.Session.html#OnOff) being a private member of GHC.Driver.Session, so it is impossible to get the disabled extensions out of DynFlags.extensions
without more or less doing something like read . dropOnOffPrefix . show
.
So what I am 99% sure is happening, based on putting traces in both sides, is that ForeignFunctionInterface
is absent from the enabledExtensions
passed to hlint if the cradle is configured with -XNoForeignFunctionInterface
, but it is then reenabled because it is a default extension.
I got fairly far in fixing this, but ran up against this brick wall, and don't really have more time to commit to fixing it. So I am filing this report with the hopes that it will at least be easier to fix. I found some time :)
Your environment
..
Steps to reproduce
Run the test suite from https://github.com/lf-/haskell-language-server/tree/hlint-flags-bug
Expected behaviour
Should pass :)
Actual behaviour
src/Test/Hls/Util.hs:317:
Got unexpected diagnostics for Uri {getUri = "file:///Users/jade/co/haskell-language-server/plugins/hls-hlint-plugin/test/testdata/lab
elkeyword/LabelKeyword.hs"} got [Diagnostic {_range = Range {_start = Position {_line = 11, _character = 17}, _end = Position {_line = 11, _
character = 22}}, _severity = Just DsInfo, _code = Just (InR "parser"), _source = Just "hlint", _message = "/Users/jade/co/haskell-language-
server/plugins/hls-hlint-plugin/test/testdata/labelkeyword/LabelKeyword.hs:12:18: error:\n parse error on input `label'\n instance Semig
roup Node where\n n1 <> n2 = Node\n> { label = n1.label <> n2.label\n }\n\n", _tags = Nothing, _relatedInformation = Nothing}]