summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-12-26 09:46:59 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2023-01-23 11:43:40 +0000
commit982e8bbec3e892f6379662017cd97fcd70d98b37 (patch)
treefbd73bc179a27215c9e55d96cb0b8b17fb7e514d
parent8a47f4e0c1b8e91edef635e6ba05f65df62a416f (diff)
downloadhaskell-982e8bbec3e892f6379662017cd97fcd70d98b37.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]
-- ---------------------------------------------------------------------------
--