From c9519af39acc5d157d1d7f5acc75cad1f02791d1 Mon Sep 17 00:00:00 2001 From: wz1000 Date: Tue, 25 Jul 2023 20:02:03 +0530 Subject: [PATCH] In 00f4e61da6c07f9a632e58dd57c73a79a1640fa3 we attempted to share the filepaths in GHC's usage field. (#3713) Unfortunately the `mi_usages` is evaluated by `checkOldIface` before we have a chance to do the sharing, resulting in them not actually being shared on the first load. Solution is to share the usages before `checkOldIface` has a chance to inspect them, breaking the sharing. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- ghcide/src/Development/IDE/Core/Compile.hs | 25 ++++++++++++++++--- ghcide/src/Development/IDE/GHC/Compat/Core.hs | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 801942fc71..e34c5323f9 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -36,6 +36,7 @@ module Development.IDE.Core.Compile , TypecheckHelpers(..) , sourceTypecheck , sourceParser + , shareUsages ) where import Control.Monad.IO.Class @@ -472,6 +473,8 @@ filterUsages = id #endif -- | Mitigation for https://gitlab.haskell.org/ghc/ghc/-/issues/22744 +-- Important to do this immediately after reading the unit before +-- anything else has a chance to read `mi_usages` shareUsages :: ModIface -> ModIface shareUsages iface = iface {mi_usages = usages} where usages = map go (mi_usages iface) @@ -1490,11 +1493,28 @@ loadInterface session ms linkableNeeded RecompilationInfo{..} = do | source_version <= dest_version -> SourceUnmodified | otherwise -> SourceModified + old_iface <- case mb_old_iface of + Just iface -> pure (Just iface) + Nothing -> do + let ncu = hsc_NC sessionWithMsDynFlags + read_dflags = hsc_dflags sessionWithMsDynFlags +#if MIN_VERSION_ghc(9,3,0) + read_result <- liftIO $ readIface read_dflags ncu mod iface_file +#else + read_result <- liftIO $ initIfaceCheck (text "readIface") sessionWithMsDynFlags + $ readIface mod iface_file +#endif + case read_result of + Util.Failed{} -> return Nothing + -- important to call `shareUsages` here before checkOldIface + -- consults `mi_usages` + Util.Succeeded iface -> return $ Just (shareUsages iface) + -- If mb_old_iface is nothing then checkOldIface will load it for us -- given that the source is unmodified (recomp_iface_reqd, mb_checked_iface) #if MIN_VERSION_ghc(9,3,0) - <- liftIO $ checkOldIface sessionWithMsDynFlags ms mb_old_iface >>= \case + <- liftIO $ checkOldIface sessionWithMsDynFlags ms old_iface >>= \case UpToDateItem x -> pure (UpToDate, Just x) OutOfDateItem reason x -> pure (NeedsRecompile reason, x) #else @@ -1508,8 +1528,7 @@ loadInterface session ms linkableNeeded RecompilationInfo{..} = do regenerate linkableNeeded case (mb_checked_iface, recomp_iface_reqd) of - (Just iface', UpToDate) -> do - let iface = shareUsages iface' + (Just iface, UpToDate) -> do details <- liftIO $ mkDetailsFromIface sessionWithMsDynFlags iface -- parse the runtime dependencies from the annotations let runtime_deps diff --git a/ghcide/src/Development/IDE/GHC/Compat/Core.hs b/ghcide/src/Development/IDE/GHC/Compat/Core.hs index be4d72beb3..3b516c6f40 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Core.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Core.hs @@ -39,6 +39,7 @@ module Development.IDE.GHC.Compat.Core ( lookupType, needWiredInHomeIface, loadWiredInHomeIface, + readIface, loadSysInterface, importDecl, #if MIN_VERSION_ghc(8,8,0)