diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2022-12-26 09:46:59 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-01-24 05:37:52 -0500 |
commit | 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc (patch) | |
tree | 35d43a8205fc2d7f14e416ade9b301d5a843f828 | |
parent | 7bfb30f92f5e21a8aca58068dc970040130433c6 (diff) | |
download | haskell-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.hs | 13 |
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] -- --------------------------------------------------------------------------- -- |