Skip to content

Commit b2311ce

Browse files
fendormergify[bot]
andauthored
Avoid unnecessary recompilation due to -haddock (#4596)
* Avoid unnecessary recompilation due to -haddock Due to unprincipled adding and removing the `-haddock` flag during compilation and recompilation checking, we were performing more work than necessary. We avoid this by compiling everything with `-haddock` by default. This is safe nowadays, we have essentially been doing this for many releases, and know this is fine. For the occasion where we actually want to parse without the `-haddock` flag, we keep explicitly disabling it. We enable `-haddock` flag during session loading, since we already perform a number of DynFlags tweaks. This behaviour is dependent on the `OptHaddockParse` opton, which can, currently, only be modified at compile-time. * Fix windows test failure --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent ae5f6a7 commit b2311ce

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

ghcide-test/exe/FindDefinitionAndHoverTests.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ tests = let
187187
holeL65 = Position 65 8 ; hleInfo2 = [ExpectHoverText ["_ :: a -> Maybe a"]]
188188
cccL17 = Position 17 16 ; docLink = [ExpectHoverTextRegex "\\*Defined in 'GHC.Types'\\* \\*\\(ghc-prim-[0-9.]+\\)\\*\n\n"]
189189
imported = Position 56 13 ; importedSig = getDocUri "Foo.hs" >>= \foo -> return [ExpectHoverText ["foo", "Foo", "Haddock"], mkL foo 5 0 5 3]
190-
reexported = Position 55 14 ; reexportedSig = getDocUri "Bar.hs" >>= \bar -> return [ExpectHoverText ["Bar", "Bar", "Haddock"], if ghcVersion < GHC910 then mkL bar 3 5 3 8 else mkL bar 3 0 3 14]
190+
reexported = Position 55 14
191+
reexportedSig = getDocUri "Bar.hs" >>= \bar -> return [ExpectHoverText ["Bar", "Bar", "Haddock"], if ghcVersion < GHC910 || not isWindows then mkL bar 3 5 3 8 else mkL bar 3 0 3 14]
191192
thLocL57 = Position 59 10 ; thLoc = [ExpectHoverText ["Identity"]]
192193
cmtL68 = Position 67 0 ; lackOfdEq = [ExpectHoverExcludeText ["$dEq"]]
193194
import310 = Position 3 10; pkgTxt = [ExpectHoverText ["Data.Text\n\ntext-"]]
@@ -237,9 +238,9 @@ tests = let
237238
, testM yes yes imported importedSig "Imported symbol"
238239
, if isWindows then
239240
-- Flaky on Windows: https://github.com/haskell/haskell-language-server/issues/2997
240-
testM no yes reexported reexportedSig "Imported symbol (reexported)"
241+
testM no yes reexported reexportedSig "Imported symbol reexported"
241242
else
242-
testM yes yes reexported reexportedSig "Imported symbol (reexported)"
243+
testM yes yes reexported reexportedSig "Imported symbol reexported"
243244
, test no yes thLocL57 thLoc "TH Splice Hover"
244245
, test yes yes import310 pkgTxt "show package name and its version"
245246
]

ghcide/session-loader/Development/IDE/Session.hs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
452452
IdeOptions{ optTesting = IdeTesting optTesting
453453
, optCheckProject = getCheckProject
454454
, optExtensions
455+
, optHaddockParse
455456
} <- getIdeOptions
456457

457458
-- populate the knownTargetsVar with all the
@@ -496,7 +497,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
496497
packageSetup (hieYaml, cfp, opts, libDir) = do
497498
-- Parse DynFlags for the newly discovered component
498499
hscEnv <- emptyHscEnv ideNc libDir
499-
newTargetDfs <- evalGhcEnv hscEnv $ setOptions cfp opts (hsc_dflags hscEnv) rootDir
500+
newTargetDfs <- evalGhcEnv hscEnv $ setOptions optHaddockParse cfp opts (hsc_dflags hscEnv) rootDir
500501
let deps = componentDependencies opts ++ maybeToList hieYaml
501502
dep_info <- getDependencyInfo deps
502503
-- Now lookup to see whether we are combining with an existing HscEnv
@@ -1110,12 +1111,13 @@ addUnit unit_str = liftEwM $ do
11101111

11111112
-- | Throws if package flags are unsatisfiable
11121113
setOptions :: GhcMonad m
1113-
=> NormalizedFilePath
1114+
=> OptHaddockParse
1115+
-> NormalizedFilePath
11141116
-> ComponentOptions
11151117
-> DynFlags
11161118
-> FilePath -- ^ root dir, see Note [Root Directory]
11171119
-> m (NonEmpty (DynFlags, [GHC.Target]))
1118-
setOptions cfp (ComponentOptions theOpts compRoot _) dflags rootDir = do
1120+
setOptions haddockOpt cfp (ComponentOptions theOpts compRoot _) dflags rootDir = do
11191121
((theOpts',_errs,_warns),units) <- processCmdLineP unit_flags [] (map noLoc theOpts)
11201122
case NE.nonEmpty units of
11211123
Just us -> initMulti us
@@ -1179,6 +1181,7 @@ setOptions cfp (ComponentOptions theOpts compRoot _) dflags rootDir = do
11791181
dontWriteHieFiles $
11801182
setIgnoreInterfacePragmas $
11811183
setBytecodeLinkerOptions $
1184+
enableOptHaddock haddockOpt $
11821185
disableOptimisation $
11831186
Compat.setUpTypedHoles $
11841187
makeDynFlagsAbsolute compRoot -- makeDynFlagsAbsolute already accounts for workingDirectory
@@ -1192,6 +1195,14 @@ setIgnoreInterfacePragmas df =
11921195
disableOptimisation :: DynFlags -> DynFlags
11931196
disableOptimisation df = updOptLevel 0 df
11941197

1198+
-- | We always compile with '-haddock' unless explicitly disabled.
1199+
--
1200+
-- This avoids inconsistencies when doing recompilation checking which was
1201+
-- observed in https://github.com/haskell/haskell-language-server/issues/4511
1202+
enableOptHaddock :: OptHaddockParse -> DynFlags -> DynFlags
1203+
enableOptHaddock HaddockParse d = gopt_set d Opt_Haddock
1204+
enableOptHaddock NoHaddockParse d = d
1205+
11951206
setHiDir :: FilePath -> DynFlags -> DynFlags
11961207
setHiDir f d =
11971208
-- override user settings to avoid conflicts leading to recompilation

ghcide/src/Development/IDE/Core/Rules.hs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,10 @@ getParsedModuleRule recorder =
260260
let ms = ms' { ms_hspp_opts = modify_dflags $ ms_hspp_opts ms' }
261261
reset_ms pm = pm { pm_mod_summary = ms' }
262262

263-
-- We still parse with Haddocks whether Opt_Haddock is True or False to collect information
264-
-- but we no longer need to parse with and without Haddocks separately for above GHC90.
265-
liftIO $ (fmap.fmap.fmap) reset_ms $ getParsedModuleDefinition hsc opt file (withOptHaddock ms)
263+
liftIO $ (fmap.fmap.fmap) reset_ms $ getParsedModuleDefinition hsc opt file ms
266264

267-
withOptHaddock :: ModSummary -> ModSummary
268-
withOptHaddock = withOption Opt_Haddock
265+
withoutOptHaddock :: ModSummary -> ModSummary
266+
withoutOptHaddock = withoutOption Opt_Haddock
269267

270268
withOption :: GeneralFlag -> ModSummary -> ModSummary
271269
withOption opt ms = ms{ms_hspp_opts= gopt_set (ms_hspp_opts ms) opt}
@@ -284,7 +282,7 @@ getParsedModuleWithCommentsRule recorder =
284282
ModSummaryResult{msrModSummary = ms, msrHscEnv = hsc} <- use_ GetModSummary file
285283
opt <- getIdeOptions
286284

287-
let ms' = withoutOption Opt_Haddock $ withOption Opt_KeepRawTokenStream ms
285+
let ms' = withoutOptHaddock $ withOption Opt_KeepRawTokenStream ms
288286
modify_dflags <- getModifyDynFlags dynFlagsModifyParser
289287
let ms'' = ms' { ms_hspp_opts = modify_dflags $ ms_hspp_opts ms' }
290288
reset_ms pm = pm { pm_mod_summary = ms' }
@@ -972,8 +970,8 @@ regenerateHiFile sess f ms compNeeded = do
972970
hsc <- setFileCacheHook (hscEnv sess)
973971
opt <- getIdeOptions
974972

975-
-- Embed haddocks in the interface file
976-
(diags, mb_pm) <- liftIO $ getParsedModuleDefinition hsc opt f (withOptHaddock ms)
973+
-- By default, we parse with `-haddock` unless 'OptHaddockParse' is overwritten.
974+
(diags, mb_pm) <- liftIO $ getParsedModuleDefinition hsc opt f ms
977975
case mb_pm of
978976
Nothing -> return (diags, Nothing)
979977
Just pm -> do

ghcide/src/Development/IDE/Types/Options.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ data IdeOptions = IdeOptions
6868
, optCheckParents :: IO CheckParents
6969
-- ^ When to typecheck reverse dependencies of a file
7070
, optHaddockParse :: OptHaddockParse
71-
-- ^ Whether to return result of parsing module with Opt_Haddock.
72-
-- Otherwise, return the result of parsing without Opt_Haddock, so
73-
-- that the parsed module contains the result of Opt_KeepRawTokenStream,
74-
-- which might be necessary for hlint.
71+
-- ^ Whether to parse modules with '-haddock' by default.
72+
-- If 'HaddockParse' is given, we parse local haskell modules with the
73+
-- '-haddock' flag enables.
74+
-- If a plugin requires the parsed sources *without* '-haddock', it needs
75+
-- to use rules that explicitly disable the '-haddock' flag.
76+
-- See call sites of 'withoutOptHaddock' for rules that parse without '-haddock'.
7577
, optModifyDynFlags :: Config -> DynFlagsModifications
7678
-- ^ Will be called right after setting up a new cradle,
7779
-- allowing to customize the Ghc options used

0 commit comments

Comments
 (0)