Wolfgang Jeltsch pushed to branch wip/jeltsch/smaller-pit at Glasgow Haskell Compiler / GHC Commits: 969e7ea7 by Wolfgang Jeltsch at 2026-10-12T17:42:15+03:00 Make `IfaceBinHandle` a type synonym family This brings the handling of `IfaceBinHandle` somewhat in line with how other phase-dependent data is handled. Note that `mi_hi_bytes_` now includes the `Strict.Maybe` layer itself, independently of the phase. This is necessary, because with a type family instead of a GADT `clear_mi_hi_bytes` cannot determine the phase at runtime anymore and thus has to set `mi_hi_bytes_` to `Strict.Nothing` for every phase. - - - - - 3 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Unit/Module/ModIface.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -197,7 +197,7 @@ getIfaceWithExtFields name_cache bh = do modIfaceBinData <- freezeBinHandle bh start pure $ mod_iface & set_mi_ext_fields extFields - & set_mi_hi_bytes (FullIfaceBinHandle $ Strict.Just modIfaceBinData) + & set_mi_hi_bytes (Strict.Just modIfaceBinData) -- | This performs a get action after reading the dictionary and symbol -- table. It is necessary to run this before trying to deserialise any @@ -276,10 +276,10 @@ writeBinIface profile traceBinIface compressionLevel hi_path mod_iface = do putIfaceWithExtFields :: TraceBinIFace -> CompressionIFace -> WriteBinHandle -> ModIface -> IO () putIfaceWithExtFields traceBinIface compressionLevel bh mod_iface = case mi_hi_bytes mod_iface of - FullIfaceBinHandle Strict.Nothing -> do + Strict.Nothing -> do forwardPutRel_ bh (\_ -> put_ bh (mi_ext_fields mod_iface)) $ do putWithUserData traceBinIface compressionLevel bh mod_iface - FullIfaceBinHandle (Strict.Just binData) -> putFullBinData bh binData + Strict.Just binData -> putFullBinData bh binData -- | Put a piece of data with an initialised `UserData` field. This -- is necessary if you want to serialise Names or FastStrings. ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -77,6 +77,7 @@ import GHC.Iface.Binary import GHC.Data.FastString import GHC.Data.Maybe +import qualified GHC.Data.Strict as Strict import GHC.HsToCore.Docs import GHC.HsToCore.Usage @@ -394,7 +395,7 @@ mkIface_ hsc_env & set_mi_docs docs & set_mi_abi_hashes () & set_mi_ext_fields emptyExtensibleFields - & set_mi_hi_bytes PartialIfaceBinHandle + & set_mi_hi_bytes Strict.Nothing where cmp_rule = lexicalCompareFS `on` ifRuleName ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -70,7 +70,7 @@ module GHC.Unit.Module.ModIface , set_mi_hash_fn , completePartialModIface , shrinkModIface - , IfaceBinHandle(..) + , IfaceBinHandle , PartialModIface , RetainedModIface , IfaceAbiHashes (..) @@ -160,6 +160,7 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception +import Data.Void (Void) {- Note [Interface file stages] @@ -236,15 +237,10 @@ data ModIfacePhase -- | In-memory byte array representation of a 'ModIface'. -- -- See Note [Sharing of ModIface] for why we need this. -data IfaceBinHandle (phase :: ModIfacePhase) where - -- | A partial 'ModIface' cannot be serialised to disk. - PartialIfaceBinHandle :: IfaceBinHandle 'ModIfaceCore - -- | Optional 'FullBinData' that can be serialised to disk directly. - -- - -- See Note [Private fields in ModIface] for when this fields needs to be cleared - -- (e.g., set to 'Nothing'). - FullIfaceBinHandle :: !(Strict.Maybe FullBinData) -> IfaceBinHandle 'ModIfaceFinal - RetainedIfaceBinHandle :: IfaceBinHandle 'ModIfaceRetained +type family IfaceBinHandle (phase :: ModIfacePhase) where + IfaceBinHandle 'ModIfaceCore = Void + IfaceBinHandle 'ModIfaceFinal = FullBinData + IfaceBinHandle 'ModIfaceRetained = Void type family IfaceSelfRecompData (phase :: ModIfacePhase) where IfaceSelfRecompData 'ModIfaceCore = Maybe IfaceSelfRecomp @@ -322,11 +318,22 @@ withSelfRecomp iface nk jk = -- fields. data ModIface_ (phase :: ModIfacePhase) = PrivateModIface { - mi_hi_bytes_ :: !(IfaceBinHandle phase), - -- ^ A serialised in-memory buffer of this 'ModIface'. - -- If this handle is given, we can avoid serialising the 'ModIface' - -- when writing this 'ModIface' to disk, and write this buffer to disk instead. - -- See Note [Sharing of ModIface]. + mi_hi_bytes_ :: !(Strict.Maybe (IfaceBinHandle phase)), + -- ^ Optionally an in-memory buffer that contains the + -- serialization of this 'ModIface'. If such a buffer is + -- present, we can avoid serialising the 'ModIface' when + -- writing it to disk and write this buffer instead. See + -- Note [Sharing of ModIface] and + -- Note [Private fields in ModIface]. + -- + -- Only in the 'ModIfaceFinal' phase, there can be a buffer + -- with the serialization. Both @IfaceBinHandle 'ModIfaceCore@ + -- and @IfaceBinHandle 'ModIfaceRetained@ are defined to be + -- 'Void', so that the 'mi_hi_bytes' field gets the type + -- @Strict.Maybe Void@. This type is isomorphic to '()', even + -- when taking partially defined values into account, because + -- @Strict.Just undefined@ is @undefined@ and so @Nothing@ and + -- @undefined@ are the only inhabitants of that type. mi_iface_hash_ :: Fingerprint, -- A hash of the whole interface mi_mod_info_ :: IfaceModInfo, @@ -718,7 +725,7 @@ instance Binary ModIface where -- We can't populate this field here, as we are -- missing the 'mi_ext_fields_' field, which is -- handled in 'getIfaceWithExtFields'. - mi_hi_bytes_ = FullIfaceBinHandle Strict.Nothing + mi_hi_bytes_ = Strict.Nothing }) instance Binary IfaceModInfo where @@ -833,7 +840,7 @@ emptyPartialModIface mod = PrivateModIface { mi_mod_info_ = emptyIfaceModInfo mod, mi_iface_hash_ = fingerprint0, - mi_hi_bytes_ = PartialIfaceBinHandle, + mi_hi_bytes_ = Strict.Nothing, mi_deps_ = noDependencies, mi_public_ = emptyPublicModIface [] [] [] [] [] [] [] (), mi_simplified_core_ = Nothing, @@ -907,7 +914,7 @@ emptyFullModIface :: Module -> ModIface emptyFullModIface mod = (emptyPartialModIface mod) { mi_public_ = emptyPublicModIface [] [] [] [] [] [] [] emptyIfaceBackend - , mi_hi_bytes_ = FullIfaceBinHandle Strict.Nothing + , mi_hi_bytes_ = Strict.Nothing } @@ -940,7 +947,7 @@ instance ( NFData (IfaceSelfRecompData phase) , NFData (IfaceAbiHashesData phase) ) => NFData (ModIface_ phase) where rnf (PrivateModIface a1 a2 a3 a4 a5 a6 a7 a8 a9 a10) - = (a1 :: IfaceBinHandle phase) + = a1 `seq` rnf a2 `seq` rnf a3 `seq` rnf a4 @@ -1051,7 +1058,7 @@ completePartialModIface :: PartialModIface completePartialModIface partial iface_hash decls extra_decls final_exts cache = partial { mi_public_ = completePublicModIface decls final_exts cache (mi_public_ partial) , mi_simplified_core_ = extra_decls - , mi_hi_bytes_ = FullIfaceBinHandle Strict.Nothing + , mi_hi_bytes_ = Strict.Nothing , mi_iface_hash_ = iface_hash } @@ -1072,7 +1079,7 @@ shrinkModIface :: ModIface -> RetainedModIface shrinkModIface PrivateModIface {..} = PrivateModIface { - mi_hi_bytes_ = RetainedIfaceBinHandle, + mi_hi_bytes_ = Strict.Nothing, mi_public_ = shrinkIfacePublic mi_public_, mi_self_recomp_ = (), mi_simplified_core_ = (), @@ -1100,7 +1107,7 @@ set_mi_mod_info val iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = val } set_mi_self_recomp :: IfaceSelfRecompData phase -> ModIface_ phase -> ModIface_ phase set_mi_self_recomp val iface = clear_mi_hi_bytes $ iface { mi_self_recomp_ = val } -set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase +set_mi_hi_bytes :: Strict.Maybe (IfaceBinHandle phase) -> ModIface_ phase -> ModIface_ phase set_mi_hi_bytes val iface = iface { mi_hi_bytes_ = val } set_mi_deps :: Dependencies -> ModIface_ phase -> ModIface_ phase @@ -1203,12 +1210,7 @@ set_mi_mod_info_field f iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = f (mi -- | Invalidate any byte array buffer we might have. clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase -clear_mi_hi_bytes iface = iface - { mi_hi_bytes_ = case mi_hi_bytes iface of - PartialIfaceBinHandle -> PartialIfaceBinHandle - FullIfaceBinHandle _ -> FullIfaceBinHandle Strict.Nothing - RetainedIfaceBinHandle -> RetainedIfaceBinHandle - } +clear_mi_hi_bytes iface = iface { mi_hi_bytes_ = Strict.Nothing } -- ---------------------------------------------------------------------------- -- 'ModIface' pattern synonyms to keep breakage low. @@ -1319,7 +1321,7 @@ pattern ModIface :: -> Maybe Docs -> IfaceAbiHashesData phase -> ExtensibleFieldsData phase - -> IfaceBinHandle phase + -> Strict.Maybe (IfaceBinHandle phase) -> IfaceSelfRecompData phase -> (OccName -> Maybe Fixity) -> (OccName -> Maybe (OccName, Fingerprint)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/969e7ea7de61ae6ad2976042e4449ef3... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/969e7ea7de61ae6ad2976042e4449ef3... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Wolfgang Jeltsch (@jeltsch)