summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-12-26 09:46:59 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2022-12-27 12:13:05 +0000
commitf3d20066a3108ab71c7c72970a05177ffc1d5ae2 (patch)
tree0d37e61239f910a76dbcc136795e02b84b774eb3
parent150b0385075a72fe83b656864c54518406871074 (diff)
downloadhaskell-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.hs14
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]
-- ---------------------------------------------------------------------------
--