From 990428fc0306a821b47c90a69c98b82fa97662b8 Mon Sep 17 00:00:00 2001 From: Akshay Mankar Date: Sat, 8 Jun 2024 16:28:41 +0200 Subject: [PATCH 1/3] 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. --- ghcide/src/Development/IDE/GHC/Compat.hs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ghcide/src/Development/IDE/GHC/Compat.hs b/ghcide/src/Development/IDE/GHC/Compat.hs index 75590d0596..e786c2ee14 100644 --- a/ghcide/src/Development/IDE/GHC/Compat.hs +++ b/ghcide/src/Development/IDE/GHC/Compat.hs @@ -133,6 +133,7 @@ import Compat.HieTypes hiding (nodeAnnotations) import qualified Compat.HieTypes as GHC (nodeAnnotations) import Compat.HieUtils +import Control.Applicative ((<|>)) import qualified Data.ByteString as BS import Data.Coerce (coerce) import Data.List (foldl') @@ -434,7 +435,7 @@ setHieDir _f d = d { hieDir = Just _f} dontWriteHieFiles :: DynFlags -> DynFlags dontWriteHieFiles d = gopt_unset d Opt_WriteHie -setUpTypedHoles ::DynFlags -> DynFlags +setUpTypedHoles :: DynFlags -> DynFlags setUpTypedHoles df = flip gopt_unset Opt_AbstractRefHoleFits -- too spammy $ flip gopt_unset Opt_ShowDocsOfHoleFits -- not used @@ -447,9 +448,13 @@ setUpTypedHoles df $ flip gopt_unset Opt_SortValidHoleFits $ flip gopt_unset Opt_UnclutterValidHoleFits $ df - { refLevelHoleFits = Just 1 -- becomes slow at higher levels - , maxRefHoleFits = Just 10 -- quantity does not impact speed - , maxValidHoleFits = Nothing -- quantity does not impact speed + { refLevelHoleFits = refLevelHoleFits df <|> Just 1 -- becomes slow at higher levels + + -- Sometimes GHC can emit a lot of hole fits, this causes editors to be slow + -- or just crash, we limit the hole fits to 10. The number was chosen + -- arbirtarily by the author. + , maxRefHoleFits = maxRefHoleFits df <|> Just 10 + , maxValidHoleFits = maxValidHoleFits df <|> Just 10 } From 0d9bb432b5be7c512a4775127a980cb1ba03ba3b Mon Sep 17 00:00:00 2001 From: Akshay Mankar Date: Sat, 8 Jun 2024 16:30:51 +0200 Subject: [PATCH 2/3] hls-refactor-plugin: Ignore "Some hole fits suppressed" message when valid hole fits are limited --- .../src/Development/IDE/Plugin/Plugins/FillHole.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillHole.hs b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillHole.hs index 35e04af6ba..8016bcc305 100644 --- a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillHole.hs +++ b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillHole.hs @@ -69,7 +69,8 @@ processHoleSuggestions mm = (holeSuggestions, refSuggestions) (mrAfter . (=~ t " *Valid (hole fits|substitutions) include")) validHolesSection let holeFit = T.strip $ T.takeWhile (/= ':') holeFitLine - guard (not $ T.null holeFit) + guard $ not $ holeFit =~ t "Some hole fits suppressed" + guard $ not $ T.null holeFit return holeFit refSuggestions = do -- @[] -- get the text indented under Valid refinement hole fits From 6a8e42405b283d02a3a46e4a91bb2f1bd209de7c Mon Sep 17 00:00:00 2001 From: Akshay Mankar Date: Sat, 8 Jun 2024 17:31:45 +0200 Subject: [PATCH 3/3] 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. --- plugins/hls-refactor-plugin/test/Main.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/hls-refactor-plugin/test/Main.hs b/plugins/hls-refactor-plugin/test/Main.hs index a4e5b235d8..069039dc14 100644 --- a/plugins/hls-refactor-plugin/test/Main.hs +++ b/plugins/hls-refactor-plugin/test/Main.hs @@ -2640,29 +2640,29 @@ fillTypedHoleTests = let , testSession "postfix hole uses postfix notation of infix operator" $ do let mkDoc x = T.unlines [ "module Testing where" - , "test :: Int -> Int -> Int" - , "test a1 a2 = " <> x <> " a1 a2" + , "test :: Int -> Maybe Int -> Maybe Int" + , "test a ma = " <> x <> " (a +) ma" ] doc <- createDoc "Test.hs" "haskell" $ mkDoc "_" _ <- waitForDiagnostics actions <- getCodeActions doc (Range (Position 2 13) (Position 2 14)) - chosen <- pickActionWithTitle "replace _ with (+)" actions + chosen <- pickActionWithTitle "replace _ with (<$>)" actions executeCodeAction chosen modifiedCode <- documentContents doc - liftIO $ mkDoc "(+)" @=? modifiedCode + liftIO $ mkDoc "(<$>)" @=? modifiedCode , testSession "filling infix type hole uses infix operator" $ do let mkDoc x = T.unlines [ "module Testing where" - , "test :: Int -> Int -> Int" - , "test a1 a2 = a1 " <> x <> " a2" + , "test :: Int -> Maybe Int -> Maybe Int" + , "test a ma = (a +) " <> x <> " ma" ] doc <- createDoc "Test.hs" "haskell" $ mkDoc "`_`" _ <- waitForDiagnostics actions <- getCodeActions doc (Range (Position 2 16) (Position 2 19)) - chosen <- pickActionWithTitle "replace _ with (+)" actions + chosen <- pickActionWithTitle "replace _ with (<$>)" actions executeCodeAction chosen modifiedCode <- documentContents doc - liftIO $ mkDoc "+" @=? modifiedCode + liftIO $ mkDoc "<$>" @=? modifiedCode ] addInstanceConstraintTests :: TestTree