[Git][ghc/ghc][wip/jeltsch/smaller-pit] 2 commits: Statically enforce module interface reduction for the PIT
by Wolfgang Jeltsch (@jeltsch) 06 Oct '26
by Wolfgang Jeltsch (@jeltsch) 06 Oct '26
06 Oct '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/smaller-pit at Glasgow Haskell Compiler / GHC
Commits:
4c77cd99 by Wolfgang Jeltsch at 2026-10-06T17:22:27+03:00
Statically enforce module interface reduction for the PIT
`GHC.Iface.Load.loadInterface` used to replace certain fields of each
fetched module interface by `panic` applications before storing it in
the PIT. With the present change, the absence of those fields in the PIT
is guaranteed statically.
See #27044 for the bigger picture.
- - - - -
51cbfb3e by Wolfgang Jeltsch at 2026-10-06T17:22:39+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.
- - - - -
24 changed files:
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Main/Interactive.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Driver/Session/Inspect.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Load.hs-boot
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Unit/External.hs
- compiler/GHC/Unit/Module/ModIface.hs
- ghc/Main.hs
- utils/count-deps/Main.hs
Changes:
=====================================
compiler/GHC/Driver/Downsweep.hs
=====================================
@@ -688,7 +688,8 @@ expandFixedModuleNode key loc = do
-- part of the compiler.
lookupIfaceByModuleHsc hsc_env (mnkToModule key) >>= \case
Just iface -> return (M.Succeeded iface)
- Nothing -> readIface (hsc_hooks hsc_env) (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule key) (ml_hi_file loc)
+ Nothing -> fmap shrinkModIface <$>
+ readIface (hsc_hooks hsc_env) (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule key) (ml_hi_file loc)
case read_result of
M.Succeeded iface -> do
-- Computer information about this node
=====================================
compiler/GHC/Driver/Env.hs
=====================================
@@ -372,10 +372,10 @@ lookupIfaceByModule
:: HomeUnitGraph
-> PackageIfaceTable
-> Module
- -> IO (Maybe ModIface)
+ -> IO (Maybe RetainedModIface)
lookupIfaceByModule hug pit mod
= HUG.lookupHugByModule mod hug >>= pure . \case
- Just hm -> Just (hm_iface hm)
+ Just hm -> Just (shrinkModIface (hm_iface hm))
Nothing -> lookupModuleEnv pit mod
-- If the module does come from the home package, why do we look in the PIT as well?
-- (a) In OneShot mode, even home-package modules accumulate in the PIT
@@ -384,7 +384,7 @@ lookupIfaceByModule hug pit mod
-- We could eliminate (b) if we wanted, by making GHC.Prim belong to a package
-- of its own, but it doesn't seem worth the bother.
-lookupIfaceByModuleHsc :: HscEnv -> Module -> IO (Maybe ModIface)
+lookupIfaceByModuleHsc :: HscEnv -> Module -> IO (Maybe RetainedModIface)
lookupIfaceByModuleHsc hsc_env mod = do
eps <- hscEPS hsc_env
lookupIfaceByModule (hsc_HUG hsc_env) (eps_PIT eps) mod
=====================================
compiler/GHC/Driver/Main/Interactive.hs
=====================================
@@ -148,7 +148,7 @@ hscIsGHCiMonad :: HscEnv -> String -> IO Name
hscIsGHCiMonad hsc_env name
= runHsc hsc_env $ ioMsgMaybe $ hoistTcRnMessage $ isGHCiMonad hsc_env name
-hscGetModuleInterface :: HscEnv -> Module -> IO ModIface
+hscGetModuleInterface :: HscEnv -> Module -> IO RetainedModIface
hscGetModuleInterface hsc_env0 mod = runInteractiveHsc hsc_env0 $ do
hsc_env <- getHscEnv
ioMsgMaybe $ hoistTcRnMessage $ getModuleInterface hsc_env mod
@@ -270,7 +270,7 @@ hscCheckSafe' m l = do
_ | isHomeModule home_unit mod -> True
_ -> isUnitTrusted unit_state (moduleUnit m)
- lookup' :: Module -> Hsc (Maybe ModIface)
+ lookup' :: Module -> Hsc (Maybe RetainedModIface)
lookup' m = do
hsc_env <- getHscEnv
iface <- liftIO $ lookupIfaceByModuleHsc hsc_env m
=====================================
compiler/GHC/Driver/Main/Passes.hs
=====================================
@@ -1335,7 +1335,7 @@ hscCheckSafe' m l = do
_ | isHomeModule home_unit mod -> True
_ -> isUnitTrusted unit_state (moduleUnit m)
- lookup' :: Module -> Hsc (Maybe ModIface)
+ lookup' :: Module -> Hsc (Maybe RetainedModIface)
lookup' m = do
hsc_env <- getHscEnv
iface <- liftIO $ lookupIfaceByModuleHsc hsc_env m
=====================================
compiler/GHC/Driver/Plugins.hs
=====================================
@@ -224,7 +224,7 @@ data PluginWithArgs = PluginWithArgs
data LoadedPlugin = LoadedPlugin
{ lpPlugin :: PluginWithArgs
-- ^ the actual plugin together with its commandline arguments
- , lpModule :: ModIface
+ , lpModule :: RetainedModIface
-- ^ the module containing the plugin
}
=====================================
compiler/GHC/Driver/Session/Inspect.hs
=====================================
@@ -87,7 +87,7 @@ data ModuleInfo = ModuleInfo {
minf_type_env :: TypeEnv,
minf_exports :: [AvailInfo],
minf_instances :: [ClsInst],
- minf_iface :: Maybe ModIface,
+ minf_iface :: Maybe RetainedModIface,
minf_safe :: SafeHaskellMode,
minf_modBreaks :: Maybe InternalModBreaks
}
@@ -140,7 +140,7 @@ getHomeModuleInfo hsc_env mdl =
Nothing -> return Nothing
Just hmi -> do
let details = hm_details hmi
- iface = hm_iface hmi
+ iface = shrinkModIface (hm_iface hmi)
return (Just (ModuleInfo {
minf_type_env = md_types details,
minf_exports = md_exports details,
@@ -187,7 +187,7 @@ modInfoLookupName minf name = withSession $ \hsc_env -> do
Just tyThing -> return (Just tyThing)
Nothing -> liftIO (lookupType hsc_env name)
-modInfoIface :: ModuleInfo -> Maybe ModIface
+modInfoIface :: ModuleInfo -> Maybe RetainedModIface
modInfoIface = minf_iface
-- | Retrieve module safe haskell mode
=====================================
compiler/GHC/HsToCore/Usage.hs
=====================================
@@ -276,7 +276,7 @@ mk_mod_usage_info uc home_unit home_unit_ids this_mod direct_imports imp_decls u
-- a) we used something from it; has something in used_names
-- b) we imported it, even if we used nothing from it
-- (need to recompile if its export list changes: export_fprint)
- mkUsage :: Module -> ModIface -> Maybe Usage
+ mkUsage :: Module -> RetainedModIface -> Maybe Usage
mkUsage mod iface
| toUnitId (moduleUnit mod) `Set.notMember` home_unit_ids
= Just $ UsagePackageModule{ usg_mod = mod,
@@ -302,9 +302,9 @@ mk_mod_usage_info uc home_unit home_unit_ids this_mod direct_imports imp_decls u
usg_entities = Map.toList ent_hashs,
usg_safe = imp_safe }
where
- finsts_mod = mi_finsts iface
+ finsts_mod = mi_abi_finsts (mi_abi_hashes iface)
hash_env = mi_hash_fn iface
- mod_hash = mi_mod_hash iface
+ mod_hash = mi_abi_mod_hash (mi_abi_hashes iface)
imported_exports
= if not depend_on_exports
then Nothing
@@ -312,9 +312,9 @@ mk_mod_usage_info uc home_unit home_unit_ids this_mod direct_imports imp_decls u
Just $
HomeModImport
{ hmiu_orphanLikeHash
- = mi_orphan_like_hash iface
+ = mi_abi_orphan_like_hash (mi_abi_hashes iface)
, hmiu_importedAvails
- = moduleImportedAvails mod (mi_export_avails_hash iface) imp_decls
+ = moduleImportedAvails mod (mi_abi_export_avails_hash (mi_abi_hashes iface)) imp_decls
}
by_is_safe (ImportedByUser imv) = imv_is_safe imv
=====================================
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/Load.hs
=====================================
@@ -308,7 +308,7 @@ loadKnownKeyOccMaps
known_key_maps :: Module -> IfM lcl KnownKeyNameMaps
known_key_maps mod
= do { iface <- loadInterfaceWithException doc mod ImportBySystem
- ; let !abi_hash = mi_mod_hash iface
+ ; let !abi_hash = mi_abi_mod_hash (mi_abi_hashes iface)
; eps <- getEps
; case lookupModuleEnv (eps_known_keys eps) mod of
Just (cached_hash, kk_maps)
@@ -321,7 +321,7 @@ loadKnownKeyOccMaps
(abi_hash, kk_maps) }
; return kk_maps } }
- build_maps :: ModIface -> KnownKeyNameMaps
+ build_maps :: RetainedModIface -> KnownKeyNameMaps
build_maps iface = (kk_map, occ_map)
where
kk_map :: UniqFM KnownKey Name
@@ -628,7 +628,7 @@ loadSrcInterface :: SDoc
-> ModuleName
-> IsBootInterface -- {-# SOURCE #-} ?
-> PkgQual -- "package", if any
- -> RnM ModIface
+ -> RnM RetainedModIface
loadSrcInterface doc scope mod want_boot maybe_pkg
= do { res <- loadSrcInterface_maybe doc scope mod want_boot maybe_pkg
@@ -648,7 +648,7 @@ loadSrcInterface_maybe :: SDoc
-> ModuleName
-> IsBootInterface -- {-# SOURCE #-} ?
-> PkgQual -- "package", if any
- -> RnM (MaybeErr MissingInterfaceError ModIface)
+ -> RnM (MaybeErr MissingInterfaceError RetainedModIface)
loadSrcInterface_maybe doc scope mod want_boot maybe_pkg
-- We must first find which Module this import refers to. This involves
@@ -667,7 +667,7 @@ loadSrcInterface_maybe doc scope mod want_boot maybe_pkg
-- rare operation, but in particular it is used to load orphan modules
-- in order to pull their instances into the global package table and to
-- handle some operations in GHCi).
-loadModuleInterface :: SDoc -> Module -> TcM ModIface
+loadModuleInterface :: SDoc -> Module -> TcM RetainedModIface
loadModuleInterface doc mod = initIfaceTcRn (loadSysInterface doc mod)
-- | Load interfaces for a collection of modules.
@@ -681,7 +681,7 @@ loadModuleInterfaces doc mods
-- | Loads the interface for a given Name.
-- Should only be called for an imported name;
-- otherwise loadSysInterface may not find the interface
-loadInterfaceForName :: SDoc -> Name -> TcRn ModIface
+loadInterfaceForName :: SDoc -> Name -> TcRn RetainedModIface
loadInterfaceForName doc name
= do { when debugIsOn $ -- Check pre-condition
do { this_mod <- getModule
@@ -690,7 +690,7 @@ loadInterfaceForName doc name
initIfaceTcRn $ loadSysInterface doc (nameModule name) }
-- | Loads the interface for a given Module.
-loadInterfaceForModule :: SDoc -> Module -> TcRn ModIface
+loadInterfaceForModule :: SDoc -> Module -> TcRn RetainedModIface
loadInterfaceForModule doc m
= do
-- Should not be called with this module
@@ -724,23 +724,23 @@ loadWiredInHomeIface name
------------------
-- | Loads a system interface and throws an exception if it fails
-loadSysInterface :: SDoc -> Module -> IfM lcl ModIface
+loadSysInterface :: SDoc -> Module -> IfM lcl RetainedModIface
loadSysInterface doc mod_name = loadInterfaceWithException doc mod_name ImportBySystem
------------------
-- | Loads a user interface and throws an exception if it fails. The first parameter indicates
-- whether we should import the boot variant of the module
-loadUserInterface :: IsBootInterface -> SDoc -> Module -> IfM lcl ModIface
+loadUserInterface :: IsBootInterface -> SDoc -> Module -> IfM lcl RetainedModIface
loadUserInterface is_boot doc mod_name
= loadInterfaceWithException doc mod_name (ImportByUser is_boot)
-loadPluginInterface :: SDoc -> Module -> IfM lcl ModIface
+loadPluginInterface :: SDoc -> Module -> IfM lcl RetainedModIface
loadPluginInterface doc mod_name
= loadInterfaceWithException doc mod_name ImportByPlugin
------------------
-- | A wrapper for 'loadInterface' that throws an exception if it fails
-loadInterfaceWithException :: SDoc -> Module -> WhereFrom -> IfM lcl ModIface
+loadInterfaceWithException :: SDoc -> Module -> WhereFrom -> IfM lcl RetainedModIface
loadInterfaceWithException doc mod_name where_from
= do
dflags <- getDynFlags
@@ -749,7 +749,7 @@ loadInterfaceWithException doc mod_name where_from
------------------
loadInterface :: SDoc -> Module -> WhereFrom
- -> IfM lcl (MaybeErr MissingInterfaceError ModIface)
+ -> IfM lcl (MaybeErr MissingInterfaceError RetainedModIface)
-- loadInterface looks in both the HPT and PIT for the required interface
-- If not found, it loads it, and puts it in the PIT (always).
@@ -796,7 +796,7 @@ loadInterface doc_str mod from
liftIO $ computeInterface hsc_env doc_str hi_boot_file mod
; case read_result of {
Failed err -> do
- { let fake_iface = emptyFullModIface mod
+ { let fake_iface = shrinkModIface (emptyFullModIface mod)
; updateEps_ $ \eps ->
eps { eps_PIT = extendModuleEnv (eps_PIT eps) (mi_module fake_iface) fake_iface }
@@ -856,16 +856,7 @@ loadInterface doc_str mod from
; new_eps_complete_matches <- tcIfaceCompleteMatches (mi_complete_matches iface)
; purged_hsc_env <- getTopEnv
- ; let final_iface = iface
- & set_mi_decls (panic "No mi_decls in PIT")
- & set_mi_insts (panic "No mi_insts in PIT")
- & set_mi_defaults (panic "No mi_defaults in PIT")
- & set_mi_fam_insts (panic "No mi_fam_insts in PIT")
- & set_mi_rules (panic "No mi_rules in PIT")
- & set_mi_anns (panic "No mi_anns in PIT")
- & set_mi_simplified_core (panic "No mi_simplified_core in PIT")
-
- bad_boot = mi_boot iface == IsBoot
+ ; let bad_boot = mi_boot iface == IsBoot
&& isJust (lookupKnotVars (if_rec_types gbl_env) mod)
-- Warn against an EPS-updating import
-- of one's own boot file! (one-shot only)
@@ -892,7 +883,7 @@ loadInterface doc_str mod from
then eps { eps_PTE = addDeclsToPTE (eps_PTE eps) new_eps_decls }
else
eps {
- eps_PIT = extendModuleEnv (eps_PIT eps) mod final_iface,
+ eps_PIT = extendModuleEnv (eps_PIT eps) mod (shrinkModIface iface),
eps_PTE = addDeclsToPTE (eps_PTE eps) new_eps_decls,
eps_iface_bytecode = add_bytecode (eps_iface_bytecode eps),
eps_rule_base = extendRuleBaseList (eps_rule_base eps)
@@ -921,10 +912,8 @@ loadInterface doc_str mod from
eps_defaults = extendModuleEnv (eps_defaults eps) mod new_eps_defaults
}
- ; -- invoke plugins with *full* interface, not final_iface, to ensure
- -- that plugins have access to declarations, etc.
- res <- withPlugins (hsc_plugins hsc_env) (\p -> interfaceLoadAction p) iface
- ; return (Succeeded res)
+ ; res <- withPlugins (hsc_plugins hsc_env) (\p -> interfaceLoadAction p) iface
+ ; return (Succeeded (shrinkModIface res))
}}}}
{- Note [Loading your own hi-boot file]
=====================================
compiler/GHC/Iface/Load.hs-boot
=====================================
@@ -2,7 +2,7 @@ module GHC.Iface.Load where
import GHC.Unit.Module (Module)
import GHC.Tc.Utils.Monad (IfM)
-import GHC.Unit.Module.ModIface (ModIface)
+import GHC.Unit.Module.ModIface (RetainedModIface)
import GHC.Utils.Outputable (SDoc)
-loadSysInterface :: SDoc -> Module -> IfM lcl ModIface
+loadSysInterface :: SDoc -> Module -> IfM lcl RetainedModIface
=====================================
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/Iface/Recomp.hs
=====================================
@@ -707,7 +707,7 @@ checkDependencies hsc_env summary iface
return $ needsRecompileBecause $ ModulePackageChanged new_name
-needInterface :: Module -> (ModIface -> IO RecompileRequired)
+needInterface :: Module -> (RetainedModIface -> IO RecompileRequired)
-> IfG RecompileRequired
needInterface mod continue
= do
@@ -727,7 +727,7 @@ needBytecode mod continue
Nothing -> return $ NeedsRecompile MustCompile
Just mbc -> liftIO $ continue mbc
-tryGetModIface :: String -> Module -> IfG (Maybe ModIface)
+tryGetModIface :: String -> Module -> IfG (Maybe RetainedModIface)
tryGetModIface doc_msg mod
= do -- Load the imported interface if possible
logger <- getLogger
@@ -779,7 +779,7 @@ checkModUsage _ UsagePackageModule{
logger <- getLogger
needInterface mod $ \iface -> do
let reason = ModuleChanged (moduleName mod)
- checkModuleFingerprint logger reason old_mod_hash (mi_mod_hash iface)
+ checkModuleFingerprint logger reason old_mod_hash (mi_abi_mod_hash (mi_abi_hashes iface))
-- We only track the ABI hash of package modules, rather than
-- individual entity usages, so if the ABI hash changes we must
-- recompile. This is safe but may entail more recompilation when
@@ -789,7 +789,7 @@ checkModUsage _ UsageMergedRequirement{ usg_mod = mod, usg_mod_hash = old_mod_ha
logger <- getLogger
needInterface mod $ \iface -> do
let reason = ModuleChangedRaw (moduleName mod)
- checkModuleFingerprint logger reason old_mod_hash (mi_mod_hash iface)
+ checkModuleFingerprint logger reason old_mod_hash (mi_abi_mod_hash (mi_abi_hashes iface))
checkModUsage _ UsageHomeModuleBytecode{ usg_mod_name = mod_name
, usg_unit_id = uid
, usg_bytecode_hash = old_bytecode_hash } = do
@@ -810,7 +810,7 @@ checkModUsage _ UsageHomeModule{
logger <- getLogger
needInterface mod $ \iface -> do
let
- new_mod_hash = mi_mod_hash iface
+ new_mod_hash = mi_abi_mod_hash (mi_abi_hashes iface)
new_decl_hash = mi_hash_fn iface
reason = ModuleChanged (moduleName mod)
@@ -864,7 +864,7 @@ checkModUsage fc UsageDirectory{ usg_dir_path = dir,
-- Does this require recompilation?
--
-- See Note [When to recompile when export lists change?]
-checkHomeModImport :: Logger -> RecompReason -> Maybe HomeModImport -> ModIface -> IO RecompileRequired
+checkHomeModImport :: Logger -> RecompReason -> Maybe HomeModImport -> RetainedModIface -> IO RecompileRequired
checkHomeModImport _ _ Nothing _ = return UpToDate
checkHomeModImport logger reason
(Just (HomeModImport old_orphan_like_hash old_avails))
@@ -901,8 +901,8 @@ checkHomeModImport logger reason
2 (ppr changes)
return $ needsRecompileBecause reason
where
- new_orphan_like_hash = mi_orphan_like_hash iface
- new_avails_hash = mi_export_avails_hash iface
+ new_orphan_like_hash = mi_abi_orphan_like_hash (mi_abi_hashes iface)
+ new_avails_hash = mi_abi_export_avails_hash (mi_abi_hashes iface)
new_exports = mi_exports iface
-- | The exported avails of a module have changed. Should this cause recompilation
@@ -1617,7 +1617,7 @@ getOrphanHashes hsc_env mods = do
get_orph_hash mod = do
iface <- initIfaceLoad hsc_env . withIfaceErr ctx
$ loadInterface (text "getOrphanHashes") mod ImportBySystem
- return (mi_orphan_hash iface)
+ return (mi_abi_orphan_hash (mi_abi_hashes iface))
mapM get_orph_hash mods
=====================================
compiler/GHC/Rename/Names.hs
=====================================
@@ -517,7 +517,7 @@ renamePkgQual unit_env mn mb_pkg = case mb_pkg of
-- interface, but without 'imp_mods'.
calculateAvails :: HomeUnit
-> S.Set UnitId
- -> ModIface
+ -> RetainedModIface
-> IsSafeImport
-> IsBootInterface
-> ImportedBy
@@ -525,8 +525,8 @@ calculateAvails :: HomeUnit
calculateAvails home_unit other_home_units iface mod_safe' want_boot imported_by =
let imp_mod = mi_module iface
imp_sem_mod= mi_semantic_module iface
- orph_iface = mi_orphan iface
- has_finsts = mi_finsts iface
+ orph_iface = mi_abi_orphan (mi_abi_hashes iface)
+ has_finsts = mi_abi_finsts (mi_abi_hashes iface)
deps = mi_deps iface
trust = getSafeMode $ mi_trust iface
trust_pkg = mi_trust_pkg iface
@@ -1209,7 +1209,7 @@ gresFromAvail hsc_env prov avail =
gresFromAvails :: HscEnv -> Maybe ImportSpec -> [AvailInfo] -> [GlobalRdrElt]
gresFromAvails hsc_env prov = concatMap (gresFromAvail hsc_env prov)
-importsFromIface :: HscEnv -> ModIface -> ImpDeclSpec -> Maybe NameSet -> GlobalRdrEnv
+importsFromIface :: HscEnv -> RetainedModIface -> ImpDeclSpec -> Maybe NameSet -> GlobalRdrEnv
importsFromIface hsc_env iface decl_spec hidden = mkGlobalRdrEnv $ case hidden of
Nothing -> all_gres
Just hidden_names -> filter (not . (`elemNameSet` hidden_names) . greName) all_gres
@@ -1225,7 +1225,7 @@ rnNamespaceSpecifier (DataNamespaceSpecifier x) = DataNamespaceSpecifier x
filterImports
:: HasDebugCallStack
=> HscEnv
- -> ModIface
+ -> RetainedModIface
-> ImpDeclSpec
-- ^ Import spec
-> Maybe (ImportListInterpretation, [LIE GhcPs])
@@ -2327,7 +2327,7 @@ getMinimalImports ie_decls
where
doc = text "Compute minimal imports for" <+> ppr decl
- to_ie :: GlobalRdrEnv -> ModIface -> AvailInfo -> RnM [IE GhcRn]
+ to_ie :: GlobalRdrEnv -> RetainedModIface -> AvailInfo -> RnM [IE GhcRn]
-- The main trick here is that if we're importing all the constructors
-- we want to say "T(..)", but if we're importing only a subset we want
-- to say "T(A,B,C)". So we have to find out what the module exports.
@@ -2529,7 +2529,7 @@ DRFPatSynExport for a test of this.
-}
badImportItemErr
- :: ModIface -> ImpDeclSpec -> IE GhcPs
+ :: RetainedModIface -> ImpDeclSpec -> IE GhcPs
-> IsSubordinateError
-> [AvailInfo]
-> TcRn (NonEmpty ImportLookupReason)
=====================================
compiler/GHC/Rename/Utils.hs
=====================================
@@ -534,7 +534,7 @@ warnIfDeclDeprecated gre@(GRE { gre_imp = iss })
definedMod = moduleName $ assertPpr (isExternalName name) (ppr name) (nameModule name)
doc = text "The name" <+> quotes (ppr occ) <+> text "is mentioned explicitly"
-lookupImpDeclDeprec :: ModIface -> GlobalRdrElt -> Maybe (WarningTxt GhcRn)
+lookupImpDeclDeprec :: RetainedModIface -> GlobalRdrElt -> Maybe (WarningTxt GhcRn)
lookupImpDeclDeprec iface gre
-- Bleat if the thing, or its parent, is warn'd
= mi_decl_warn_fn iface (greOccName gre) `mplus`
=====================================
compiler/GHC/Runtime/Loader.hs
=====================================
@@ -190,7 +190,7 @@ checkExternalInterpreter hsc_env = case interpInstance <$> hsc_interp hsc_env of
-> throwIO (InstallationError "Plugins require -fno-external-interpreter")
_ -> pure ()
-loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [LinkableUsage], PkgsLoaded)
+loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, RetainedModIface, [LinkableUsage], PkgsLoaded)
loadPlugin' occ_name plugin_name hsc_env mod_name
= do { let plugin_rdr_name = mkRdrQual mod_name occ_name
dflags = hsc_dflags hsc_env
@@ -341,7 +341,7 @@ lessUnsafeCoerce logger context what = do
-- Need the module as well to record information in the interface file
lookupRdrNameInModuleForPlugins :: HasDebugCallStack
=> HscEnv -> ModuleName -> RdrName
- -> IO (Maybe (Name, ModIface))
+ -> IO (Maybe (Name, RetainedModIface))
lookupRdrNameInModuleForPlugins hsc_env mod_name rdr_name = do
let dflags = hsc_dflags hsc_env
-- First find the unit the module resides in by searching exposed units and home modules
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -6386,7 +6386,7 @@ pprImportLookup :: ImportLookupReason -> SDoc
pprImportLookup = \case
ImportLookupBad k iface decl_spec ie _exts ->
let
- pprImpDeclSpec :: ModIface -> ImpDeclSpec -> SDoc
+ pprImpDeclSpec :: RetainedModIface -> ImpDeclSpec -> SDoc
pprImpDeclSpec iface decl_spec =
quotes (ppr (moduleName $ is_mod decl_spec)) <+> case mi_boot iface of
IsBoot -> text "(hi-boot interface)"
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -215,7 +215,7 @@ import GHC.Types.DefaultEnv (ClassDefaults)
import GHC.Unit.Types (Module)
import GHC.Unit.State (UnitState)
-import GHC.Unit.Module.ModIface (ModIface)
+import GHC.Unit.Module.ModIface (RetainedModIface)
import GHC.Utils.Outputable
@@ -6635,7 +6635,7 @@ data ImportLookupReason where
T9006, T11071, T9905fail2, T5385, T10668
-}
ImportLookupBad :: BadImportKind
- -> ModIface
+ -> RetainedModIface
-> ImpDeclSpec
-> IE GhcPs
-> ImportLookupExtensions
=====================================
compiler/GHC/Tc/Gen/Splice.hs
=====================================
@@ -1693,7 +1693,7 @@ lookupArgDoc i nm = do
_ -> pure Nothing
-- | Returns the module a Name belongs to, if it is isn't local.
-getExternalModIface :: Name -> TcM (Maybe ModIface)
+getExternalModIface :: Name -> TcM (Maybe RetainedModIface)
getExternalModIface nm = do
isLocal <- nameIsLocalOrFrom <$> getModule <*> pure nm
if isLocal
=====================================
compiler/GHC/Tc/Instance/Family.hs
=====================================
@@ -308,7 +308,7 @@ checkFamInstConsistency directlyImpMods
ifc <- modIface mod
deps <- dep_finsts . mi_deps <$> modIface mod
pure $
- if mi_finsts ifc
+ if mi_abi_finsts (mi_abi_hashes ifc)
then mod:deps
else deps
=====================================
compiler/GHC/Tc/Module.hs
=====================================
@@ -2964,7 +2964,7 @@ externaliseAndTidyId this_mod id
-- a package module with an interface on disk. If neither of these is
-- true, then the result will be an error indicating the interface
-- could not be found.
-getModuleInterface :: HscEnv -> Module -> IO (Messages TcRnMessage, Maybe ModIface)
+getModuleInterface :: HscEnv -> Module -> IO (Messages TcRnMessage, Maybe RetainedModIface)
getModuleInterface hsc_env mod
= runTcInteractive NoTcMPlugins hsc_env $
loadModuleInterface (text "getModuleInterface") mod
=====================================
compiler/GHC/Unit/External.hs
=====================================
@@ -49,7 +49,7 @@ type PackageAnnEnv = AnnEnv
type PackageCompleteMatches = CompleteMatches
-- | Helps us find information about modules in the imported packages
-type PackageIfaceTable = ModuleEnv ModIface
+type PackageIfaceTable = ModuleEnv RetainedModIface
-- Domain = modules in the imported packages
-- | Constructs an empty PackageIfaceTable
=====================================
compiler/GHC/Unit/Module/ModIface.hs
=====================================
@@ -2,6 +2,7 @@
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE RecordWildCards #-}
module GHC.Unit.Module.ModIface
( ModIface
@@ -68,19 +69,31 @@ module GHC.Unit.Module.ModIface
, set_mi_fix_fn
, set_mi_hash_fn
, completePartialModIface
- , IfaceBinHandle(..)
+ , shrinkModIface
+ , IfaceBinHandle
, PartialModIface
+ , RetainedModIface
, IfaceAbiHashes (..)
, IfaceSelfRecomp (..)
, IfaceCache (..)
, IfaceSimplifiedCore (..)
, withSelfRecomp
- , IfaceDeclExts
- , IfaceAbiHashesExts
+ , IfaceSelfRecompData
+ , IfaceSimplifiedCoreData
+ , ExtensibleFieldsData
+ , IfaceAnnotationsData
+ , IfaceDeclsData
+ , IfaceDefaultsData
+ , IfaceClsInstsData
+ , IfaceFamInstsData
+ , IfaceRulesData
+ , IfaceCompleteMatchesData
+ , IfaceAbiHashesData
, IfaceExport
, IfacePublic_(..)
, IfacePublic
, PartialIfacePublic
+ , RetainedIfacePublic
, IfaceModInfo(..)
, WhetherHasOrphans
, WhetherHasFamInst
@@ -147,6 +160,7 @@ import GHC.Utils.Binary
import Control.DeepSeq
import Control.Exception
+import Data.Void (Void)
{- Note [Interface file stages]
@@ -167,9 +181,11 @@ We can build a full interface file two ways:
type PartialModIface = ModIface_ 'ModIfaceCore
type ModIface = ModIface_ 'ModIfaceFinal
+type RetainedModIface = ModIface_ 'ModIfaceRetained
type PartialIfacePublic = IfacePublic_ 'ModIfaceCore
type IfacePublic = IfacePublic_ 'ModIfaceFinal
+type RetainedIfacePublic = IfacePublic_ 'ModIfaceRetained
-- | Extends a PartialModIface with hashes of the ABI.
--
@@ -212,34 +228,78 @@ data IfaceCache = IfaceCache
data ModIfacePhase
= ModIfaceCore
- -- ^ Partial interface built based on output of core pipeline.
+ -- ^ Partial interface built from the output of the core pipeline
| ModIfaceFinal
-
--- | Selects a IfaceDecl representation.
--- For fully instantiated interfaces we also maintain
--- a fingerprint, which is used for recompilation checks.
-type family IfaceDeclExts (phase :: ModIfacePhase) = decl | decl -> phase where
- IfaceDeclExts 'ModIfaceCore = IfaceDecl
- IfaceDeclExts 'ModIfaceFinal = (Fingerprint, IfaceDecl)
-
-type family IfaceAbiHashesExts (phase :: ModIfacePhase) = bk | bk -> phase where
- IfaceAbiHashesExts 'ModIfaceCore = ()
- IfaceAbiHashesExts 'ModIfaceFinal = IfaceAbiHashes
+ -- ^ Complete interface
+ | ModIfaceRetained
+ -- ^ Interface shrunk to the parts that may be retained
-- | 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
-
-
-withSelfRecomp :: ModIface_ phase -> r -> (IfaceSelfRecomp -> r) -> r
+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
+ IfaceSelfRecompData 'ModIfaceFinal = Maybe IfaceSelfRecomp
+ IfaceSelfRecompData 'ModIfaceRetained = ()
+
+type family IfaceSimplifiedCoreData (phase :: ModIfacePhase) where
+ IfaceSimplifiedCoreData 'ModIfaceCore = Maybe IfaceSimplifiedCore
+ IfaceSimplifiedCoreData 'ModIfaceFinal = Maybe IfaceSimplifiedCore
+ IfaceSimplifiedCoreData 'ModIfaceRetained = ()
+
+type family ExtensibleFieldsData (phase :: ModIfacePhase) where
+ ExtensibleFieldsData 'ModIfaceCore = ExtensibleFields
+ ExtensibleFieldsData 'ModIfaceFinal = ExtensibleFields
+ ExtensibleFieldsData 'ModIfaceRetained = ()
+
+type family IfaceAnnotationsData (phase :: ModIfacePhase) where
+ IfaceAnnotationsData 'ModIfaceCore = [IfaceAnnotation]
+ IfaceAnnotationsData 'ModIfaceFinal = [IfaceAnnotation]
+ IfaceAnnotationsData 'ModIfaceRetained = ()
+
+-- | The fingerprint in the 'ModIfaceFinal' case is used for recompilation
+-- checks.
+type family IfaceDeclsData (phase :: ModIfacePhase) where
+ IfaceDeclsData 'ModIfaceCore = [IfaceDecl]
+ IfaceDeclsData 'ModIfaceFinal = [(Fingerprint, IfaceDecl)]
+ IfaceDeclsData 'ModIfaceRetained = ()
+
+type family IfaceDefaultsData (phase :: ModIfacePhase) where
+ IfaceDefaultsData 'ModIfaceCore = [IfaceDefault]
+ IfaceDefaultsData 'ModIfaceFinal = [IfaceDefault]
+ IfaceDefaultsData 'ModIfaceRetained = ()
+
+type family IfaceClsInstsData (phase :: ModIfacePhase) where
+ IfaceClsInstsData 'ModIfaceCore = [IfaceClsInst]
+ IfaceClsInstsData 'ModIfaceFinal = [IfaceClsInst]
+ IfaceClsInstsData 'ModIfaceRetained = ()
+
+type family IfaceFamInstsData (phase :: ModIfacePhase) where
+ IfaceFamInstsData 'ModIfaceCore = [IfaceFamInst]
+ IfaceFamInstsData 'ModIfaceFinal = [IfaceFamInst]
+ IfaceFamInstsData 'ModIfaceRetained = ()
+
+type family IfaceRulesData (phase :: ModIfacePhase) where
+ IfaceRulesData 'ModIfaceCore = [IfaceRule]
+ IfaceRulesData 'ModIfaceFinal = [IfaceRule]
+ IfaceRulesData 'ModIfaceRetained = ()
+
+type family IfaceCompleteMatchesData (phase :: ModIfacePhase) where
+ IfaceCompleteMatchesData 'ModIfaceCore = [IfaceCompleteMatch]
+ IfaceCompleteMatchesData 'ModIfaceFinal = [IfaceCompleteMatch]
+ IfaceCompleteMatchesData 'ModIfaceRetained = ()
+
+type family IfaceAbiHashesData (phase :: ModIfacePhase) where
+ IfaceAbiHashesData 'ModIfaceCore = ()
+ IfaceAbiHashesData 'ModIfaceFinal = IfaceAbiHashes
+ IfaceAbiHashesData 'ModIfaceRetained = IfaceAbiHashes
+
+withSelfRecomp :: ModIface -> r -> (IfaceSelfRecomp -> r) -> r
withSelfRecomp iface nk jk =
case mi_self_recomp_info iface of
Nothing -> nk
@@ -258,11 +318,12 @@ withSelfRecomp iface nk jk =
-- fields.
data ModIface_ (phase :: ModIfacePhase)
= PrivateModIface {
- mi_hi_bytes_ :: !(IfaceBinHandle phase),
+ mi_hi_bytes_ :: !(Strict.Maybe (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].
+ -- See Note [Sharing of ModIface] and
+ -- Note [Private fields in ModIface].
mi_iface_hash_ :: Fingerprint, -- A hash of the whole interface
mi_mod_info_ :: IfaceModInfo,
@@ -279,11 +340,11 @@ data ModIface_ (phase :: ModIfacePhase)
-- importing this module. The main, original part of an interface.
- mi_self_recomp_ :: Maybe IfaceSelfRecomp,
+ mi_self_recomp_ :: IfaceSelfRecompData phase,
-- ^ Information needed for checking self-recompilation.
-- See Note [Self recompilation information in interface files]
- mi_simplified_core_ :: Maybe IfaceSimplifiedCore,
+ mi_simplified_core_ :: IfaceSimplifiedCoreData phase,
-- ^ The part of the interface written when `-fwrite-if-simplified-core` is enabled.
-- These parts are used to restart bytecode generation.
@@ -301,7 +362,7 @@ data ModIface_ (phase :: ModIfacePhase)
-- defined by the user). Used for GHCi and for inspecting
-- the contents of modules via the GHC API only.
- mi_ext_fields_ :: ExtensibleFields
+ mi_ext_fields_ :: ExtensibleFieldsData phase
-- ^ Additional optional fields, where the Map key represents
-- the field name, resulting in a (size, serialized data) pair.
-- Because the data is intended to be serialized through the
@@ -334,12 +395,12 @@ data IfacePublic_ phase = IfacePublic {
-- ^ Warnings
-- NOT STRICT! we read this field lazily from the interface file
- mi_anns_ :: [IfaceAnnotation],
+ mi_anns_ :: IfaceAnnotationsData phase,
-- ^ Annotations
-- NOT STRICT! we read this field lazily from the interface file
- mi_decls_ :: [IfaceDeclExts phase],
+ mi_decls_ :: IfaceDeclsData phase,
-- ^ Type, class and variable declarations
-- The hash of an Id changes if its fixity or deprecations change
-- (as well as its type of course)
@@ -347,14 +408,14 @@ data IfacePublic_ phase = IfacePublic {
-- the hash of the parent class/tycon changes
- mi_defaults_ :: [IfaceDefault],
+ mi_defaults_ :: IfaceDefaultsData phase,
-- ^ default declarations exported by the module
-- Instance declarations and rules
- mi_insts_ :: [IfaceClsInst], -- ^ Sorted class instance
- mi_fam_insts_ :: [IfaceFamInst], -- ^ Sorted family instances
- mi_rules_ :: [IfaceRule], -- ^ Sorted rules
+ mi_insts_ :: IfaceClsInstsData phase, -- ^ Sorted class instance
+ mi_fam_insts_ :: IfaceFamInstsData phase, -- ^ Sorted family instances
+ mi_rules_ :: IfaceRulesData phase, -- ^ Sorted rules
mi_trust_ :: IfaceTrustInfo,
@@ -367,20 +428,20 @@ data IfacePublic_ phase = IfacePublic {
-- itself) but imports some trustworthy modules from its own
-- package (which does require its own package be trusted).
-- See Note [Trust Own Package] in GHC.Rename.Names
- mi_complete_matches_ :: [IfaceCompleteMatch],
+ mi_complete_matches_ :: IfaceCompleteMatchesData phase,
-- ^ {-# COMPLETE #-} declarations
mi_caches_ :: IfaceCache,
-- ^ Cached lookups of some parts of mi_public
- mi_abi_hashes_ :: (IfaceAbiHashesExts phase)
+ mi_abi_hashes_ :: IfaceAbiHashesData phase
-- ^ Either `()` or `IfaceAbiHashes` for
-- a fully instantiated interface.
-- These fields are hashes of different parts of the public interface.
}
mkIfacePublic :: [IfaceExport]
- -> [IfaceDeclExts 'ModIfaceFinal]
+ -> [(Fingerprint, IfaceDecl)]
-> [(OccName, Fixity)]
-> IfaceWarnings
-> [IfaceAnnotation]
@@ -501,22 +562,22 @@ That's why in GHC.Driver.Main.hscMaybeWriteIface there is the call to
forceModIface.
-}
-mi_flag_hash :: ModIface_ phase -> Maybe (FingerprintWithValue IfaceDynFlags)
+mi_flag_hash :: ModIface -> Maybe (FingerprintWithValue IfaceDynFlags)
mi_flag_hash = fmap mi_sr_flag_hash . mi_self_recomp_
-mi_opt_hash :: ModIface_ phase -> Maybe Fingerprint
+mi_opt_hash :: ModIface -> Maybe Fingerprint
mi_opt_hash = fmap mi_sr_opt_hash . mi_self_recomp_
-mi_hpc_hash :: ModIface_ phase -> Maybe Fingerprint
+mi_hpc_hash :: ModIface -> Maybe Fingerprint
mi_hpc_hash = fmap mi_sr_hpc_hash . mi_self_recomp_
-mi_src_hash :: ModIface_ phase -> Maybe Fingerprint
+mi_src_hash :: ModIface -> Maybe Fingerprint
mi_src_hash = fmap mi_sr_src_hash . mi_self_recomp_
-mi_usages :: ModIface_ phase -> Maybe [Usage]
+mi_usages :: ModIface -> Maybe [Usage]
mi_usages = fmap mi_sr_usages . mi_self_recomp_
-mi_plugin_hash :: ModIface_ phase -> Maybe Fingerprint
+mi_plugin_hash :: ModIface -> Maybe Fingerprint
mi_plugin_hash = fmap mi_sr_plugin_hash . mi_self_recomp_
-- | Accessor for the module hash of the ABI from a ModIface.
@@ -547,7 +608,7 @@ mi_orphan_hash iface = mi_abi_orphan_hash (mi_abi_hashes iface)
-- | Old-style accessor for whether or not the ModIface came from an hs-boot
-- file.
-mi_boot :: ModIface -> IsBootInterface
+mi_boot :: ModIface_ phase -> IsBootInterface
mi_boot iface = if mi_hsc_src iface == HsBootFile
then IsBoot
else NotBoot
@@ -557,7 +618,7 @@ mi_mnwib iface = GWIB (moduleName $ mi_module iface) (mi_boot iface)
-- | Lookups up a (possibly cached) fixity from a 'ModIface'. If one cannot be
-- found, 'defaultFixity' is returned instead.
-mi_fix :: ModIface -> OccName -> Fixity
+mi_fix :: ModIface_ phase -> OccName -> Fixity
mi_fix iface name = mi_fix_fn iface name `orElse` defaultFixity
-- | The semantic module for this interface; e.g., if it's a interface
@@ -573,7 +634,7 @@ mi_semantic_module iface = mi_mod_info_semantic_module (mi_mod_info iface)
-- | The "precise" free holes, e.g., the signatures that this
-- 'ModIface' depends on.
-mi_free_holes :: ModIface -> UniqDSet ModuleName
+mi_free_holes :: ModIface_ phase -> UniqDSet ModuleName
mi_free_holes iface =
case getModuleInstantiation (mi_module iface) of
(_, Just indef)
@@ -654,7 +715,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
@@ -769,9 +830,9 @@ 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_public_ = emptyPublicModIface [] [] [] [] [] [] [] (),
mi_simplified_core_ = Nothing,
mi_top_env_ = IfaceTopEnv emptyDetOrdAvails [] ,
mi_docs_ = Nothing,
@@ -787,24 +848,39 @@ emptyIfaceModInfo mod = IfaceModInfo
, mi_mod_info_hsc_src = HsSrcFile
}
-
-emptyPublicModIface :: IfaceAbiHashesExts phase -> IfacePublic_ phase
-emptyPublicModIface abi_hashes = IfacePublic
- { mi_exports_ = []
- , mi_decls_ = []
- , mi_fixities_ = []
- , mi_warns_ = IfWarnSome [] []
- , mi_anns_ = []
- , mi_defaults_ = []
- , mi_insts_ = []
- , mi_fam_insts_ = []
- , mi_rules_ = []
- , mi_abi_hashes_ = abi_hashes
- , mi_trust_ = noIfaceTrustInfo
- , mi_trust_pkg_ = False
- , mi_caches_ = emptyModIfaceCache
- , mi_complete_matches_ = []
- }
+emptyPublicModIface :: IfaceAnnotationsData phase
+ -> IfaceDeclsData phase
+ -> IfaceDefaultsData phase
+ -> IfaceClsInstsData phase
+ -> IfaceFamInstsData phase
+ -> IfaceRulesData phase
+ -> IfaceCompleteMatchesData phase
+ -> IfaceAbiHashesData phase
+ -> IfacePublic_ phase
+emptyPublicModIface anns
+ decls
+ defaults
+ insts
+ fam_insts
+ rules
+ complete_matches
+ abi_hashes
+ = IfacePublic
+ { mi_exports_ = []
+ , mi_fixities_ = []
+ , mi_warns_ = IfWarnSome [] []
+ , mi_anns_ = anns
+ , mi_decls_ = decls
+ , mi_defaults_ = defaults
+ , mi_insts_ = insts
+ , mi_fam_insts_ = fam_insts
+ , mi_rules_ = rules
+ , mi_trust_ = noIfaceTrustInfo
+ , mi_trust_pkg_ = False
+ , mi_complete_matches_ = complete_matches
+ , mi_caches_ = emptyModIfaceCache
+ , mi_abi_hashes_ = abi_hashes
+ }
emptyModIfaceCache :: IfaceCache
emptyModIfaceCache = IfaceCache {
@@ -827,8 +903,8 @@ emptyIfaceBackend = IfaceAbiHashes
emptyFullModIface :: Module -> ModIface
emptyFullModIface mod =
(emptyPartialModIface mod)
- { mi_public_ = emptyPublicModIface emptyIfaceBackend
- , mi_hi_bytes_ = FullIfaceBinHandle Strict.Nothing
+ { mi_public_ = emptyPublicModIface [] [] [] [] [] [] [] emptyIfaceBackend
+ , mi_hi_bytes_ = Strict.Nothing
}
@@ -848,11 +924,20 @@ emptyIfaceHashCache _occ = Nothing
-- ModIface is completely forced since it will live in memory for a long time.
-- If forcing it uses a lot of memory, then store less things in ModIface.
-instance ( NFData (IfaceAbiHashesExts (phase :: ModIfacePhase))
- , NFData (IfaceDeclExts (phase :: ModIfacePhase))
+instance ( NFData (IfaceSelfRecompData phase)
+ , NFData (IfaceSimplifiedCoreData phase)
+ , NFData (ExtensibleFieldsData phase)
+ , NFData (IfaceAnnotationsData phase)
+ , NFData (IfaceDeclsData phase)
+ , NFData (IfaceDefaultsData phase)
+ , NFData (IfaceClsInstsData phase)
+ , NFData (IfaceFamInstsData phase)
+ , NFData (IfaceRulesData phase)
+ , NFData (IfaceCompleteMatchesData 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
@@ -882,7 +967,15 @@ instance NFData IfaceAbiHashes where
`seq` rnf a5
`seq` rnf a6
-instance (NFData (IfaceAbiHashesExts phase), NFData (IfaceDeclExts phase)) => NFData (IfacePublic_ phase) where
+instance ( NFData (IfaceAnnotationsData phase)
+ , NFData (IfaceDeclsData phase)
+ , NFData (IfaceDefaultsData phase)
+ , NFData (IfaceClsInstsData phase)
+ , NFData (IfaceFamInstsData phase)
+ , NFData (IfaceRulesData phase)
+ , NFData (IfaceCompleteMatchesData phase)
+ , NFData (IfaceAbiHashesData phase)
+ ) => NFData (IfacePublic_ phase) where
rnf (IfacePublic a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14)
= rnf a1
`seq` rnf a2
@@ -955,10 +1048,9 @@ 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
}
- where
-- | Given a 'PartialIfacePublic', turn it into an 'IfacePublic' by completing
-- missing fields.
@@ -973,13 +1065,39 @@ completePublicModIface decls abi_hashes cache partial = partial
, mi_caches_ = cache
}
+shrinkModIface :: ModIface -> RetainedModIface
+shrinkModIface PrivateModIface {..}
+ = PrivateModIface
+ {
+ mi_hi_bytes_ = Strict.Nothing,
+ mi_public_ = shrinkIfacePublic mi_public_,
+ mi_self_recomp_ = (),
+ mi_simplified_core_ = (),
+ mi_ext_fields_ = (),
+ ..
+ }
+
+shrinkIfacePublic :: IfacePublic -> RetainedIfacePublic
+shrinkIfacePublic IfacePublic {..}
+ = IfacePublic
+ {
+ mi_anns_ = (),
+ mi_decls_ = (),
+ mi_defaults_ = (),
+ mi_insts_ = (),
+ mi_fam_insts_ = (),
+ mi_rules_ = (),
+ mi_complete_matches_ = (),
+ ..
+ }
+
set_mi_mod_info :: IfaceModInfo -> ModIface_ phase -> ModIface_ phase
set_mi_mod_info val iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = val }
-set_mi_self_recomp :: Maybe IfaceSelfRecomp-> ModIface_ phase -> ModIface_ phase
+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
@@ -988,7 +1106,7 @@ set_mi_deps val iface = clear_mi_hi_bytes $ iface { mi_deps_ = val }
set_mi_public :: (IfacePublic_ phase -> IfacePublic_ phase) -> ModIface_ phase -> ModIface_ phase
set_mi_public f iface = clear_mi_hi_bytes $ iface { mi_public_ = f (mi_public_ iface) }
-set_mi_simplified_core :: Maybe IfaceSimplifiedCore -> ModIface_ phase -> ModIface_ phase
+set_mi_simplified_core :: IfaceSimplifiedCoreData phase -> ModIface_ phase -> ModIface_ phase
set_mi_simplified_core val iface = clear_mi_hi_bytes $ iface { mi_simplified_core_ = val }
set_mi_top_env :: IfaceTopEnv -> ModIface_ phase -> ModIface_ phase
@@ -997,7 +1115,7 @@ set_mi_top_env val iface = clear_mi_hi_bytes $ iface { mi_top_env_ = val }
set_mi_docs :: Maybe Docs -> ModIface_ phase -> ModIface_ phase
set_mi_docs val iface = clear_mi_hi_bytes $ iface { mi_docs_ = val }
-set_mi_ext_fields :: ExtensibleFields -> ModIface_ phase -> ModIface_ phase
+set_mi_ext_fields :: ExtensibleFieldsData phase -> ModIface_ phase -> ModIface_ phase
set_mi_ext_fields val iface = clear_mi_hi_bytes $ iface { mi_ext_fields_ = val }
{- Settings for mi_public interface fields -}
@@ -1011,22 +1129,22 @@ set_mi_fixities val = set_mi_public (\iface -> iface { mi_fixities_ = val })
set_mi_warns :: IfaceWarnings -> ModIface_ phase -> ModIface_ phase
set_mi_warns val = set_mi_public (\iface -> iface { mi_warns_ = val })
-set_mi_anns :: [IfaceAnnotation] -> ModIface_ phase -> ModIface_ phase
+set_mi_anns :: IfaceAnnotationsData phase -> ModIface_ phase -> ModIface_ phase
set_mi_anns val = set_mi_public (\iface -> iface { mi_anns_ = val })
-set_mi_insts :: [IfaceClsInst] -> ModIface_ phase -> ModIface_ phase
+set_mi_insts :: IfaceClsInstsData phase -> ModIface_ phase -> ModIface_ phase
set_mi_insts val = set_mi_public (\iface -> iface { mi_insts_ = val })
-set_mi_fam_insts :: [IfaceFamInst] -> ModIface_ phase -> ModIface_ phase
+set_mi_fam_insts :: IfaceFamInstsData phase -> ModIface_ phase -> ModIface_ phase
set_mi_fam_insts val = set_mi_public (\iface -> iface { mi_fam_insts_ = val })
-set_mi_rules :: [IfaceRule] -> ModIface_ phase -> ModIface_ phase
+set_mi_rules :: IfaceRulesData phase -> ModIface_ phase -> ModIface_ phase
set_mi_rules val = set_mi_public (\iface -> iface { mi_rules_ = val })
-set_mi_decls :: [IfaceDeclExts phase] -> ModIface_ phase -> ModIface_ phase
+set_mi_decls :: IfaceDeclsData phase -> ModIface_ phase -> ModIface_ phase
set_mi_decls val = set_mi_public (\iface -> iface { mi_decls_ = val })
-set_mi_defaults :: [IfaceDefault] -> ModIface_ phase -> ModIface_ phase
+set_mi_defaults :: IfaceDefaultsData phase -> ModIface_ phase -> ModIface_ phase
set_mi_defaults val = set_mi_public (\iface -> iface { mi_defaults_ = val })
set_mi_trust :: IfaceTrustInfo -> ModIface_ phase -> ModIface_ phase
@@ -1035,10 +1153,10 @@ set_mi_trust val = set_mi_public (\iface -> iface { mi_trust_ = val })
set_mi_trust_pkg :: Bool -> ModIface_ phase -> ModIface_ phase
set_mi_trust_pkg val = set_mi_public (\iface -> iface { mi_trust_pkg_ = val })
-set_mi_complete_matches :: [IfaceCompleteMatch] -> ModIface_ phase -> ModIface_ phase
+set_mi_complete_matches :: IfaceCompleteMatchesData phase -> ModIface_ phase -> ModIface_ phase
set_mi_complete_matches val = set_mi_public (\iface -> iface { mi_complete_matches_ = val })
-set_mi_abi_hashes :: IfaceAbiHashesExts phase -> ModIface_ phase -> ModIface_ phase
+set_mi_abi_hashes :: IfaceAbiHashesData phase -> ModIface_ phase -> ModIface_ phase
set_mi_abi_hashes val = set_mi_public (\iface -> iface { mi_abi_hashes_ = val })
{- Setters for mi_caches interface fields -}
@@ -1082,11 +1200,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
- }
+clear_mi_hi_bytes iface = iface { mi_hi_bytes_ = Strict.Nothing }
-- ----------------------------------------------------------------------------
-- 'ModIface' pattern synonyms to keep breakage low.
@@ -1183,22 +1297,22 @@ pattern ModIface ::
-> [IfaceExport]
-> [(OccName, Fixity)]
-> IfaceWarnings
- -> [IfaceAnnotation]
- -> [IfaceDeclExts phase]
- -> Maybe IfaceSimplifiedCore
- -> [IfaceDefault]
+ -> IfaceAnnotationsData phase
+ -> IfaceDeclsData phase
+ -> IfaceSimplifiedCoreData phase
+ -> IfaceDefaultsData phase
-> IfaceTopEnv
- -> [IfaceClsInst]
- -> [IfaceFamInst]
- -> [IfaceRule]
+ -> IfaceClsInstsData phase
+ -> IfaceFamInstsData phase
+ -> IfaceRulesData phase
-> IfaceTrustInfo
-> Bool
- -> [IfaceCompleteMatch]
+ -> IfaceCompleteMatchesData phase
-> Maybe Docs
- -> IfaceAbiHashesExts phase
- -> ExtensibleFields
- -> IfaceBinHandle phase
- -> Maybe IfaceSelfRecomp
+ -> IfaceAbiHashesData phase
+ -> ExtensibleFieldsData phase
+ -> Strict.Maybe (IfaceBinHandle phase)
+ -> IfaceSelfRecompData phase
-> (OccName -> Maybe Fixity)
-> (OccName -> Maybe (OccName, Fingerprint))
-> (OccName -> Maybe (WarningTxt GhcRn))
=====================================
ghc/Main.hs
=====================================
@@ -515,7 +515,7 @@ abiHash strs = do
put_ bh hiVersion
-- package hashes change when the compiler version changes (for now)
-- see #5328
- mapM_ (put_ bh . mi_mod_hash) ifaces
+ mapM_ (put_ bh . mi_abi_mod_hash . mi_abi_hashes) ifaces
f <- fingerprintBinMem bh
putStrLn (showPpr dflags f)
=====================================
utils/count-deps/Main.hs
=====================================
@@ -79,5 +79,5 @@ calcDeps modName libdir =
mkModule :: String -> ModuleName -> Module
mkModule ghcUnitId = Module (stringToUnit ghcUnitId)
- modDeps :: ModIface -> [ModuleName]
+ modDeps :: ModIface_ phase -> [ModuleName]
modDeps mi = map (gwib_mod . (\(_, _, mn) -> mn)) $ Set.toList $ dep_direct_mods (mi_deps mi)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c767ce9a48c7401e2e5c772bf7741e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c767ce9a48c7401e2e5c772bf7741e…
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
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: hadrian: Persist the used flavour name in the build root (#20650)
by Marge Bot (@marge-bot) 06 Oct '26
by Marge Bot (@marge-bot) 06 Oct '26
06 Oct '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
b3b89d32 by mangoiv at 2026-10-05T22:03:32-04:00
hadrian: Persist the used flavour name in the build root (#20650)
This executes the idea proposed in #20650, teaching Hadrian to persist
the flavour used to build a build root. This both makes use of multiple
build roots more ergonomic (as the user no longer needs to repeat
themselves) and avoids a tiresome foot-gun (forgetting to specify a
flavour, often wholly invalidating a build root).
Closes #20650.
Co-authored-by: Sylvain Henry <sylvain(a)haskus.fr>
- - - - -
f977837b by mangoiv at 2026-10-05T22:04:21-04:00
configure: fix sed script and subst tooldir script
Fixes #27672
Adds sanity checking for SUBST_TOOLDIR
Metric Decrease:
LinkableUsage01
MultiLayerModulesTH_OneShot
T10547
T12234
T12425
T13035
T13820
T18140
T18730
T18923
T9198
TcPlugin_RewritePerf
mhu-perf
- - - - -
f1cb08be by Hannes Siebenhandl at 2026-10-05T22:05:03-04:00
Prepend in-memory unit database for backpack
The packageDbFlags are stored in reverse order. Thus, prepending will
ensure that the in-memory unit database is the last item on the unit
database stack.
Further, the in-memory unit database needs to be able to shadow units
from earlier unit databases in the unit database stack.
Moreover, a `-clear-package-db` would remove the in-memory database if
it weren't the last item on the stack.
Closes #27835
- - - - -
64ce7e20 by mangoiv at 2026-10-06T10:05:03-04:00
ci: move hadrian/ghci into the lint category so it can be picked up by more runners
Fixes #27817
- - - - -
5fe7e9db by mangoiv at 2026-10-06T10:05:03-04:00
ci: make lint-adjacent jobs into platform independent
- move lint jobs into lint-anyarch tag
- unify lint jobs under the same platform independent container
- - - - -
5d7d60d1 by Kazu Yamamoto at 2026-10-06T10:05:12-04:00
Do not leave standard file descriptors free at startup (#24450)
A process may be started with stdout closed -- `prog >&-` from a shell does
exactly that. Nothing then reserves descriptor 1, and open(), pipe() and
socket() hand out the lowest free descriptor, so the next descriptor the
runtime creates for itself takes it: the ticker's pipe, or a capability's IO
manager control pipe.
'GHC.Internal.IO.StdHandles.stdout' is a CAF, built the first time the program
writes to stdout, which is long after that has happened. It builds a 'Handle'
over descriptor 1, which now belongs to the runtime, and nothing reports an
error because the descriptor is perfectly good. The program then writes its
output into the runtime's own plumbing.
What that looks like from the outside is a hang. The descriptor the Handle has
taken over is the read end of a pipe, so poll() for POLLOUT on it never says
yes and epoll_ctl() accepts a registration for it; the thread waiting to write
blocks for ever. Closing the Handle at exit closes the runtime's descriptor,
which is worse: the ticker then fails on every tick.
'hs_init_ghc' now opens /dev/null onto whichever of descriptors 0, 1 and 2 are
closed, before the runtime creates any descriptor of its own. Each is opened
for the access that descriptor would normally have, read-only for 0 and
write-only for 1 and 2, so that writing to 'stdin' or reading from 'stdout'
still fails rather than quietly succeeding against /dev/null. See
Note [Standard file descriptors must be open].
Moving only the descriptors the runtime opens would not do: the first file the
program itself opened would land on the free number instead. The fix has to
leave no free number. A program run this way therefore finds stdout connected
to /dev/null rather than failing with EBADF on the first write, which is what
such a program would get from most other language runtimes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply(a)anthropic.com>
- - - - -
03383bf1 by Simon Jakobi at 2026-10-06T10:05:13-04:00
changelog: Repair the sentence describing #27477
The description read "programs using could crash", the object of
"using" having been lost. The synopsis already says which programs are
affected, so drop the dangling word.
Assisted-by: Claude Fable 5.1
- - - - -
18 changed files:
- .gitlab-ci.yml
- + changelog.d/24450
- changelog.d/fix-parallel-gc-selector-race-27477
- + changelog.d/hadrian-persist-flavour
- changelog.d/unit-index
- compiler/GHC/Driver/Backpack.hs
- distrib/configure.ac.in
- hadrian/doc/flavours.md
- hadrian/src/Rules.hs
- hadrian/src/Settings.hs
- m4/subst_tooldir.m4
- rts/RtsStartup.c
- + testsuite/tests/backpack/should_compile/T27835.bkp
- + testsuite/tests/backpack/should_compile/T27835.stderr
- testsuite/tests/backpack/should_compile/all.T
- + testsuite/tests/rts/T24450.hs
- + testsuite/tests/rts/T24450.stderr
- testsuite/tests/rts/all.T
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -137,15 +137,37 @@ workflow:
.lint:
stage: tool-lint
tags:
- - lint
- before_script:
- # Allow Git to read from the runner-owned checkout. This is needed
- # for example by the lint-author job.
- - git config --global --add safe.directory "$CI_PROJECT_DIR"
+ - lint-anyarch
+ image: debian:13
rules:
- *drafts-can-fail-lint
- when: always
+.install-ghc-toolchain: &install-ghc-toolchain
+ - apt update
+ - apt install -qy build-essential curl libffi-dev libffi8 libgmp-dev libgmp10 libncurses-dev libncurses6 libtinfo6 pkg-config python3 cmake git happy alex autoconf automake python3 libgmp-dev libnuma-dev libncurses-dev
+ - curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
+ - source /root/.ghcup/env
+ - ghcup --no-verbose install ghc --set --install-targets 'install_bin install_lib update_package_db' '9.10'
+ - ghcup --no-verbose install cabal --set
+ - ghc --info
+ - cabal --version
+
+# linting but we need a boot toolchain
+.lint-ghc-toolchain:
+ extends: .lint
+ before_script:
+ - *install-ghc-toolchain
+ - git config --global --add safe.directory "$CI_PROJECT_DIR"
+
+# linting but we need python
+.lint-python:
+ extends: .lint
+ before_script:
+ - apt update
+ - apt install -qy python3 mypy shellcheck git
+ - git config --global --add safe.directory "$CI_PROJECT_DIR"
+
.nightly: &nightly
variables:
XZ_OPT: "-9"
@@ -217,11 +239,11 @@ not-interruptible:
stage: not-interruptible
script: "true"
interruptible: false
- image: "debian:13"
+ image: debian:13
variables:
GIT_STRATEGY: none
tags:
- - lint
+ - lint-anyarch
rules:
# - if: '$CI_COMMIT_BRANCH == "master"'
# when: always
@@ -242,7 +264,6 @@ include: '.gitlab/jobs.yaml'
ghc-linters:
stage: tool-lint
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
extends: .lint-params
variables:
BUILD_FLAVOUR: default
@@ -258,16 +279,11 @@ ghc-linters:
# Skipped if the MR has the ~"no-changelog" label.
lint-changelog:
stage: tool-lint
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
- extends: .lint
+ extends: .lint-ghc-toolchain
variables:
CHANGELOG_EXPECT_MR: "$CI_MERGE_REQUEST_IID"
GIT_DEPTH: 1
GIT_SUBMODULE_STRATEGY: none
- before_script:
- - export PATH="/opt/toolchain/bin:$PATH"
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
script:
- .gitlab/ci.sh lint_changelog
dependencies: []
@@ -279,42 +295,30 @@ lint-changelog:
# Run mypy Python typechecker on linter scripts.
lint-linters:
- image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
- extends: .lint
+ extends: .lint-python
variables:
GIT_DEPTH: 1
GIT_SUBMODULE_STRATEGY: none
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
script:
- mypy testsuite/tests/linters/regex-linters/*.py
dependencies: []
# Check that .T files all parse by listing broken tests.
lint-testsuite:
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
- extends: .lint
+ extends: .lint-ghc-toolchain
variables:
GIT_DEPTH: 1
GIT_SUBMODULE_STRATEGY: none
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
script:
- - make -Ctestsuite list_broken TEST_HC=$GHC
+ - make -Ctestsuite list_broken TEST_HC=$(which ghc)
dependencies: []
# Run mypy Python typechecker on testsuite driver
typecheck-testsuite:
- image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
- extends: .lint
+ extends: .lint-python
variables:
GIT_DEPTH: 1
GIT_SUBMODULE_STRATEGY: none
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
script:
- mypy testsuite/driver/runtests.py
dependencies: []
@@ -323,7 +327,6 @@ typecheck-testsuite:
# accommodate, e.g., haddock changes not yet upstream) but not on `master` or
# Marge jobs.
.lint-submods:
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
extends: .lint-params
variables:
BUILD_FLAVOUR: default
@@ -341,13 +344,9 @@ typecheck-testsuite:
# Check that commits in an MR were not authored with the identity that CI uses
# when it needs to create commits itself. This only needs Git history.
lint-author:
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
- extends: .lint
+ extends: .lint-python
variables:
GIT_SUBMODULE_STRATEGY: none
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
script:
- git fetch "$CI_MERGE_REQUEST_PROJECT_URL" $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- base="$(git merge-base FETCH_HEAD $CI_COMMIT_SHA)"
@@ -425,12 +424,9 @@ lint-submods-branch:
.lint-params:
needs: []
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
extends: .lint
before_script:
- - export PATH="/opt/toolchain/bin:$PATH"
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
+ - *install-ghc-toolchain
- .gitlab/ci.sh setup
after_script:
- .gitlab/ci.sh save_cache
@@ -448,18 +444,13 @@ lint-submods-branch:
hadrian-ghc-in-ghci:
stage: quick-build
+ extends: .lint-ghc-toolchain
needs:
- job: lint-linters
- job: lint-submods
optional: true
- image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
variables:
GHC_FLAGS: -Werror -Wwarn=unused-imports
- tags:
- - x86_64-linux
script:
- git clean -xdf && git submodule foreach git clean -xdf
- . .gitlab/ci.sh setup
@@ -493,9 +484,6 @@ hadrian-multi:
optional: true
dependencies: null
image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
variables:
GHC_FLAGS: "-Wwarn=deprecations -Wwarn=unused-imports"
CONFIGURE_ARGS: --enable-bootstrap-with-devel-snapshot
@@ -544,6 +532,7 @@ stack-hadrian-build:
extends: hadrian-ghc-in-ghci
stage: quick-build
script:
+ - ghcup --no-verbose install stack --set
- . .gitlab/ci.sh setup
- . .gitlab/ci.sh configure
- hadrian/build-stack --version
@@ -1050,9 +1039,6 @@ perf:
image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
tags:
- x86_64-linux-perf
- before_script:
- # workaround for docker permissions
- - sudo chown ghc:ghc -R .
script:
- root=$(pwd)/ghc
- |
=====================================
changelog.d/24450
=====================================
@@ -0,0 +1,14 @@
+section: rts
+synopsis:
+ Fix a hang when a program is started with a standard file descriptor closed
+description:
+ A process started with stdout or stderr closed -- ``prog >&-`` from a shell
+ does exactly that -- left that descriptor number free for the runtime to
+ take for its own use. The ``Handle`` for the stream, built later when the
+ program first wrote to it, then took over a descriptor belonging to the
+ runtime: the program wrote its output into the runtime's own plumbing and
+ hung, with no error reported anywhere. The runtime now opens ``/dev/null``
+ onto whichever of the descriptors 0, 1 and 2 are closed when it starts, so
+ such a stream is connected to ``/dev/null`` instead.
+mrs: !16710
+issues: #24450
=====================================
changelog.d/fix-parallel-gc-selector-race-27477
=====================================
@@ -1,7 +1,7 @@
section: rts
synopsis: Fix a parallel GC race on weakly-ordered architectures (AArch64) that could crash or silently corrupt the heap
description:
- On weakly-ordered architectures such as AArch64 programs using
+ On weakly-ordered architectures such as AArch64, programs
could crash during parallel garbage collection (segmentation fault
or ``internal error: eval_thunk_selector: strange selectee <n>``) or
continue running with silently corrupted heap data, due to a missing
=====================================
changelog.d/hadrian-persist-flavour
=====================================
@@ -0,0 +1,7 @@
+section: packaging
+synopsis: Hadrian now persists the flavour name in the build root. When
+ rebuilding, the previously used flavour is automatically restored, removing
+ the need to re-specify it on every invocation and avoiding accidental build
+ root invalidation.
+issues: #20650
+mrs: !7017
=====================================
changelog.d/unit-index
=====================================
@@ -1,7 +1,7 @@
section: compiler
synopsis: Use global ``UnitIndex`` to deduplicate ``UnitInfo``s over multiple home units
-issues: #27500 #26423 #27748 #27834
-mrs: !16115 !16598 !16743
+issues: #27500 #26423 #27748 #27834 #27835
+mrs: !16115 !16598 !16743 !16748
description: {
The ``UnitState`` used to be duplicated for all ``HomeUnitEnv``, not sharing any of the ``UnitInfo``s.
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -441,9 +441,11 @@ addInMemoryDatabase dflags u = do
}
let uic = hscUIC hsc_env
liftIO $ cacheExternalUnitDatabase uic newdb
- -- added at the end because ordering matters
+ -- Ordering matters here! We prepend the new unit database, because 'packageDBFlags'
+ -- works like a stack, where what's on top takes precedence over what's below (same as right-to-left when given at the CLI).
+ -- The new db needs highest precedence to overwrite any other in-memory units that potentially occur in the dbs below it.
pure dflags
- { packageDBFlags = packageDBFlags dflags ++ [PackageDB (PkgDbPath (unitDatabasePath newdb))]
+ { packageDBFlags = PackageDB (PkgDbPath (unitDatabasePath newdb)) : packageDBFlags dflags
}
-- | Register a new virtual unit database containing a single unit
=====================================
distrib/configure.ac.in
=====================================
@@ -103,7 +103,7 @@ AC_ARG_ENABLE(distro-toolchain,
AC_SUBST([EnableDistroToolchain])
if test "$HostOS" = "mingw32" -a "$EnableDistroToolchain" = "NO"; then
- FP_SETUP_WINDOWS_TOOLCHAIN([$hardtop/mingw/], [\$\$topdir/../mingw/])
+ FP_SETUP_WINDOWS_TOOLCHAIN([$hardtop/mingw/], [\$topdir/../mingw/])
fi
=====================================
hadrian/doc/flavours.md
=====================================
@@ -3,7 +3,14 @@
Hadrian supports a few predefined _build flavours_, i.e. collections of build
settings that fully define a GHC build (see `src/Flavour.hs`). Users can add their
own build flavours if need be, as described
-[here](https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/user-settings.md#build-flavour).
+[here](https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/user-settings.md#build-flavour) or modify existing flavours using the flavour transformers notion seem below.
+
+The flavour to be used for a build root can be specified on the command-line
+via the `--flavour` flag. Moreover, this flavour name is saved in the build
+root; future invocations of Hadrian without a `--flavour` flag will default to
+the last-used flavour.
+
+See `Note [Persisting the flavour]` in `hadrian/src/Settings.hs`
## Arguments
=====================================
hadrian/src/Rules.hs
=====================================
@@ -129,6 +129,7 @@ packageRules = do
buildRules :: Rules ()
buildRules = do
+ Settings.flavourFileRules
Rules.BinaryDist.bindistRules
Rules.Generate.copyRules
Rules.Generate.generateRules
=====================================
hadrian/src/Settings.hs
=====================================
@@ -1,10 +1,14 @@
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TypeFamilies #-}
+
module Settings (
getExtraArgs, getArgs, getLibraryWays, getRtsWays, flavour, knownPackages,
findPackageByName, unsafeFindPackageByName, unsafeFindPackageByPath,
isLibrary, stagePackages, getBignumBackend, completeSetting,
queryBuildTarget, queryHostTarget,
queryBuild, queryHost,
- queryArch, queryOS, queryVendor
+ queryArch, queryOS, queryVendor,
+ flavourFileRules
) where
import CommandLine
@@ -58,6 +62,56 @@ hadrianFlavours =
, ghcInGhciFlavour, validateFlavour, slowValidateFlavour
]
+{-
+Note [Persisting the flavour]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Passing the flavour on the command-line means the user must consistently pass
+the same --flavour flag to all Hadrian invocations on a particular build root.
+Forgetting even once can result in a full rebuild of the tree.
+
+To avoid this we persist the flavour name in the build root itself
+(specifically, in `<build root>/flavour`). We refer to this file when looking
+up the active flavour, defaulting to it if the user does not specify a flavour
+name explicitly.
+-}
+
+-- | Oracle query type for the active flavour name.
+-- See Note [Persisting the flavour].
+newtype FlavourName = FlavourName ()
+ deriving (Binary, Eq, Hashable, NFData, Show)
+type instance RuleResult FlavourName = String
+
+flavourFileRules :: Rules ()
+flavourFileRules = do
+ root <- buildRootRules
+
+ -- Cache the flavour name lookup for the whole Shake run.
+ -- alwaysRerun ensures the oracle re-executes on every new invocation so
+ -- that a changed --flavour flag is never ignored due to a stale cross-run
+ -- cache entry (CLI args are not tracked as Shake dependencies).
+ -- See Note [Persisting the flavour].
+ void $ addOracleCache $ \(FlavourName _) -> do
+ alwaysRerun
+ let flavourFile = root -/- "flavour"
+ cmdFlavour >>= \case
+ Just nm -> do
+ putBuild $ "Flavour: " ++ nm
+ liftIO $ writeFile flavourFile nm
+ return nm
+ Nothing -> do
+ exists <- doesFileExist flavourFile
+ if exists
+ then do nm <- liftIO $ readFile flavourFile
+ putBuild $ "Flavour: " ++ nm ++ " (cached from last build, override by passing --flavour=... explicitly)"
+ return nm
+ else return userDefaultFlavour
+
+-- | Lookup the requested flavour name, referring to the persistent flavour
+-- file saved from the previous Hadrian execution if not specified.
+-- The result is cached for the whole Shake run via the 'FlavourName' oracle.
+getFlavourName :: Action String
+getFlavourName = askOracle (FlavourName ())
+
-- | This action looks up a flavour with the name given on the
-- command line with @--flavour@, defaulting to 'userDefaultFlavour'
-- when no explicit @--flavour@ is passed. It then applies any
@@ -66,7 +120,7 @@ hadrianFlavours =
-- syntax. See Note [Hadrian settings] at the bottom of this file.
flavour :: Action Flavour
flavour = do
- flavourName <- fromMaybe userDefaultFlavour <$> cmdFlavour
+ flavourName <- getFlavourName
when ("quickest" `isPrefixOf` flavourName) $
fail $ "The `quickest` flavour has been deprecated. Use `quick` instead.\n"
++ "Skip building dynamic libraries with `quick+no_dynamic_libs`\n"
=====================================
m4/subst_tooldir.m4
=====================================
@@ -41,5 +41,5 @@ dnl ghc-toolchain.
# See Note [How we configure the bundled windows toolchain]
AC_DEFUN([SUBST_TOOLDIR],
[
- sed -i.bkp $1 's%'"$mingw_prefix"'%'"$mingw_install_prefix"'%g'
+ sed -i.bkp 's%'"$mingw_prefix"'%'"$mingw_install_prefix"'%g' $1
])
=====================================
rts/RtsStartup.c
=====================================
@@ -69,6 +69,10 @@
#if defined(HAVE_LOCALE_H)
#include <locale.h>
#endif
+#if !defined(mingw32_HOST_OS)
+#include <errno.h>
+#include <fcntl.h>
+#endif
// Count of how many outstanding hs_init()s there have been.
static StgWord hs_init_count = 0;
@@ -81,6 +85,10 @@ static int64_t __codePage = -1;
static void flushStdHandles(void);
+#if !defined(mingw32_HOST_OS)
+static void sanitiseStandardFds(void);
+#endif
+
/* -----------------------------------------------------------------------------
Initialise floating point unit on x86 (currently disabled; See Note
[x86 Floating point precision] in compiler/GHC/CmmToAsm/X86/Instr.hs)
@@ -238,6 +246,82 @@ hs_init_with_rtsopts(int *argc, char **argv[])
void init_ghc_hs_iface(void);
+#if !defined(mingw32_HOST_OS)
+/* See Note [Standard file descriptors must be open]. */
+static void sanitiseStandardFds(void)
+{
+ // The access mode each descriptor would have had, had the process been
+ // started with it open.
+ static const int access_mode[3] = { O_RDONLY, O_WRONLY, O_WRONLY };
+
+ for (int fd = 0; fd <= 2; fd++) {
+ if (fcntl(fd, F_GETFD) != -1 || errno != EBADF) {
+ continue; // already open
+ }
+
+ int nullfd;
+ do {
+ nullfd = open("/dev/null", access_mode[fd]);
+ } while (nullfd == -1 && errno == EINTR);
+
+ if (nullfd == -1) {
+ // No /dev/null to be had. There is nothing better to do than
+ // carry on; the hazard the Note describes is then still there,
+ // but refusing to start would be worse.
+ return;
+ }
+ if (nullfd != fd) {
+ // open() hands out the lowest free descriptor, so this cannot
+ // happen unless something in this process is opening descriptors
+ // concurrently. Do not shuffle its descriptor around.
+ close(nullfd);
+ return;
+ }
+ }
+}
+
+/*
+ * Note [Standard file descriptors must be open]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * A process may be started with any of file descriptors 0, 1 and 2 closed --
+ * from a shell, `prog >&-` does exactly that. Nothing then reserves those
+ * numbers, and open(), pipe() and socket() hand out the lowest free
+ * descriptor, so the next descriptor the runtime creates for itself takes one
+ * of them: the ticker's pipe, or a capability's IO manager control pipe.
+ *
+ * Nothing warns anybody. 'GHC.Internal.IO.StdHandles.stdout' is a CAF, so it
+ * is built the first time the program writes to stdout, which is long after
+ * that has happened, and it builds a 'Handle' over descriptor 1 -- which now
+ * belongs to the runtime. The program then writes its output into the
+ * runtime's own plumbing, and at exit closes it.
+ *
+ * What this looks like from the outside is a hang, because the descriptor the
+ * Handle has taken over is the read end of a pipe. It is a perfectly good
+ * descriptor, so nothing reports an error: poll() for POLLOUT on it simply
+ * never says yes, epoll_ctl() accepts a registration for it, and the thread
+ * waiting to write blocks for ever. See #24450, where this is `prog >&-`
+ * hanging after main has finished.
+ *
+ * Closing those descriptors is legal, so the runtime cannot refuse them; and
+ * moving only the descriptors the runtime opens would not help, since the
+ * first file the program itself opens would land on the free number instead.
+ * The fix is to leave no free number: open /dev/null onto whichever of 0, 1
+ * and 2 are closed, before the runtime creates any descriptor of its own.
+ * Other runtimes do the same, and for the same reason.
+ *
+ * A program run this way therefore finds stdout connected to /dev/null rather
+ * than failing with EBADF on the first write. That is the price of the fix,
+ * and it is the behaviour such a program would get from most other language
+ * runtimes.
+ *
+ * Each substitute is opened for the access the descriptor would normally have:
+ * read-only for 0, write-only for 1 and 2. Opening all three for both would
+ * make the substitute something a real stdin or stdout is not, and writing to
+ * 'stdin' or reading from 'stdout' would then quietly succeed instead of
+ * failing with EBADF.
+ */
+#endif
+
void
hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
{
@@ -252,6 +336,12 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
stg_exit(1);
}
+#if !defined(mingw32_HOST_OS)
+ /* Before anything here opens a file descriptor of its own.
+ See Note [Standard file descriptors must be open]. */
+ sanitiseStandardFds();
+#endif
+
#if defined(wasm32_HOST_ARCH)
char *pwd = getenv("PWD");
if (pwd != NULL) {
=====================================
testsuite/tests/backpack/should_compile/T27835.bkp
=====================================
@@ -0,0 +1,11 @@
+unit p where
+ module P where
+ p :: Int
+ p = 42
+
+unit q where
+ dependency p
+ module Q where
+ import P
+ q :: Int
+ q = p + 1
=====================================
testsuite/tests/backpack/should_compile/T27835.stderr
=====================================
@@ -0,0 +1,7 @@
+[1 of 2] Processing p
+ Instantiating p
+ [1 of 1] Compiling P ( p/P.hs, T27835.out/p/P.o )
+[2 of 2] Processing q
+ Instantiating q
+ [1 of 1] Including p
+ [1 of 1] Compiling Q ( q/Q.hs, T27835.out/q/Q.o )
=====================================
testsuite/tests/backpack/should_compile/all.T
=====================================
@@ -61,3 +61,4 @@ test('T13250', normal, backpack_compile, [''])
test('T13323', normal, backpack_compile, [''])
test('T20396', normal, backpack_compile, [''])
test('T23424', [ignore_stdout, ignore_stderr], backpack_compile, ['-ddump-rn-trace -ddump-if-trace -ddump-tc-trace'])
+test('T27835', normal, backpack_compile, ['-clear-package-db -global-package-db'])
=====================================
testsuite/tests/rts/T24450.hs
=====================================
@@ -0,0 +1,41 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+-- A process may be started with stdout closed -- `prog >&-` from a shell does
+-- exactly that. Nothing then reserves descriptor 1, so the next descriptor
+-- the runtime opens for itself takes it, and the 'Handle' for stdout, built
+-- later when the program first writes, takes over a descriptor belonging to
+-- the runtime. The write then goes into the runtime's own plumbing, and what
+-- this looks like from the outside is a hang. See #24450 and
+-- Note [Standard file descriptors must be open] in rts/RtsStartup.c.
+--
+-- This test is run with its stdin and stdout closed, so what it has to say
+-- goes to stderr. The four writes are the reproducer from the ticket and must
+-- simply finish. The lines after them are what tell the two outcomes apart:
+-- the descriptors the runtime opens for itself are pipes, so finding a pipe on
+-- descriptor 0 or 1 means it was handed to the runtime.
+module Main (main) where
+
+import Control.Exception (IOException, try)
+import System.IO
+import System.Posix.Files (getFdStatus, isCharacterDevice, isNamedPipe)
+import System.Posix.Types (Fd (..))
+
+main :: IO ()
+main = do
+ hPutChar stderr 'A' -- unbuffered
+ hPutChar stdout 'X' -- buffered; this is the one that used to hang
+ hPutChar stderr 'Z' -- unbuffered
+ hPutChar stderr '\n' -- unbuffered
+ mapM_ (\fd -> hPutStrLn stderr =<< describeFd fd) [0, 1]
+
+describeFd :: Fd -> IO String
+describeFd fd = do
+ r <- try (getFdStatus fd)
+ return $ "fd " ++ show fd ++ ": " ++ case r of
+ Left (_ :: IOException) -> "closed"
+ Right st
+ -- What the fix arranges: /dev/null, opened onto the free number
+ -- before the runtime could take it.
+ | isCharacterDevice st -> "character device"
+ -- What #24450 is: the runtime's ticker or control pipe.
+ | isNamedPipe st -> "pipe"
+ | otherwise -> "something else"
=====================================
testsuite/tests/rts/T24450.stderr
=====================================
@@ -0,0 +1,3 @@
+AZ
+fd 0: character device
+fd 1: character device
=====================================
testsuite/tests/rts/all.T
=====================================
@@ -408,6 +408,18 @@ test('T10590', [ ignore_stderr
, req_process
], compile_and_run, [''])
+# Run with stdin and stdout closed -- that is what leaves those descriptors
+# free for the runtime to take, which is the whole of #24450. What the test
+# has to say therefore goes to stderr and is checked against T24450.stderr.
+test('T24450',
+ [ when(opsys('mingw32'), skip) # POSIX only
+ , js_skip # JS backend has its own runtime
+ # The wrapper below would close the stdout of the wasm runtime rather
+ # than that of the program running under it, which tests nothing.
+ , when(arch('wasm32'), skip)
+ , cmd_wrapper(lambda c: c + ' <&- >&-')
+ ], compile_and_run, [''])
+
# 20000 was easily enough to trigger the bug with 7.10
test('T10904', [ extra_run_opts('20000'), req_c ],
compile_and_run, ['T10904lib.c'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aee5101e777cf926166646fbfe8214…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aee5101e777cf926166646fbfe8214…
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
1
0
[Git][ghc/ghc][wip/fendor/dep-json] 5 commits: Add json output format
by Hannes Siebenhandl (@fendor) 06 Oct '26
by Hannes Siebenhandl (@fendor) 06 Oct '26
06 Oct '26
Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC
Commits:
1aaf33fb by fendor at 2026-10-06T15:25:05+02:00
Add json output format
- - - - -
27b131ae by fendor at 2026-10-06T15:25:05+02:00
Add support for multiple home units
- - - - -
004210d0 by fendor at 2026-10-06T15:25:05+02:00
Record OPTIONS_GHC in the `PreprocessingNode`
This allows user to treat modules if they use -XTemplateHaskell, for
example.
- - - - -
dc1e7982 by fendor at 2026-10-06T15:25:05+02:00
Deprecate doMkDependHS
- - - - -
d0d76280 by fendor at 2026-10-06T15:25:05+02:00
Testsuite changes
- - - - -
62 changed files:
- + changelog.d/make-depends-json
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Utils/Json.hs
- + docs/users_guide/make-depends-json-schema-1_0.json
- docs/users_guide/separate_compilation.rst
- ghc/Main.hs
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/mkdepend/Makefile
- testsuite/tests/driver/mkdepend/A.hs → testsuite/tests/driver/mkdepend/T24384/A.hs
- testsuite/tests/driver/mkdepend/C.hs → testsuite/tests/driver/mkdepend/T24384/C.hs
- testsuite/tests/driver/mkdepend/C.hs-boot → testsuite/tests/driver/mkdepend/T24384/C.hs-boot
- testsuite/tests/driver/mkdepend/D.hs → testsuite/tests/driver/mkdepend/T24384/D.hs
- testsuite/tests/driver/mkdepend/E.hs → testsuite/tests/driver/mkdepend/T24384/E.hs
- testsuite/tests/driver/mkdepend/dep-internal/DepInternal.hs → testsuite/tests/driver/mkdepend/T24384/dep-internal/DepInternal.hs
- testsuite/tests/driver/mkdepend/dep-internal/dep-internal.pkg → testsuite/tests/driver/mkdepend/T24384/dep-internal/dep-internal.pkg
- testsuite/tests/driver/mkdepend/dep-public/DepPublic.hs → testsuite/tests/driver/mkdepend/T24384/dep-public/DepPublic.hs
- testsuite/tests/driver/mkdepend/dep-public/dep-public.pkg → testsuite/tests/driver/mkdepend/T24384/dep-public/dep-public.pkg
- testsuite/tests/driver/mkdepend/dep/Dep.hs → testsuite/tests/driver/mkdepend/T24384/dep/Dep.hs
- testsuite/tests/driver/mkdepend/dep/dep.pkg → testsuite/tests/driver/mkdepend/T24384/dep/dep.pkg
- testsuite/tests/driver/mkdepend/foo.h → testsuite/tests/driver/mkdepend/T24384/foo.h
- testsuite/tests/driver/mkdepend/lib/B.hs → testsuite/tests/driver/mkdepend/T24384/lib/B.hs
- + testsuite/tests/driver/mkdepend/T24384/lib/B.hs-boot
- testsuite/tests/driver/mkdepend/preproc.sh → testsuite/tests/driver/mkdepend/T24384/preproc.sh
- testsuite/tests/driver/mkdepend/T24384a.stdout
- + testsuite/tests/driver/mkdepend/T24384b.stdout
- + testsuite/tests/driver/mkdepend/T24384c.stdout
- testsuite/tests/driver/mkdepend/all.T
- + testsuite/tests/driver/mkdepend/format_json.sh
- + testsuite/tests/driver/mkdepend/format_makefile.sh
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs-boot
- + testsuite/tests/driver/mkdepend/mhu01/a/A/TH.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Normal.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Splice.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/c/C.hs
- + testsuite/tests/driver/mkdepend/mhu01/unitA
- + testsuite/tests/driver/mkdepend/mhu01/unitB
- + testsuite/tests/driver/mkdepend/mhu01/unitC
- + testsuite/tests/driver/mkdepend/mhu02/A.hs
- + testsuite/tests/driver/mkdepend/mhu02/B.hs
- + testsuite/tests/driver/mkdepend/mhu02/pp.sh
- + testsuite/tests/driver/mkdepend/mhu02/unitA
- + testsuite/tests/driver/mkdepend/mhu02/unitB
- + testsuite/tests/driver/mkdepend/mhu03/pkg/A.hs
- + testsuite/tests/driver/mkdepend/mhu03/pkg/pp.sh
- + testsuite/tests/driver/mkdepend/mhu03/unitA
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend01/A.hs
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend_mhu02.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu03.dep-json
- testsuite/tests/perf/compiler/large-project/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/abd54272a12ea9f30b340666280de8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/abd54272a12ea9f30b340666280de8…
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
1
0
[Git][ghc/ghc][wip/dcoutts/foreign-label-source-refactoring] 2 commits: fixup! Extend 'foreign import prim' syntax to allow specifying the source package
by David Eichmann (@DavidEichmann) 06 Oct '26
by David Eichmann (@DavidEichmann) 06 Oct '26
06 Oct '26
David Eichmann pushed to branch wip/dcoutts/foreign-label-source-refactoring at Glasgow Haskell Compiler / GHC
Commits:
5bb6024b by David Eichmann at 2026-10-05T15:28:30+01:00
fixup! Extend 'foreign import prim' syntax to allow specifying the source package
- - - - -
ea588929 by David Eichmann at 2026-10-06T11:55:14+01:00
fixup! Rename CCallStaticTargetUnit to CLabelTargetLibrary
- - - - -
2 changed files:
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Types/ForeignCall.hs
Changes:
=====================================
compiler/GHC/Parser/PostProcess.hs
=====================================
@@ -3321,18 +3321,18 @@ parsePrimImportStr str =
-- ""
((Nothing, Nothing) <$ skipSpaces) +++
-- "cmmid"
- ((\() cmmid () -> (Nothing, Just cmmid))
- <$> sp
+ ((\cmmid -> (Nothing, Just cmmid))
+ <$ sp
<*> parse_cmmid
- <*> sp
+ <* sp
) +++
-- "packageName cmmid"
- ((\() pkgname () cmmid () -> (Just pkgname, Just cmmid))
- <$> sp
+ ((\pkgname cmmid -> (Just pkgname, Just cmmid))
+ <$ sp
<*> parse_pkgname
- <*> sp
+ <* sp
<*> parse_cmmid
- <*> sp
+ <* sp
)
parse_cmmid = (:) <$> satisfy cmmid_first_char
=====================================
compiler/GHC/Types/ForeignCall.hs
=====================================
@@ -394,6 +394,10 @@ instance Outputable CLabelTargetLibrary where
data StaticTargetGhc = StaticTargetGhc
{ staticTargetLabel :: SourceText
, staticTargetUnit :: CLabelTargetLibrary
+ -- ^ What package the static target is in.
+ -- Foreign prim imports (CMM) should always use CLabelTargetInUnit.
+ -- Other user defined foreign imports always use CLabelTargetUnknown unless a
+ -- wrapper functin is generated e.g. in the case of capi and dynamic.
}
deriving (Data, Eq)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7ccabc15aac7d817d6789fe00c13d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7ccabc15aac7d817d6789fe00c13d…
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
1
0
[Git][ghc/ghc][wip/fendor/dep-json] 5 commits: Add json output format
by Hannes Siebenhandl (@fendor) 06 Oct '26
by Hannes Siebenhandl (@fendor) 06 Oct '26
06 Oct '26
Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC
Commits:
9ab99be3 by fendor at 2026-10-06T13:33:15+02:00
Add json output format
- - - - -
66226dd8 by fendor at 2026-10-06T14:56:57+02:00
Add support for multiple home units
- - - - -
6a236714 by fendor at 2026-10-06T14:56:57+02:00
Record OPTIONS_GHC in the `PreprocessingNode`
This allows user to treat modules if they use -XTemplateHaskell, for
example.
- - - - -
56631177 by fendor at 2026-10-06T14:56:57+02:00
Deprecate doMkDependHS
- - - - -
abd54272 by fendor at 2026-10-06T14:56:57+02:00
Testsuite changes
- - - - -
62 changed files:
- + changelog.d/make-depends-json
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Utils/Json.hs
- + docs/users_guide/make-depends-json-schema-1_0.json
- docs/users_guide/separate_compilation.rst
- ghc/Main.hs
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/mkdepend/Makefile
- testsuite/tests/driver/mkdepend/A.hs → testsuite/tests/driver/mkdepend/T24384/A.hs
- testsuite/tests/driver/mkdepend/C.hs → testsuite/tests/driver/mkdepend/T24384/C.hs
- testsuite/tests/driver/mkdepend/C.hs-boot → testsuite/tests/driver/mkdepend/T24384/C.hs-boot
- testsuite/tests/driver/mkdepend/D.hs → testsuite/tests/driver/mkdepend/T24384/D.hs
- testsuite/tests/driver/mkdepend/E.hs → testsuite/tests/driver/mkdepend/T24384/E.hs
- testsuite/tests/driver/mkdepend/dep-internal/DepInternal.hs → testsuite/tests/driver/mkdepend/T24384/dep-internal/DepInternal.hs
- testsuite/tests/driver/mkdepend/dep-internal/dep-internal.pkg → testsuite/tests/driver/mkdepend/T24384/dep-internal/dep-internal.pkg
- testsuite/tests/driver/mkdepend/dep-public/DepPublic.hs → testsuite/tests/driver/mkdepend/T24384/dep-public/DepPublic.hs
- testsuite/tests/driver/mkdepend/dep-public/dep-public.pkg → testsuite/tests/driver/mkdepend/T24384/dep-public/dep-public.pkg
- testsuite/tests/driver/mkdepend/dep/Dep.hs → testsuite/tests/driver/mkdepend/T24384/dep/Dep.hs
- testsuite/tests/driver/mkdepend/dep/dep.pkg → testsuite/tests/driver/mkdepend/T24384/dep/dep.pkg
- testsuite/tests/driver/mkdepend/foo.h → testsuite/tests/driver/mkdepend/T24384/foo.h
- testsuite/tests/driver/mkdepend/lib/B.hs → testsuite/tests/driver/mkdepend/T24384/lib/B.hs
- + testsuite/tests/driver/mkdepend/T24384/lib/B.hs-boot
- testsuite/tests/driver/mkdepend/preproc.sh → testsuite/tests/driver/mkdepend/T24384/preproc.sh
- testsuite/tests/driver/mkdepend/T24384a.stdout
- + testsuite/tests/driver/mkdepend/T24384b.stdout
- + testsuite/tests/driver/mkdepend/T24384c.stdout
- testsuite/tests/driver/mkdepend/all.T
- + testsuite/tests/driver/mkdepend/format_json.sh
- + testsuite/tests/driver/mkdepend/format_makefile.sh
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs-boot
- + testsuite/tests/driver/mkdepend/mhu01/a/A/TH.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Normal.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Splice.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/c/C.hs
- + testsuite/tests/driver/mkdepend/mhu01/unitA
- + testsuite/tests/driver/mkdepend/mhu01/unitB
- + testsuite/tests/driver/mkdepend/mhu01/unitC
- + testsuite/tests/driver/mkdepend/mhu02/A.hs
- + testsuite/tests/driver/mkdepend/mhu02/B.hs
- + testsuite/tests/driver/mkdepend/mhu02/pp.sh
- + testsuite/tests/driver/mkdepend/mhu02/unitA
- + testsuite/tests/driver/mkdepend/mhu02/unitB
- + testsuite/tests/driver/mkdepend/mhu03/pkg/A.hs
- + testsuite/tests/driver/mkdepend/mhu03/pkg/pp.sh
- + testsuite/tests/driver/mkdepend/mhu03/unitA
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend01/A.hs
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend_mhu02.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu03.dep-json
- testsuite/tests/perf/compiler/large-project/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd9caa3d5cb83b7cf834823b761f62…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd9caa3d5cb83b7cf834823b761f62…
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
1
0
[Git][ghc/ghc][wip/fendor/dep-json] 4 commits: Add json output format
by Hannes Siebenhandl (@fendor) 06 Oct '26
by Hannes Siebenhandl (@fendor) 06 Oct '26
06 Oct '26
Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC
Commits:
f4caae4d by fendor at 2026-10-06T13:07:48+02:00
Add json output format
- - - - -
0a9cfa65 by fendor at 2026-10-06T13:07:49+02:00
Add support for multiple home units
- - - - -
90d727ae by fendor at 2026-10-06T13:08:05+02:00
Record OPTIONS_GHC in the `PreprocessingNode`
This allows user to treat modules if they use -XTemplateHaskell, for
example.
- - - - -
dd9caa3d by fendor at 2026-10-06T13:08:05+02:00
Testsuite changes
- - - - -
61 changed files:
- + changelog.d/make-depends-json
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Utils/Json.hs
- docs/users_guide/separate_compilation.rst
- ghc/Main.hs
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/mkdepend/Makefile
- testsuite/tests/driver/mkdepend/A.hs → testsuite/tests/driver/mkdepend/T24384/A.hs
- testsuite/tests/driver/mkdepend/C.hs → testsuite/tests/driver/mkdepend/T24384/C.hs
- testsuite/tests/driver/mkdepend/C.hs-boot → testsuite/tests/driver/mkdepend/T24384/C.hs-boot
- testsuite/tests/driver/mkdepend/D.hs → testsuite/tests/driver/mkdepend/T24384/D.hs
- testsuite/tests/driver/mkdepend/E.hs → testsuite/tests/driver/mkdepend/T24384/E.hs
- testsuite/tests/driver/mkdepend/dep-internal/DepInternal.hs → testsuite/tests/driver/mkdepend/T24384/dep-internal/DepInternal.hs
- testsuite/tests/driver/mkdepend/dep-internal/dep-internal.pkg → testsuite/tests/driver/mkdepend/T24384/dep-internal/dep-internal.pkg
- testsuite/tests/driver/mkdepend/dep-public/DepPublic.hs → testsuite/tests/driver/mkdepend/T24384/dep-public/DepPublic.hs
- testsuite/tests/driver/mkdepend/dep-public/dep-public.pkg → testsuite/tests/driver/mkdepend/T24384/dep-public/dep-public.pkg
- testsuite/tests/driver/mkdepend/dep/Dep.hs → testsuite/tests/driver/mkdepend/T24384/dep/Dep.hs
- testsuite/tests/driver/mkdepend/dep/dep.pkg → testsuite/tests/driver/mkdepend/T24384/dep/dep.pkg
- testsuite/tests/driver/mkdepend/foo.h → testsuite/tests/driver/mkdepend/T24384/foo.h
- testsuite/tests/driver/mkdepend/lib/B.hs → testsuite/tests/driver/mkdepend/T24384/lib/B.hs
- + testsuite/tests/driver/mkdepend/T24384/lib/B.hs-boot
- testsuite/tests/driver/mkdepend/preproc.sh → testsuite/tests/driver/mkdepend/T24384/preproc.sh
- testsuite/tests/driver/mkdepend/T24384a.stdout
- + testsuite/tests/driver/mkdepend/T24384b.stdout
- + testsuite/tests/driver/mkdepend/T24384c.stdout
- testsuite/tests/driver/mkdepend/all.T
- + testsuite/tests/driver/mkdepend/format_json.sh
- + testsuite/tests/driver/mkdepend/format_makefile.sh
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs-boot
- + testsuite/tests/driver/mkdepend/mhu01/a/A/TH.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Normal.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Splice.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/c/C.hs
- + testsuite/tests/driver/mkdepend/mhu01/unitA
- + testsuite/tests/driver/mkdepend/mhu01/unitB
- + testsuite/tests/driver/mkdepend/mhu01/unitC
- + testsuite/tests/driver/mkdepend/mhu02/A.hs
- + testsuite/tests/driver/mkdepend/mhu02/B.hs
- + testsuite/tests/driver/mkdepend/mhu02/pp.sh
- + testsuite/tests/driver/mkdepend/mhu02/unitA
- + testsuite/tests/driver/mkdepend/mhu02/unitB
- + testsuite/tests/driver/mkdepend/mhu03/pkg/A.hs
- + testsuite/tests/driver/mkdepend/mhu03/pkg/pp.sh
- + testsuite/tests/driver/mkdepend/mhu03/unitA
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend01/A.hs
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend_mhu02.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu03.dep-json
- testsuite/tests/perf/compiler/large-project/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0707c5d4ba4b1f498faf54b270ef5b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0707c5d4ba4b1f498faf54b270ef5b…
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
1
0
[Git][ghc/ghc][wip/fendor/dep-json] 3 commits: Add support for multiple home units
by Hannes Siebenhandl (@fendor) 06 Oct '26
by Hannes Siebenhandl (@fendor) 06 Oct '26
06 Oct '26
Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC
Commits:
7f76b633 by fendor at 2026-10-06T13:06:34+02:00
Add support for multiple home units
- - - - -
b97a8e29 by fendor at 2026-10-06T13:06:34+02:00
Record OPTIONS_GHC in the `PreprocessingNode`
This allows user to treat modules if they use -XTemplateHaskell, for
example.
- - - - -
0707c5d4 by fendor at 2026-10-06T13:06:34+02:00
Testsuite changes
- - - - -
56 changed files:
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Session/Units.hs
- ghc/Main.hs
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/mkdepend/Makefile
- testsuite/tests/driver/mkdepend/A.hs → testsuite/tests/driver/mkdepend/T24384/A.hs
- testsuite/tests/driver/mkdepend/C.hs → testsuite/tests/driver/mkdepend/T24384/C.hs
- testsuite/tests/driver/mkdepend/C.hs-boot → testsuite/tests/driver/mkdepend/T24384/C.hs-boot
- testsuite/tests/driver/mkdepend/D.hs → testsuite/tests/driver/mkdepend/T24384/D.hs
- testsuite/tests/driver/mkdepend/E.hs → testsuite/tests/driver/mkdepend/T24384/E.hs
- testsuite/tests/driver/mkdepend/dep-internal/DepInternal.hs → testsuite/tests/driver/mkdepend/T24384/dep-internal/DepInternal.hs
- testsuite/tests/driver/mkdepend/dep-internal/dep-internal.pkg → testsuite/tests/driver/mkdepend/T24384/dep-internal/dep-internal.pkg
- testsuite/tests/driver/mkdepend/dep-public/DepPublic.hs → testsuite/tests/driver/mkdepend/T24384/dep-public/DepPublic.hs
- testsuite/tests/driver/mkdepend/dep-public/dep-public.pkg → testsuite/tests/driver/mkdepend/T24384/dep-public/dep-public.pkg
- testsuite/tests/driver/mkdepend/dep/Dep.hs → testsuite/tests/driver/mkdepend/T24384/dep/Dep.hs
- testsuite/tests/driver/mkdepend/dep/dep.pkg → testsuite/tests/driver/mkdepend/T24384/dep/dep.pkg
- testsuite/tests/driver/mkdepend/foo.h → testsuite/tests/driver/mkdepend/T24384/foo.h
- testsuite/tests/driver/mkdepend/lib/B.hs → testsuite/tests/driver/mkdepend/T24384/lib/B.hs
- + testsuite/tests/driver/mkdepend/T24384/lib/B.hs-boot
- testsuite/tests/driver/mkdepend/preproc.sh → testsuite/tests/driver/mkdepend/T24384/preproc.sh
- testsuite/tests/driver/mkdepend/T24384a.stdout
- + testsuite/tests/driver/mkdepend/T24384b.stdout
- + testsuite/tests/driver/mkdepend/T24384c.stdout
- testsuite/tests/driver/mkdepend/all.T
- + testsuite/tests/driver/mkdepend/format_json.sh
- + testsuite/tests/driver/mkdepend/format_makefile.sh
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs-boot
- + testsuite/tests/driver/mkdepend/mhu01/a/A/TH.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Normal.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Splice.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/c/C.hs
- + testsuite/tests/driver/mkdepend/mhu01/unitA
- + testsuite/tests/driver/mkdepend/mhu01/unitB
- + testsuite/tests/driver/mkdepend/mhu01/unitC
- + testsuite/tests/driver/mkdepend/mhu02/A.hs
- + testsuite/tests/driver/mkdepend/mhu02/B.hs
- + testsuite/tests/driver/mkdepend/mhu02/pp.sh
- + testsuite/tests/driver/mkdepend/mhu02/unitA
- + testsuite/tests/driver/mkdepend/mhu02/unitB
- + testsuite/tests/driver/mkdepend/mhu03/pkg/A.hs
- + testsuite/tests/driver/mkdepend/mhu03/pkg/pp.sh
- + testsuite/tests/driver/mkdepend/mhu03/unitA
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend01/A.hs
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend_mhu02.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu03.dep-json
- testsuite/tests/perf/compiler/large-project/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/acb7ad051e4d9dd81fe39878713e63…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/acb7ad051e4d9dd81fe39878713e63…
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
1
0
06 Oct '26
Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC
Commits:
acb7ad05 by fendor at 2026-10-06T12:47:17+02:00
Testsuite changes
- - - - -
51 changed files:
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/mkdepend/Makefile
- testsuite/tests/driver/mkdepend/A.hs → testsuite/tests/driver/mkdepend/T24384/A.hs
- testsuite/tests/driver/mkdepend/C.hs → testsuite/tests/driver/mkdepend/T24384/C.hs
- testsuite/tests/driver/mkdepend/C.hs-boot → testsuite/tests/driver/mkdepend/T24384/C.hs-boot
- testsuite/tests/driver/mkdepend/D.hs → testsuite/tests/driver/mkdepend/T24384/D.hs
- testsuite/tests/driver/mkdepend/E.hs → testsuite/tests/driver/mkdepend/T24384/E.hs
- testsuite/tests/driver/mkdepend/dep-internal/DepInternal.hs → testsuite/tests/driver/mkdepend/T24384/dep-internal/DepInternal.hs
- testsuite/tests/driver/mkdepend/dep-internal/dep-internal.pkg → testsuite/tests/driver/mkdepend/T24384/dep-internal/dep-internal.pkg
- testsuite/tests/driver/mkdepend/dep-public/DepPublic.hs → testsuite/tests/driver/mkdepend/T24384/dep-public/DepPublic.hs
- testsuite/tests/driver/mkdepend/dep-public/dep-public.pkg → testsuite/tests/driver/mkdepend/T24384/dep-public/dep-public.pkg
- testsuite/tests/driver/mkdepend/dep/Dep.hs → testsuite/tests/driver/mkdepend/T24384/dep/Dep.hs
- testsuite/tests/driver/mkdepend/dep/dep.pkg → testsuite/tests/driver/mkdepend/T24384/dep/dep.pkg
- testsuite/tests/driver/mkdepend/foo.h → testsuite/tests/driver/mkdepend/T24384/foo.h
- testsuite/tests/driver/mkdepend/lib/B.hs → testsuite/tests/driver/mkdepend/T24384/lib/B.hs
- + testsuite/tests/driver/mkdepend/T24384/lib/B.hs-boot
- testsuite/tests/driver/mkdepend/preproc.sh → testsuite/tests/driver/mkdepend/T24384/preproc.sh
- testsuite/tests/driver/mkdepend/T24384a.stdout
- + testsuite/tests/driver/mkdepend/T24384b.stdout
- + testsuite/tests/driver/mkdepend/T24384c.stdout
- testsuite/tests/driver/mkdepend/all.T
- + testsuite/tests/driver/mkdepend/format_json.sh
- + testsuite/tests/driver/mkdepend/format_makefile.sh
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs-boot
- + testsuite/tests/driver/mkdepend/mhu01/a/A/TH.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Normal.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Splice.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/c/C.hs
- + testsuite/tests/driver/mkdepend/mhu01/unitA
- + testsuite/tests/driver/mkdepend/mhu01/unitB
- + testsuite/tests/driver/mkdepend/mhu01/unitC
- + testsuite/tests/driver/mkdepend/mhu02/A.hs
- + testsuite/tests/driver/mkdepend/mhu02/B.hs
- + testsuite/tests/driver/mkdepend/mhu02/pp.sh
- + testsuite/tests/driver/mkdepend/mhu02/unitA
- + testsuite/tests/driver/mkdepend/mhu02/unitB
- + testsuite/tests/driver/mkdepend/mhu03/pkg/A.hs
- + testsuite/tests/driver/mkdepend/mhu03/pkg/pp.sh
- + testsuite/tests/driver/mkdepend/mhu03/unitA
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend01/A.hs
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend_mhu02.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu03.dep-json
- testsuite/tests/perf/compiler/large-project/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/acb7ad051e4d9dd81fe39878713e639…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/acb7ad051e4d9dd81fe39878713e639…
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
1
0
[Git][ghc/ghc][wip/fendor/dep-json] 4 commits: Add json output format
by Hannes Siebenhandl (@fendor) 06 Oct '26
by Hannes Siebenhandl (@fendor) 06 Oct '26
06 Oct '26
Hannes Siebenhandl pushed to branch wip/fendor/dep-json at Glasgow Haskell Compiler / GHC
Commits:
73051de9 by fendor at 2026-10-06T12:40:48+02:00
Add json output format
- - - - -
93e7a99b by fendor at 2026-10-06T12:40:48+02:00
Add support for multiple home units
- - - - -
a4910a42 by fendor at 2026-10-06T12:40:48+02:00
Record OPTIONS_GHC in the `PreprocessingNode`
This allows user to treat modules if they use -XTemplateHaskell, for
example.
- - - - -
eec42b61 by fendor at 2026-10-06T12:40:48+02:00
Testsuite changes
- - - - -
61 changed files:
- + changelog.d/make-depends-json
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Utils/Json.hs
- docs/users_guide/separate_compilation.rst
- ghc/Main.hs
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/driver/mkdepend/Makefile
- testsuite/tests/driver/mkdepend/A.hs → testsuite/tests/driver/mkdepend/T24384/A.hs
- testsuite/tests/driver/mkdepend/C.hs → testsuite/tests/driver/mkdepend/T24384/C.hs
- testsuite/tests/driver/mkdepend/C.hs-boot → testsuite/tests/driver/mkdepend/T24384/C.hs-boot
- testsuite/tests/driver/mkdepend/D.hs → testsuite/tests/driver/mkdepend/T24384/D.hs
- testsuite/tests/driver/mkdepend/E.hs → testsuite/tests/driver/mkdepend/T24384/E.hs
- testsuite/tests/driver/mkdepend/dep-internal/DepInternal.hs → testsuite/tests/driver/mkdepend/T24384/dep-internal/DepInternal.hs
- testsuite/tests/driver/mkdepend/dep-internal/dep-internal.pkg → testsuite/tests/driver/mkdepend/T24384/dep-internal/dep-internal.pkg
- testsuite/tests/driver/mkdepend/dep-public/DepPublic.hs → testsuite/tests/driver/mkdepend/T24384/dep-public/DepPublic.hs
- testsuite/tests/driver/mkdepend/dep-public/dep-public.pkg → testsuite/tests/driver/mkdepend/T24384/dep-public/dep-public.pkg
- testsuite/tests/driver/mkdepend/dep/Dep.hs → testsuite/tests/driver/mkdepend/T24384/dep/Dep.hs
- testsuite/tests/driver/mkdepend/dep/dep.pkg → testsuite/tests/driver/mkdepend/T24384/dep/dep.pkg
- testsuite/tests/driver/mkdepend/foo.h → testsuite/tests/driver/mkdepend/T24384/foo.h
- testsuite/tests/driver/mkdepend/lib/B.hs → testsuite/tests/driver/mkdepend/T24384/lib/B.hs
- + testsuite/tests/driver/mkdepend/T24384/lib/B.hs-boot
- testsuite/tests/driver/mkdepend/preproc.sh → testsuite/tests/driver/mkdepend/T24384/preproc.sh
- testsuite/tests/driver/mkdepend/T24384a.stdout
- + testsuite/tests/driver/mkdepend/T24384b.stdout
- + testsuite/tests/driver/mkdepend/T24384c.stdout
- testsuite/tests/driver/mkdepend/all.T
- + testsuite/tests/driver/mkdepend/format_json.sh
- + testsuite/tests/driver/mkdepend/format_makefile.sh
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/A/Base.hs-boot
- + testsuite/tests/driver/mkdepend/mhu01/a/A/TH.hs
- + testsuite/tests/driver/mkdepend/mhu01/a/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Normal.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/B/Splice.hs
- + testsuite/tests/driver/mkdepend/mhu01/b/Util.hs
- + testsuite/tests/driver/mkdepend/mhu01/c/C.hs
- + testsuite/tests/driver/mkdepend/mhu01/unitA
- + testsuite/tests/driver/mkdepend/mhu01/unitB
- + testsuite/tests/driver/mkdepend/mhu01/unitC
- + testsuite/tests/driver/mkdepend/mhu02/A.hs
- + testsuite/tests/driver/mkdepend/mhu02/B.hs
- + testsuite/tests/driver/mkdepend/mhu02/pp.sh
- + testsuite/tests/driver/mkdepend/mhu02/unitA
- + testsuite/tests/driver/mkdepend/mhu02/unitB
- + testsuite/tests/driver/mkdepend/mhu03/pkg/A.hs
- + testsuite/tests/driver/mkdepend/mhu03/pkg/pp.sh
- + testsuite/tests/driver/mkdepend/mhu03/unitA
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend01/A.hs
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu01.dep-makefile
- + testsuite/tests/driver/mkdepend/mkdepend_mhu02.dep-json
- + testsuite/tests/driver/mkdepend/mkdepend_mhu03.dep-json
- testsuite/tests/perf/compiler/large-project/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e47a98b0609e9d582dc1929574837…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e47a98b0609e9d582dc1929574837…
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
1
0
[Git][ghc/ghc][wip/mangoiv/9.12.5-rc4] ci: update signatories for root key for cabal-install 3.8
by Magnus (@MangoIV) 06 Oct '26
by Magnus (@MangoIV) 06 Oct '26
06 Oct '26
Magnus pushed to branch wip/mangoiv/9.12.5-rc4 at Glasgow Haskell Compiler / GHC
Commits:
087fbaa9 by mangoiv at 2026-10-06T12:27:47+02:00
ci: update signatories for root key for cabal-install 3.8
- - - - -
1 changed file:
- .gitlab/ci.sh
Changes:
=====================================
.gitlab/ci.sh
=====================================
@@ -231,6 +231,24 @@ function set_toolchain_paths() {
}
function cabal_update() {
+ # root key signing changes randomly which affects old
+ # cabal-install versions
+ CONFIG="${CABAL_CONFIG:-/builds/ghc/ghc/cabal/config}"
+ mkdir -p "$(dirname "$CONFIG")"
+
+ cat > "$CONFIG" <<'EOF'
+repository hackage.haskell.org
+ url: http://hackage.haskell.org/
+ secure: True
+ key-threshold: 0
+ root-keys:
+ fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0
+ c7de58fc6a224b92b5b513f26fbb8b370f2d97c7cfe0075a951314a55734be93
+ d26e46f3b631aae1433b89379a6c68bd417eb5d1c408f0643dcc07757fece522
+ 1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42
+ key-threshold: 3
+EOF
+
# In principle -w shouldn't be necessary here but with
# cabal-install 3.8.1.0 it is, due to cabal#8447.
run "$CABAL" update -w "$GHC" "hackage.haskell.org,${HACKAGE_INDEX_STATE}"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/087fbaa9bbbedc61b1a4100c7dba763…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/087fbaa9bbbedc61b1a4100c7dba763…
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
1
0