summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-12-26 09:46:59 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-01-24 05:37:52 -0500
commit69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc (patch)
tree35d43a8205fc2d7f14e416ade9b301d5a843f828
parent7bfb30f92f5e21a8aca58068dc970040130433c6 (diff)
downloadhaskell-69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc.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.hs13
1 files changed, 10 insertions, 3 deletions
diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs
index 999bed68b5..5cfe71014f 100644
--- a/compiler/GHC/Driver/Make.hs
+++ b/compiler/GHC/Driver/Make.hs
@@ -449,6 +449,9 @@ addHmiToCache c (HomeModInfo i _ l) = iface_addToCache c (CachedIface i l)
data CachedIface = CachedIface { cached_modiface :: !ModIface
, cached_linkable :: !HomeModLinkable }
+instance Outputable CachedIface where
+ ppr (CachedIface mi ln) = hsep [text "CachedIface", ppr (miKey mi), ppr (isJust ln)]
+
noIfaceCache :: Maybe ModIfaceCache
noIfaceCache = Nothing
@@ -829,15 +832,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
= emptyHomeModInfoLinkable
| 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]
-- ---------------------------------------------------------------------------
--