Skip to content

Commit 7b8e2e5

Browse files
Limit number of valid hole fits to 10 (#4288)
* ghcide: Pass -fmax-valid-hole-fits=10 to GHC In cases where GHC doesn't know anything about the type of a hole, it suggests every available symbol as a hole fit, which can cause editors to crash or at least be very slow. 10 seems to be a fair number to limit hole fits to. * hls-refactor-plugin: Ignore "Some hole fits suppressed" message when valid hole fits are limited * hls-refactor-plugin: More predictable hole fit for test Now that we limit number of hole fits recommended by GHC, the test that hopes to find `+` being recommended for `Int -> Int -> Int` becomes unpredictable because there are too many symbols which match that type and the sorting has little control over which symbols get recommended. There are way fewer matches for `(Int -> Maybe Int) -> Maybe Int -> Maybe Int`, so it makes the test consistently succeed. --------- Co-authored-by: Michael Peyton Jones <[email protected]>
1 parent 026d0ce commit 7b8e2e5

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

ghcide/src/Development/IDE/GHC/Compat.hs

+9-4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ import Compat.HieTypes hiding
133133
(nodeAnnotations)
134134
import qualified Compat.HieTypes as GHC (nodeAnnotations)
135135
import Compat.HieUtils
136+
import Control.Applicative ((<|>))
136137
import qualified Data.ByteString as BS
137138
import Data.Coerce (coerce)
138139
import Data.List (foldl')
@@ -434,7 +435,7 @@ setHieDir _f d = d { hieDir = Just _f}
434435
dontWriteHieFiles :: DynFlags -> DynFlags
435436
dontWriteHieFiles d = gopt_unset d Opt_WriteHie
436437

437-
setUpTypedHoles ::DynFlags -> DynFlags
438+
setUpTypedHoles :: DynFlags -> DynFlags
438439
setUpTypedHoles df
439440
= flip gopt_unset Opt_AbstractRefHoleFits -- too spammy
440441
$ flip gopt_unset Opt_ShowDocsOfHoleFits -- not used
@@ -447,9 +448,13 @@ setUpTypedHoles df
447448
$ flip gopt_unset Opt_SortValidHoleFits
448449
$ flip gopt_unset Opt_UnclutterValidHoleFits
449450
$ df
450-
{ refLevelHoleFits = Just 1 -- becomes slow at higher levels
451-
, maxRefHoleFits = Just 10 -- quantity does not impact speed
452-
, maxValidHoleFits = Nothing -- quantity does not impact speed
451+
{ refLevelHoleFits = refLevelHoleFits df <|> Just 1 -- becomes slow at higher levels
452+
453+
-- Sometimes GHC can emit a lot of hole fits, this causes editors to be slow
454+
-- or just crash, we limit the hole fits to 10. The number was chosen
455+
-- arbirtarily by the author.
456+
, maxRefHoleFits = maxRefHoleFits df <|> Just 10
457+
, maxValidHoleFits = maxValidHoleFits df <|> Just 10
453458
}
454459

455460

plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillHole.hs

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ processHoleSuggestions mm = (holeSuggestions, refSuggestions)
6969
(mrAfter . (=~ t " *Valid (hole fits|substitutions) include"))
7070
validHolesSection
7171
let holeFit = T.strip $ T.takeWhile (/= ':') holeFitLine
72-
guard (not $ T.null holeFit)
72+
guard $ not $ holeFit =~ t "Some hole fits suppressed"
73+
guard $ not $ T.null holeFit
7374
return holeFit
7475
refSuggestions = do -- @[]
7576
-- get the text indented under Valid refinement hole fits

plugins/hls-refactor-plugin/test/Main.hs

+8-8
Original file line numberDiff line numberDiff line change
@@ -2640,29 +2640,29 @@ fillTypedHoleTests = let
26402640
, testSession "postfix hole uses postfix notation of infix operator" $ do
26412641
let mkDoc x = T.unlines
26422642
[ "module Testing where"
2643-
, "test :: Int -> Int -> Int"
2644-
, "test a1 a2 = " <> x <> " a1 a2"
2643+
, "test :: Int -> Maybe Int -> Maybe Int"
2644+
, "test a ma = " <> x <> " (a +) ma"
26452645
]
26462646
doc <- createDoc "Test.hs" "haskell" $ mkDoc "_"
26472647
_ <- waitForDiagnostics
26482648
actions <- getCodeActions doc (Range (Position 2 13) (Position 2 14))
2649-
chosen <- pickActionWithTitle "replace _ with (+)" actions
2649+
chosen <- pickActionWithTitle "replace _ with (<$>)" actions
26502650
executeCodeAction chosen
26512651
modifiedCode <- documentContents doc
2652-
liftIO $ mkDoc "(+)" @=? modifiedCode
2652+
liftIO $ mkDoc "(<$>)" @=? modifiedCode
26532653
, testSession "filling infix type hole uses infix operator" $ do
26542654
let mkDoc x = T.unlines
26552655
[ "module Testing where"
2656-
, "test :: Int -> Int -> Int"
2657-
, "test a1 a2 = a1 " <> x <> " a2"
2656+
, "test :: Int -> Maybe Int -> Maybe Int"
2657+
, "test a ma = (a +) " <> x <> " ma"
26582658
]
26592659
doc <- createDoc "Test.hs" "haskell" $ mkDoc "`_`"
26602660
_ <- waitForDiagnostics
26612661
actions <- getCodeActions doc (Range (Position 2 16) (Position 2 19))
2662-
chosen <- pickActionWithTitle "replace _ with (+)" actions
2662+
chosen <- pickActionWithTitle "replace _ with (<$>)" actions
26632663
executeCodeAction chosen
26642664
modifiedCode <- documentContents doc
2665-
liftIO $ mkDoc "+" @=? modifiedCode
2665+
liftIO $ mkDoc "<$>" @=? modifiedCode
26662666
]
26672667

26682668
addInstanceConstraintTests :: TestTree

0 commit comments

Comments
 (0)