haskell-language-server icon indicating copy to clipboard operation
haskell-language-server copied to clipboard

hls-hlint-plugin: Build fails with ghc-lib >= 9.0 and ghc <= 8.10.7

Open maralorn opened this issue 3 years ago • 18 comments

I am trying to build hls-hlint-plugin in the above mentioned combination.

I get the following error:

src/Ide/Plugin/Hlint.hs:132:44: error:
    • The constructor ‘GHC.RealSrcSpan’ should have 2 arguments, but has been given 1
    • In the pattern: GHC.RealSrcSpan x
      In the pattern: (GHC.RealSrcSpan x, y)
      In the pattern: (, Nothing) -> (GHC.RealSrcSpan x, y)
    |
132 | pattern RealSrcSpan x y <- ((,Nothing) -> (GHC.RealSrcSpan x, y))
    |                                            ^^^^^^^^^^^^^^^^^

src/Ide/Plugin/Hlint.hs:230:23: error:
    • The constructor ‘RealSrcSpan’ should have no arguments, but has been given 2
    • In the pattern: RealSrcSpan span _
      In an equation for ‘srcSpanToRange’:
          srcSpanToRange (RealSrcSpan span _)
            = Range
                {_start = Position
                            {_line = fromIntegral $ srcSpanStartLine span - 1,
                             _character = fromIntegral $ srcSpanStartCol span - 1},
                 _end = Position
                          {_line = fromIntegral $ srcSpanEndLine span - 1,
                           _character = fromIntegral $ srcSpanEndCol span - 1}}
      In an equation for ‘rules’:
          rules plugin
            = do define $ \ GetHlintDiagnostics file -> ...                 defineNoFile $ \ GetHlintSettings -> ...
                 action
                   $ do files <- getFilesOfInterestUntracked
                        ....
            where
                diagnostics ::
                  NormalizedFilePath -> Either ParseError [Idea] -> [FileDiagnostic]
                diagnostics file (Right ideas)
                  = [(file, ShowDiag, ideaToDiagnostic i) |
                       i <- ideas, ideaSeverity i /= Ignore]
                diagnostics file (Left parseErr)
                  = [(file, ShowDiag, parseErrorToDiagnostic parseErr)]
                ideaToDiagnostic :: Idea -> Diagnostic
                ideaToDiagnostic idea
                  = Diagnostic
                      {_range = srcSpanToRange $ ideaSpan idea, _severity = Just DsInfo,
                       _code = Just (InR $ T.pack $ codePre ++ ideaHint idea),
                       _source = Just "hlint", _message = idea2Message idea,
                       _relatedInformation = Nothing, _tags = Nothing}
                  where
                      codePre = ...
                ....
    |
230 |       srcSpanToRange (RealSrcSpan span _) = Range {

I might be holding it wrong, but my impression is, that this line should not compare ghc, but ghc-lib versions.

https://github.com/haskell/haskell-language-server/blob/3b687a52acdd1662d316d9e369d04c2919ed9a98/plugins/hls-hlint-plugin/src/Ide/Plugin/Hlint.hs#L139

If someone more knowledgeable (e.g. @fendor) could tell me if that’s right, I‘d be very grateful.

maralorn avatar Feb 20 '22 22:02 maralorn

My initial assumption about what the problem is, was wrong.

https://github.com/haskell/haskell-language-server/blob/3b687a52acdd1662d316d9e369d04c2919ed9a98/plugins/hls-hlint-plugin/src/Ide/Plugin/Hlint.hs#L142

I could fix the problem for this specific config by replacing the above line with

pattern RealSrcSpan x y <- ((,Nothing) -> (GHC.RealSrcSpan x Nothing, y))

The other solution did not work because then I got a mismatch in the type of BufSpan (the ghc or ghc lib BufSpan vs. the IDE Compat BufSpan).

maralorn avatar Apr 14 '22 10:04 maralorn

That fix isn‘t a fix after all. We get the following runtime error:

Source:   compiler
Severity: DsError
Message: 
  src/Ide/Plugin/Hlint.hs:(250,7)-(258,48): Non-exhaustive patterns in function srcSpanToRange

maralorn avatar May 24 '22 10:05 maralorn

cc @pepeiborra

michaelpj avatar May 24 '22 11:05 michaelpj

I've actually also observed that runtime error in HLS from nixpkgs recently.

michaelpj avatar May 24 '22 11:05 michaelpj

Currently you need to build hlint with the ghc-lib flag until https://github.com/ndmitchell/hlint/issues/1376 is fixed and released

pepeiborra avatar May 24 '22 11:05 pepeiborra

Is there an example for how to build hlint with the ghc-lib with nix? Do you override the Haskell package HLS inputs somehow?

mjrussell avatar May 24 '22 14:05 mjrussell

Looks like there is an incomplete pattern match in the hls-hlint-plugin itself? Perhaps this wasn't noticed before because the code path was CPP'd out.

pepeiborra avatar May 24 '22 14:05 pepeiborra

Presumably from here?

https://github.com/haskell/haskell-language-server/blob/master/plugins/hls-hlint-plugin/src/Ide/Plugin/Hlint.hs#L258-L267

It doesn't look non-exhaustive to me and it doesn't look like its changed in a recent GHC version to add a new constructor. Am I missing something obvious?

mjrussell avatar May 24 '22 15:05 mjrussell

The runtime error in nixpkgs could totally be my fault, because I have added this line in nixpkgs to make the setup compile:

https://github.com/NixOS/nixpkgs/blob/8d8b6e8f442c658f53ae4b10a5060adbd1859c56/pkgs/development/haskell-modules/configuration-ghc-8.10.x.nix#L97

maralorn avatar May 24 '22 21:05 maralorn

Ohhhh, yes indeed I think that could be the culprit

Stepping back for a second, and sorry if this is obvious as I'm a bit new to GHC Lib, but shouldn't we be trying to compile GHC-Lib 8.10.7 with GHC 8.10.7? Can we force the package bounds in the nix derivation?

[edit below]

Im wondering if hls-hlint-plugin = addBuildDepend self.ghc-lib_8_10_7 ... would work without a patch.

mjrussell avatar May 24 '22 21:05 mjrussell

I believe your initial assessment was indeed correct. The pragma line should be changed from

#if MIN_VERSION_ghc(9,0,0)

to

#if MIN_GHC_API_VERSION(9,0,0)

It was changed from the latter to the former in #2128, probably by mistake, when updating the pattern synonym to take two arguments instead of one.

anka-213 avatar May 26 '22 06:05 anka-213

I believe your initial assessment was indeed correct. The pragma line should be changed from

#if MIN_VERSION_ghc(9,0,0)

to

#if MIN_GHC_API_VERSION(9,0,0)

It was from the latter to the former in #2128, probably by mistake, when updating the pattern synonym to take two arguments instead of one.

I think it has been fixed in a recent commit

July541 avatar May 26 '22 06:05 July541

The change to

pattern RealSrcSpan x y <- ((,Nothing) -> (GHC.RealSrcSpan x Nothing, y))

would assert that the second field must be nothing, which is what caused the non-exhaustive pattern match error.

The correct version would be

pattern RealSrcSpan x y <- ((,Nothing) -> (GHC.RealSrcSpan x y, _))

but that is just equivalent to

pattern RealSrcSpan x y <- GHC.RealSrcSpan x y

which is what the other branch of the #if says.

(All of these versions only works with the ghc-9 api, since that's where GHC.RealSrcSpan was changed to have two fields instead of one)

anka-213 avatar May 26 '22 07:05 anka-213

I think it has been fixed in a recent commit

Yes, #2854 seems to have fixed it.

@maralorn Can you try with the latest version from master and see if it works now?

anka-213 avatar May 26 '22 10:05 anka-213

Ah, well I hadn‘t dabbled with pattern synonyms before and got confused somewhere along the way.

The easiest way for me to try this is out is waiting for the next release. Depending on when that happens I‘d rather wait for that.

maralorn avatar May 26 '22 21:05 maralorn

@maralorn do you know when that release will be? I'd love to get this working again and am happy to try to build it if I can get some instructions on how to do so. It wasn't super obvious how to do so in the nixpkgs repo

mjrussell avatar Jun 01 '22 04:06 mjrussell

Is there a workaround for getting hlint to work with hls on 8.10.7 in nix?

shinzui avatar Jun 16 '22 05:06 shinzui

@shinzui Since this is now a downstream issue, I have continued the discussion here: https://github.com/NixOS/nixpkgs/issues/168064

maralorn avatar Jun 16 '22 08:06 maralorn

GHC 8.10.7 is no longer supported

michaelpj avatar Jan 16 '24 17:01 michaelpj