haskell / haskell/haskell-language-server
`-fno-max-refinement-hole-fits` is ignored
- Dominant language
- Haskell
- Stars
- 3k
- Forks
- 455
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 13
Description
### Your environment
Which OS do you use? ArchLinux
Which version of GHC do you use and how did you install it? 9.14.1 GHCup
How is your project built (alternative: link to the project)? See below
Which LSP client (editor/plugin) do you use? Terminal Vim + YCM
Which version of HLS do you use and how did you install it? 2.14.0.0 via GHCup
Have you configured HLS in any way (especially: a `hie.yaml` file)? No
### Steps to reproduce
```app.cabal
cabal-version: 3.4
name: app
version: 0.1.0.0
executable app
main-is: Main.hs
build-depends: base
hs-source-dirs: .
default-language: GHC2024
```
```cabal
packages: .
package *
ghc-options: -fno-defer-typed-holes
with-compiler: ghc-9.14.1
```
```haskell
-- This is just because to bring the number of valid holes to 7 (i.e. above the
-- default of 6)
fun :: Int -> [Int] -> [Int]
fun = _
main :: IO ()
main = do
let x :: [Int] = _ (_ :: Int) (_ :: [Int])
print x
```
Ask for diagnostics on the first `_` on line 9. You'll get:
```none
• Found hole: _ :: Int -> [Int] -> [Int]
• In the expression: _ (_ :: Int) (_ :: [Int])
In a pattern binding: x :: [Int] = _ (_ :: Int) (_ :: [Int])
In a stmt of a 'do' block:
let x :: [Int] = _ (_ :: Int) (_ :: [Int])
• Relevant bindings include
main :: IO () (bound at /home/enrico/deleteme/app/Main.hs:8:1)
Valid hole fits include
fun
(:)
drop
take
(<$)
mempty
(Some hole fits suppressed; use -fmax-valid-hole-fits=N or -fno-max-valid-hole-fits)
Valid refinement hole fits include
($!) _
const _
flip _
curry _
(!!) _
id _
(Some refinement hole fits suppressed; use -fmax-refinement-hole-fits=N or -fno-max-refinement-hole-fits) [GHC-88464]
```
revealing that the default of 6 for both `-fmax-valid-hole-fits` and `-fmax-refinement-hole-fits` causes some hole fits to be suppressed.
Now add this line
```cabal
ghc-options: -fmax-valid-hole-fits=20 -fmax-refinement-hole-fits=20
```
to the `executable app` stanza, reload HLS, and see the diagnostics again:
```none
• Found hole: _ :: Int -> [Int] -> [Int]
• In the expression: _ (_ :: Int) (_ :: [Int])
In a pattern binding: x :: [Int] = _ (_ :: Int) (_ :: [Int])
In a stmt of a 'do' block:
let x :: [Int] = _ (_ :: Int) (_ :: [Int])
• Relevant bindings include
main :: IO () (bound at /home/enrico/deleteme/app/Main.hs:8:1)
Valid hole fits include
fun
(:)
drop
take
(<$)
mempty
seq
Valid refinement hole fits include
($!) _
const _
flip _
curry _
(!!) _
scanl _
scanr _
($) _
return _
pure _
id _
head _
last _
mconcat _ [GHC-88464]
```
revealing that all holes HLS is aware of are shown now.
One last time, change the added line to this:
```cabal
ghc-options: -fno-max-valid-hole-fits -fno-max-refinement-hole-fits
```
### Expected behaviour
I would expect the same diagnostics as before.
### Actual behaviour
The diagnostic you'll get, instead, is this:
```none
• Found hole: _ :: Int -> [Int] -> [Int]
• In the expression: _ (_ :: Int) (_ :: [Int])
In a pattern binding: x :: [Int] = _ (_ :: Int) (_ :: [Int])
In a stmt of a 'do' block:
let x :: [Int] = _ (_ :: Int) (_ :: [Int])
• Relevant bindings include
main :: IO () (bound at /home/enrico/deleteme/app/Main.hs:8:1)
Valid hole fits include
fun
(:)
drop
take
(<$)
mempty
seq
Valid refinement hole fits include
($!) _
const _
flip _
curry _
(!!) _
scanl _
scanr _
id _
head _
last _
(Some refinement hole fits suppressed; use -fmax-refinement-hole-fits=N or -fno-max-refinement-hole-fits) [GHC-88464]
```
which reveals that the refinement `mconcat _` is suppressed, meaning that `-fno-max-refinement-hole-fits` is in fact ignored.
### Debug information
Not sure what else I can provide. Let me know.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the diagnostics using app.cabal and Main.hs with GHC 9.14.1, first comparing the two GHC option configurations shown in the report. Trace how HLS consumes these options for hole-fit diagnostics; done means -fno-max-refinement-hole-fits shows all refinement fits, matching the expected output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100