From a05bd2872d01a41991fdb35f9431e0c54efaa8fb Mon Sep 17 00:00:00 2001 From: Cheng Shao <terrorjack@type.dance> Date: Thu, 13 Feb 2025 23:43:10 +0000 Subject: [PATCH] compiler: avoid overwriting existing writers in putWithTables This patch makes `putWithTables` avoid overwriting all existing UserData writers in the handle. This is crucial for GHC API users that use putWithUserData/getWithUserData for serialization logic that involve Names. (cherry picked from commit c331eebf575221ed8c67ca232bac4ae047b794a3) --- compiler/GHC/Iface/Binary.hs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/GHC/Iface/Binary.hs b/compiler/GHC/Iface/Binary.hs index 94ebbad34c3..25739f77fc5 100644 --- a/compiler/GHC/Iface/Binary.hs +++ b/compiler/GHC/Iface/Binary.hs @@ -43,7 +43,6 @@ import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Utils.Binary as Binary import GHC.Data.FastMutInt -import GHC.Data.FastString (FastString) import GHC.Types.Unique import GHC.Utils.Outputable import GHC.Types.Name.Cache @@ -321,18 +320,21 @@ putWithTables compressionLevel bh' put_payload = do (ifaceType_wt, ifaceTypeWriter) <- initWriteIfaceType compressionLevel -- Initialise the 'WriterUserData'. - let writerUserData = mkWriterUserData - [ mkSomeBinaryWriter @FastString fsWriter - , mkSomeBinaryWriter @Name nameWriter - -- We sometimes serialise binding and non-binding names differently, but - -- not during 'ModIface' serialisation. Here, we serialise both to the same - -- deduplication table. - -- - -- See Note [Binary UserData] - , mkSomeBinaryWriter @BindingName $ mkWriter (\bh name -> putEntry nameWriter bh (getBindingName name)) - , mkSomeBinaryWriter @IfaceType ifaceTypeWriter - ] - let bh = setWriterUserData bh' writerUserData + -- + -- Similar to how 'getTables' calls 'addReaderToUserData', here we + -- call 'addWriterToUserData' instead of 'setWriterUserData', to + -- avoid overwriting existing writers of other types in bh'. + let bh = + addWriterToUserData fsWriter + $ addWriterToUserData nameWriter + -- We sometimes serialise binding and non-binding names differently, but + -- not during 'ModIface' serialisation. Here, we serialise both to the same + -- deduplication table. + -- + -- See Note [Binary UserData] + $ addWriterToUserData + (mkWriter $ \bh name -> putEntry nameWriter bh $ getBindingName name) + $ addWriterToUserData ifaceTypeWriter bh' ([fs_count, name_count, ifacetype_count] , r) <- -- The order of these entries matters! -- GitLab