diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2022-12-26 09:46:59 +0000 |
---|---|---|
committer | Matthew Pickering <matthewtpickering@gmail.com> | 2022-12-27 12:13:05 +0000 |
commit | f3d20066a3108ab71c7c72970a05177ffc1d5ae2 (patch) | |
tree | 0d37e61239f910a76dbcc136795e02b84b774eb3 | |
parent | 150b0385075a72fe83b656864c54518406871074 (diff) | |
download | haskell-f3d20066a3108ab71c7c72970a05177ffc1d5ae2.tar.gz |
Use NodeKey rather than ModuleName in pruneCache
The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true:
* In normal compilation, the same module name can appear for a file and it's boot file.
* In multiple home unit compilation the same ModuleName can appear in different units
The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`.
Fixes #22677
-rw-r--r-- | compiler/GHC/Driver/Make.hs | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs index fe98fbe577..0560ace917 100644 --- a/compiler/GHC/Driver/Make.hs +++ b/compiler/GHC/Driver/Make.hs @@ -105,7 +105,6 @@ import GHC.Types.Target import GHC.Types.SourceFile import GHC.Types.SourceError import GHC.Types.SrcLoc -import GHC.Types.Unique.FM import GHC.Types.PkgQual import GHC.Unit @@ -445,6 +444,9 @@ addHmiToCache c (HomeModInfo i _ l) = iface_addToCache c (CachedIface i l) data CachedIface = CachedIface { cached_modiface :: !ModIface , cached_linkable :: !(Maybe Linkable) } +instance Outputable CachedIface where + ppr (CachedIface mi ln) = hsep [text "CachedIface", ppr (miKey mi), ppr (isJust ln)] + noIfaceCache :: Maybe ModIfaceCache noIfaceCache = Nothing @@ -815,15 +817,19 @@ pruneCache hpt summ , cached_linkable = linkable }) = HomeModInfo iface emptyModDetails linkable' where - modl = moduleName (mi_module iface) + modl = miKey iface linkable' - | Just ms <- lookupUFM ms_map modl + | Just ms <- M.lookup modl ms_map , mi_src_hash iface /= ms_hs_hash ms = Nothing | otherwise = linkable - ms_map = listToUFM [(ms_mod_name ms, ms) | ms <- summ] + -- Using UFM Module is safe for determinism because the map is just used for a transient lookup. The cache should be unique and a key clash is an error. + ms_map = M.fromListWith + (\ms1 ms2 -> assertPpr False (text "prune_cache" $$ (ppr ms1 <+> ppr ms2)) + ms2) + [(msKey ms, ms) | ms <- summ] -- --------------------------------------------------------------------------- -- |