[Git][ghc/ghc][wip/romes/27514] 3 commits: Driver: structured concurrent worker abstraction
by sheaf (@sheaf) 26 Aug '26
by sheaf (@sheaf) 26 Aug '26
26 Aug '26
sheaf pushed to branch wip/romes/27514 at Glasgow Haskell Compiler / GHC
Commits:
57fdff77 by sheaf at 2026-08-26T16:19:39+02:00
Driver: structured concurrent worker abstraction
This commits introduces a structured concurrency framework in the style
of the 'ki' library: a collection of threads within a scope.
We implement two kind of concurrent workers on top of this framework:
- Independent workers cannot wait for one another at all. The only
scheduling operation is to wait for quiescence.
- Coordinating workers declare an STM readiness condition (waiting on
other workers to complete) which gates their start.
See Note [Deterministic concurrent workers] in GHC.Driver.Concurrency.
This commit ports upsweep to this new framework, with downsweep being
left as subsequent work.
Further changes along the way:
- Refactoring of how concurrency is acquired to avoid the footgun of
trying to use a no-op 'AbstractSem' as a lock in the serial case.
- The "re-run with -j1" logic for semaphore opening errors no longer
triggers on late semaphore failures (part-way through a lengthy
computation).
- Logger threads are properly cleaned up on exception, with each
concurrent worker's log queue and local TmpFs properly bracketed.
- The 'GhcMessage -> AnyGhcDiagnostic' and 'Maybe Messager'
arguments of 'depanalE', 'depanalPartial' and 'downsweep', which
were all dead in practice, have been dropped.
- - - - -
56a87ca8 by sheaf at 2026-08-26T16:19:40+02:00
Rule-based deterministic concurrent downsweep
This commit rewrites downsweep as a single query-answering rule
(see 'DownsweepRule') that can be executed by concurrent worker threads.
The design allows every expensive operation (preprocessing files with CPP,
parsing headers, reading interfaces) to be performed concurrently
according to the -j<N>/-jsem flags.
See Note [Rules-based downsweep] in GHC.Driver.Downsweep.
To achieve this, the finder cache was slightly restructured in order to
account for modules whose source files are directly specified as targets;
see the new Note [Known home modules] in GHC.Unit.Finder.Types. This
allowed us to remove 'addModuleToFinder', 'addHomeModuleToFinder' and
a few brittle hacks (e.g. in Backpack).
Fixes #27514
- - - - -
6f6fe2d0 by sheaf at 2026-08-26T16:19:40+02:00
Separate Home/External finder caches
- - - - -
49 changed files:
- + changelog.d/parallel-downsweep
- compiler/GHC.hs
- compiler/GHC/Builtin.hs
- + compiler/GHC/Data/Dependent.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/Concurrency.hs
- + compiler/GHC/Driver/Config/Concurrency.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeAction.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/LogQueue.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/UnresolvedImport.hs
- compiler/GHC/Unit/Finder.hs
- + compiler/GHC/Unit/Finder/Cache.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- + compiler/GHC/Utils/Concurrent/Scope.hs
- compiler/GHC/Utils/TmpFs.hs
- compiler/ghc.cabal.in
- ghc/GHCi/UI.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/T27461/Makefile
- + testsuite/tests/driver/T27461/T27461c.stderr
- testsuite/tests/driver/T27461/all.T
- + testsuite/tests/driver/T27461/src/Wrong.hs
- testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs
- testsuite/tests/ghc-api/downsweep/OldModLocation.hs
- testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs
- testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- testsuite/tests/splice-imports/SI35.hs
- utils/check-ppr/Main.hs
- utils/haddock/haddock-api/src/Haddock/Interface.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68246948ad2370cd9da4d73635c648…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68246948ad2370cd9da4d73635c648…
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
26 Aug '26
Andreas Klebinger pushed new branch wip/apk/fam-app-test at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/apk/fam-app-test
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/homeunit-is-just] `HomeUnitEnv` should always have a concrete `HomeUnit`
by Hannes Siebenhandl (@fendor) 26 Aug '26
by Hannes Siebenhandl (@fendor) 26 Aug '26
26 Aug '26
Hannes Siebenhandl pushed to branch wip/fendor/homeunit-is-just at Glasgow Haskell Compiler / GHC
Commits:
400ee8a1 by fendor at 2026-08-26T15:49:16+02:00
`HomeUnitEnv` should always have a concrete `HomeUnit`
The `HomeUnit` describes what kind of home unit a particular
`HomeUnitEnv` is and its `UnitId`.
To get a `HomeUnit`, we need to initialise the `UnitState` via `initUnits` otherwise,
we can't tell whether the `HomeUnit` is a definite one, or an indefinite
one, for example a backpack signature file.
That's why previously we maintained a `Maybe HomeUnit`.
However, a `HomeUnitEnv` always has at least a `UnitId` (accessible via
`DynFlags`).
We can fake a `HomeUnit` until we have actually initialised the
home unit and assume it is not a backpack unit.
This avoids many partial functions that should have never been partial
in the first case.
- - - - -
21 changed files:
- compiler/GHC.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Main/Hsc.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Errors.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/StgToJS/Linker/Linker.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Unit/Env.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Home.hs
- compiler/GHC/Unit/Home/Graph.hs
- ghc/GHCi/UI.hs
Changes:
=====================================
compiler/GHC.hs
=====================================
@@ -678,7 +678,7 @@ setUnitDynFlagsNoCheck uid dflags1 = do
hue
{ homeUnitEnv_units = unit_state
, homeUnitEnv_dflags = updated_dflags
- , homeUnitEnv_home_unit = Just home_unit
+ , homeUnitEnv_home_unit = home_unit
}
let unit_env = UnitEnv.ue_updateHomeUnitEnv upd uid (hsc_unit_env hsc_env)
@@ -767,7 +767,7 @@ setProgramDynFlags_ invalidate_needed dflags = do
{ homeUnitEnv_units = unit_state
, homeUnitEnv_dflags = updated_dflags
, homeUnitEnv_hpt = old_hpt
- , homeUnitEnv_home_unit = Just home_unit
+ , homeUnitEnv_home_unit = home_unit
}
let dflags1 = homeUnitEnv_dflags $ HUG.unitEnv_lookup (ue_currentUnit old_unit_env) home_unit_graph
@@ -891,7 +891,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do
{ homeUnitEnv_units = unit_state
, homeUnitEnv_dflags = updated_dflags
, homeUnitEnv_hpt = old_hpt
- , homeUnitEnv_home_unit = Just home_unit
+ , homeUnitEnv_home_unit = home_unit
}
-- When changing the DynFlags, we want the changes to apply to future
@@ -1684,7 +1684,7 @@ findQualifiedModule :: GhcMonad m => PkgQual -> ModuleName -> m Module
findQualifiedModule pkgqual mod_name = withSession $ \hsc_env -> do
let logger = hsc_logger hsc_env
liftIO $ trace_if logger (text "findQualifiedModule" <+> ppr mod_name <+> ppr pkgqual)
- let mhome_unit = hsc_home_unit_maybe hsc_env
+ let home_unit = hsc_home_unit hsc_env
let dflags = hsc_dflags hsc_env
let sec = initSourceErrorContext dflags
case pkgqual of
@@ -1695,7 +1695,7 @@ findQualifiedModule pkgqual mod_name = withSession $ \hsc_env -> do
Nothing -> liftIO $ do
res <- findImportedModule hsc_env LookupUser mod_name pkgqual
case res of
- Found loc m | notHomeModuleMaybe mhome_unit m -> return m
+ Found loc m | notHomeModule home_unit m -> return m
| otherwise -> modNotLoadedError dflags m loc
err -> throwOneError sec $ noModError hsc_env noSrcSpan mod_name err
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -470,7 +470,7 @@ addUnit u = do
, ue_home_unit_graph =
HUG.unitEnv_singleton
(homeUnitId home_unit)
- (HUG.mkHomeUnitEnv unit_state dflags (ue_hpt old_unit_env) (Just home_unit))
+ (HUG.mkHomeUnitEnv unit_state dflags (ue_hpt old_unit_env) home_unit)
, ue_eps = ue_eps old_unit_env
, ue_module_graph = ue_module_graph old_unit_env
, ue_uic = ue_uic old_unit_env
=====================================
compiler/GHC/Driver/Env.hs
=====================================
@@ -7,7 +7,6 @@ module GHC.Driver.Env
, hscUpdateFlags
, hscSetFlags
, hsc_home_unit
- , hsc_home_unit_maybe
, hsc_units
, hsc_HPT
, hsc_HUE
@@ -122,10 +121,7 @@ runInteractiveHsc :: HscEnv -> Hsc a -> IO a
runInteractiveHsc hsc_env = runHsc (mkInteractiveHscEnv hsc_env)
hsc_home_unit :: HscEnv -> HomeUnit
-hsc_home_unit = ue_unsafeHomeUnit . hsc_unit_env
-
-hsc_home_unit_maybe :: HscEnv -> Maybe HomeUnit
-hsc_home_unit_maybe = ue_homeUnit . hsc_unit_env
+hsc_home_unit = ue_homeUnit . hsc_unit_env
hsc_units :: HasDebugCallStack => HscEnv -> UnitState
hsc_units = ue_homeUnitState . hsc_unit_env
@@ -390,7 +386,7 @@ lookupIfaceByModuleHsc hsc_env mod = do
lookupIfaceByModule (hsc_HUG hsc_env) (eps_PIT eps) mod
mainModIs :: HomeUnitEnv -> Module
-mainModIs hue = mkHomeModule (expectJust $ homeUnitEnv_home_unit hue) (mainModuleNameIs (homeUnitEnv_dflags hue))
+mainModIs hue = mkHomeModule (homeUnitEnv_home_unit hue) (mainModuleNameIs (homeUnitEnv_dflags hue))
-- | Retrieve the target code interpreter
--
=====================================
compiler/GHC/Driver/Main/Hsc.hs
=====================================
@@ -112,7 +112,7 @@ newHscEnv top_dir dflags = do
where
home_unit_graph hpt = HUG.unitEnv_singleton
(homeUnitId_ dflags)
- (HUG.mkHomeUnitEnv emptyUnitState dflags hpt Nothing)
+ (HUG.mkHomeUnitEnv emptyUnitState dflags hpt (DefiniteHomeUnit (homeUnitId_ dflags) Nothing))
newHscEnvWithHUG :: FilePath -> DynFlags -> UnitId -> HomeUnitGraph -> IO HscEnv
newHscEnvWithHUG top_dir top_dynflags cur_unit home_unit_graph = do
=====================================
compiler/GHC/Driver/Make.hs
=====================================
@@ -1672,7 +1672,7 @@ maybeRehydrateBefore hsc_env mni (Just mns) = do
where
initialise_knot_var hsc_env = liftIO $
- let mod_name = homeModuleInstantiation (hsc_home_unit_maybe hsc_env) (moduleNodeInfoModule mni)
+ let mod_name = homeModuleInstantiation (hsc_home_unit hsc_env) (moduleNodeInfoModule mni)
in mkModuleEnv . (:[]) . (mod_name,) <$> newIORef emptyTypeEnv
rehydrateAfter :: HscEnv
=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -373,7 +373,7 @@ runCcPhase cc_phase pipe_env hsc_env location input_fn = do
let dflags = hsc_dflags hsc_env
let logger = hsc_logger hsc_env
let unit_env = hsc_unit_env hsc_env
- let home_unit = hsc_home_unit_maybe hsc_env
+ let home_unit = hsc_home_unit hsc_env
let tmpfs = hsc_tmpfs hsc_env
let tmpdir = tmpDir dflags
let platform = ue_platform unit_env
@@ -473,12 +473,11 @@ runCcPhase cc_phase pipe_env hsc_env location input_fn = do
-- These symbols are imported into the stub.c file via RtsAPI.h, and the
-- way we do the import depends on whether we're currently compiling
-- the base package or not.
- ++ (case home_unit of
- Just hu
- | isHomeUnitId hu ghcInternalUnitId
- , platformOS platform == OSMinGW32
- -> ["-DCOMPILING_GHC_INTERNAL_PACKAGE"]
- _ -> [])
+ ++ (if
+ | isHomeUnitId home_unit ghcInternalUnitId
+ , platformOS platform == OSMinGW32
+ -> ["-DCOMPILING_GHC_INTERNAL_PACKAGE"]
+ | otherwise -> [])
-- GCC 4.6+ doesn't like -Wimplicit when compiling C++.
++ (if (cc_phase /= Ccxx && cc_phase /= Cobjcxx)
=====================================
compiler/GHC/Driver/Session/Units.hs
=====================================
@@ -17,9 +17,9 @@ import GHC.Driver.Config.Diagnostic
import GHC.Unit.Env
import GHC.Unit (UnitId)
+import GHC.Unit.Home (homeUnitId)
import GHC.Unit.Home.PackageTable
import qualified GHC.Unit.Home.Graph as HUG
-import GHC.Unit.State ( emptyUnitState )
import qualified GHC.Unit.State as State
import GHC.Types.SrcLoc
@@ -125,23 +125,24 @@ initMulti unitArgsFiles lintDynFlagsAndSrcs = do
checkDuplicateUnits initial_dflags (NE.toList (NE.zip unitArgsFiles unitDflags))
- (initial_home_graph, mainUnitId) <- liftIO $ createUnitEnvFromFlags unitDflags
- let home_units = HUG.allUnits initial_home_graph
+ let home_units = Set.fromList $ map homeUnitId_ $ NE.toList unitDflags
- home_unit_graph <- forM initial_home_graph $ \homeUnitEnv -> do
- let hue_flags = homeUnitEnv_dflags homeUnitEnv
- dflags = homeUnitEnv_dflags homeUnitEnv
- (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hscUIC hsc_env) home_units
+ home_unit_envs <- forM unitDflags $ \dflags -> do
+ emptyHpt <- liftIO $ emptyHomePackageTable
+ (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger dflags (hscUIC hsc_env) home_units
updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
- emptyHpt <- liftIO $ emptyHomePackageTable
pure $ HomeUnitEnv
{ homeUnitEnv_units = unit_state
, homeUnitEnv_dflags = updated_dflags
, homeUnitEnv_hpt = emptyHpt
- , homeUnitEnv_home_unit = Just home_unit
+ , homeUnitEnv_home_unit = home_unit
}
+
+ let mainUnitId = homeUnitId $ homeUnitEnv_home_unit $ NE.head home_unit_envs
+ let home_unit_graph = HUG.hugFromHomeUnitEnvs $ NE.toList home_unit_envs
+
checkUnitCycles initial_dflags home_unit_graph
let dflags = homeUnitEnv_dflags $ HUG.unitEnv_lookup mainUnitId home_unit_graph
@@ -230,16 +231,3 @@ offsetDynFlags dflags =
augment_maybe (Just f) = Just (augment f)
augment f | isRelative f, Just offset <- workingDirectory dflags = offset </> f
| otherwise = f
-
-
-createUnitEnvFromFlags :: NE.NonEmpty DynFlags -> IO (HomeUnitGraph, UnitId)
-createUnitEnvFromFlags unitDflags = do
- unitEnvList <- forM unitDflags $ \dflags -> do
- emptyHpt <- emptyHomePackageTable
- let newInternalUnitEnv =
- HUG.mkHomeUnitEnv emptyUnitState dflags emptyHpt Nothing
- return (homeUnitId_ dflags, newInternalUnitEnv)
- let activeUnit = fst $ NE.head unitEnvList
- return (HUG.hugFromList (NE.toList unitEnvList), activeUnit)
-
-
=====================================
compiler/GHC/HsToCore/Usage.hs
=====================================
@@ -82,7 +82,7 @@ mkUsageInfo uc plugins fc unit_env
= do
file_hashes <- liftIO $ mapM getFileHash dependent_files
dirs_hashes <- liftIO $ mapM getDirHash dependent_dirs
- let hu = ue_unsafeHomeUnit unit_env
+ let hu = ue_homeUnit unit_env
-- Dependencies on object files due to TH and plugins
object_usages <- liftIO $ mkObjectUsage plugins fc needed_links needed_pkgs
let all_home_ids = HUG.allUnits (ue_home_unit_graph unit_env)
=====================================
compiler/GHC/Iface/Errors.hs
=====================================
@@ -27,20 +27,20 @@ badIfaceFile file err
= vcat [text "Bad interface file:" <+> text file,
nest 4 err]
-cannotFindInterface :: UnitState -> Maybe HomeUnit -> Profile
+cannotFindInterface :: UnitState -> HomeUnit -> Profile
-> ModuleName -> InstalledFindResult -> MissingInterfaceError
-cannotFindInterface us mhu p mn ifr =
+cannotFindInterface us hu p mn ifr =
CantFindErr us FindingInterface $
- cantFindInstalledErr us mhu p mn ifr
+ cantFindInstalledErr us hu p mn ifr
cantFindInstalledErr
:: UnitState
- -> Maybe HomeUnit
+ -> HomeUnit
-> Profile
-> ModuleName
-> InstalledFindResult
-> CantFindInstalled
-cantFindInstalledErr unit_state mhome_unit profile mod_name find_result
+cantFindInstalledErr unit_state home_unit profile mod_name find_result
= CantFindInstalled mod_name more_info
where
build_tag = waysBuildTag (profileWays profile)
@@ -52,7 +52,7 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result
InstalledNotFound files mb_pkg
| Just pkg <- mb_pkg
- , notHomeUnitId mhome_unit pkg
+ , not (isHomeUnitId home_unit pkg)
-> not_found_in_package pkg $ fmap unsafeDecodeUtf files
| null files
@@ -102,7 +102,7 @@ cantFindErr _ _ mod_name (FoundMultiple mods)
cantFindErr unit_env profile mod_name find_result
= CantFindInstalled mod_name more_info
where
- mhome_unit = ue_homeUnit unit_env
+ home_unit = ue_homeUnit unit_env
more_info
= case find_result of
NoPackage pkg
@@ -111,12 +111,7 @@ cantFindErr unit_env profile mod_name find_result
, fr_mods_hidden = mod_hiddens, fr_pkgs_hidden = pkg_hiddens
, fr_unusables = unusables, fr_suggestions = suggest }
| Just pkg <- mb_pkg
- , Nothing <- mhome_unit -- no home-unit
- -> not_found_in_package (toUnitId pkg) files
-
- | Just pkg <- mb_pkg
- , Just home_unit <- mhome_unit -- there is a home-unit but the
- , not (isHomeUnit home_unit pkg) -- module isn't from it
+ , not (isHomeUnit home_unit pkg) -- module isn't from this home unit
-> not_found_in_package (toUnitId pkg) files
| not (null suggest)
=====================================
compiler/GHC/Iface/Load.hs
=====================================
@@ -774,14 +774,14 @@ loadInterface doc_str mod from
-- Check whether we have the interface already
; hsc_env <- getTopEnv
- ; let mhome_unit = ue_homeUnit (hsc_unit_env hsc_env)
+ ; let home_unit = ue_homeUnit (hsc_unit_env hsc_env)
; liftIO (lookupIfaceByModule hug (eps_PIT eps) mod) >>= \case {
Just iface
-> return (Succeeded iface) ; -- Already loaded
_ -> do {
-- READ THE MODULE IN
- ; read_result <- case wantHiBootFile mhome_unit eps mod from of
+ ; read_result <- case wantHiBootFile home_unit eps mod from of
Failed err -> return (Failed err)
Succeeded hi_boot_file -> do
hsc_env <- getTopEnv
@@ -877,7 +877,7 @@ loadInterface doc_str mod from
; warnPprTrace bad_boot "loadInterface" (ppr mod) $
updateEps_ $ \ eps ->
- if elemModuleEnv mod (eps_PIT eps) || is_external_sig mhome_unit iface
+ if elemModuleEnv mod (eps_PIT eps) || is_external_sig home_unit iface
then eps
else if bad_boot
-- See Note [Loading your own hi-boot file]
@@ -1042,12 +1042,12 @@ dontLeakTheHUG thing_inside = do
-- | Returns @True@ if a 'ModIface' comes from an external package.
-- In this case, we should NOT load it into the EPS; the entities
-- should instead come from the local merged signature interface.
-is_external_sig :: Maybe HomeUnit -> ModIface -> Bool
-is_external_sig mhome_unit iface =
+is_external_sig :: HomeUnit -> ModIface -> Bool
+is_external_sig home_unit iface =
-- It's a signature iface...
mi_semantic_module iface /= mi_module iface &&
-- and it's not from the local package
- notHomeModuleMaybe mhome_unit (mi_module iface)
+ notHomeModule home_unit (mi_module iface)
-- | This is an improved version of 'findAndReadIface' which can also
-- handle the case when a user requests @p[A=<B>]:M@ but we only
@@ -1071,13 +1071,12 @@ computeInterface
-> IO (MaybeErr MissingInterfaceError (ModIface, ModLocation))
computeInterface hsc_env doc_str hi_boot_file mod0 = do
massert (not (isHoleModule mod0))
- let mhome_unit = hsc_home_unit_maybe hsc_env
+ let home_unit = hsc_home_unit hsc_env
let find_iface m = findAndReadIface hsc_env doc_str
m mod0 hi_boot_file
case getModuleInstantiation mod0 of
(imod, Just indef)
- | Just home_unit <- mhome_unit
- , isHomeUnitIndefinite home_unit ->
+ | isHomeUnitIndefinite home_unit ->
find_iface imod >>= \case
Succeeded (iface0, path) ->
rnModIface hsc_env (instUnitInsts (moduleUnit indef)) Nothing iface0 >>= \case
@@ -1134,13 +1133,13 @@ moduleFreeHolesPrecise doc_str mod
return (Succeeded (renameFreeHoles ifhs insts))
Failed err -> return (Failed err)
-wantHiBootFile :: Maybe HomeUnit -> ExternalPackageState -> Module -> WhereFrom
+wantHiBootFile :: HomeUnit -> ExternalPackageState -> Module -> WhereFrom
-> MaybeErr MissingInterfaceError IsBootInterface
-- Figure out whether we want Foo.hi or Foo.hi-boot
-wantHiBootFile mhome_unit eps mod from
+wantHiBootFile home_unit eps mod from
= case from of
ImportByUser usr_boot
- | usr_boot == IsBoot && notHomeModuleMaybe mhome_unit mod
+ | usr_boot == IsBoot && notHomeModule home_unit mod
-> Failed (BadSourceImport mod)
| otherwise -> Succeeded usr_boot
@@ -1148,7 +1147,7 @@ wantHiBootFile mhome_unit eps mod from
-> Succeeded NotBoot
ImportBySystem
- | notHomeModuleMaybe mhome_unit mod
+ | notHomeModule home_unit mod
-> Succeeded NotBoot
-- If the module to be imported is not from this package
-- don't look it up in eps_is_boot, because that is keyed
@@ -1222,7 +1221,7 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do
let profile = targetProfile dflags
unit_state = hsc_units hsc_env
name_cache = hsc_NC hsc_env
- mhome_unit = hsc_home_unit_maybe hsc_env
+ home_unit = hsc_home_unit hsc_env
dflags = hsc_dflags hsc_env
logger = hsc_logger hsc_env
hooks = hsc_hooks hsc_env
@@ -1261,7 +1260,7 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do
trace_if logger (text "...not found")
return $ Failed $ cannotFindInterface
unit_state
- mhome_unit
+ home_unit
profile
(moduleName mod)
err
=====================================
compiler/GHC/Linker/Deps.hs
=====================================
@@ -160,22 +160,18 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
= HUG.lookupHugByModule mod (ue_home_unit_graph unit_env) >>= \case
Just mod_info -> adjust_linkable (expectJust (homeModLinkable mod_info))
Nothing -> do
- -- It's not in the HPT because we are in one shot mode,
- -- so use the Finder to get a ModLocation...
- case ue_homeUnit unit_env of
- Nothing -> no_obj mod
- Just home_unit -> do
-
- let fc = ldFinderCache opts
- let fopts = ldFinderOpts opts
- mb_stuff <- findHomeModule fc fopts home_unit (moduleName mod)
- case mb_stuff of
- Found loc _ -> do
- from_bc <- ldLoadByteCode opts mod loc
- maybe (fallback_no_bytecode home_unit mod) pure from_bc
- _ -> fallback_no_bytecode home_unit mod
+ -- It's not in the HPT because we are in one shot mode,
+ -- so use the Finder to get a ModLocation...
+ let fc = ldFinderCache opts
+ let fopts = ldFinderOpts opts
+ mb_stuff <- findHomeModule fc fopts hu (moduleName mod)
+ case mb_stuff of
+ Found loc _ -> do
+ from_bc <- ldLoadByteCode opts mod loc
+ maybe (fallback_no_bytecode hu mod) pure from_bc
+ _ -> fallback_no_bytecode hu mod
where
-
+ hu = ue_homeUnit unit_env
fallback_no_bytecode home_unit mod = do
let fc = ldFinderCache opts
let fopts = ldFinderOpts opts
=====================================
compiler/GHC/Rename/Names.hs
=====================================
@@ -487,7 +487,7 @@ renamePkgQual :: UnitEnv -> ModuleName -> Maybe FastString -> PkgQual
renamePkgQual unit_env mn mb_pkg = case mb_pkg of
Nothing -> NoPkgQual
Just pkg_fs
- | Just uid <- homeUnitId <$> ue_homeUnit unit_env
+ | uid <- homeUnitId (ue_homeUnit unit_env)
, pkg_fs == fsLit "this"
-> ThisPkg uid
=====================================
compiler/GHC/StgToJS/Linker/Linker.hs
=====================================
@@ -485,17 +485,15 @@ computeLinkDependencies cfg unit_env link_spec finder_opts finder_cache ar_cache
let load_info mod = do
-- Adapted from the tangled code in GHC.Linker.Loader.getLinkDeps.
linkable <- HUG.lookupHugByModule mod (ue_home_unit_graph unit_env) >>= \case
- Nothing ->
+ Nothing -> do
-- It's not in the HPT because we are in one shot mode,
-- so use the Finder to get a ModLocation...
- case ue_homeUnit unit_env of
- Nothing -> pprPanic "getDeps: No home-unit: " (pprModule mod)
- Just home_unit -> do
- mb_stuff <- findHomeModule finder_cache finder_opts home_unit (moduleName mod)
- case mb_stuff of
- Found loc mod -> found loc mod
- _ -> pprPanic "getDeps: Couldn't find home-module: " (pprModule mod)
+ mb_stuff <- findHomeModule finder_cache finder_opts home_unit (moduleName mod)
+ case mb_stuff of
+ Found loc mod -> found loc mod
+ _ -> pprPanic "getDeps: Couldn't find home-module: " (pprModule mod)
where
+ home_unit = ue_homeUnit unit_env
found loc mod = do {
mb_lnk <- findObjectLinkableMaybe mod loc ;
case mb_lnk of {
=====================================
compiler/GHC/Tc/Utils/Backpack.hs
=====================================
@@ -286,11 +286,11 @@ implicitRequirements hsc_env normal_imports
forM normal_imports $ \e -> do
found <- resolveImport hsc_env e
case found of
- Found _ mod | notHomeModuleMaybe mhome_unit mod ->
+ Found _ mod | notHomeModule home_unit mod ->
return (uniqDSetToList (moduleFreeHoles mod))
_ -> return []
where
- mhome_unit = hsc_home_unit_maybe hsc_env
+ home_unit = hsc_home_unit hsc_env
-- | Like @implicitRequirements'@, but returns the instantiated unit the
-- imported module is from, so that that instantiated unit can be processed and
@@ -302,13 +302,13 @@ implicitRequirementsShallow
-> IO [InstantiatedUnit]
implicitRequirementsShallow hsc_env normal_imports = go [] normal_imports
where
- mhome_unit = hsc_home_unit_maybe hsc_env
+ home_unit = hsc_home_unit hsc_env
go acc [] = pure acc
go accR (e:imports) = do
found <- resolveImport hsc_env e
let acc' = case found of
- Found _ mod | notHomeModuleMaybe mhome_unit mod ->
+ Found _ mod | notHomeModule home_unit mod ->
case moduleUnit mod of
HoleUnit -> panic "implicitRequirementsShallow: HoleUnit is unreachable through findImportedModule!"
RealUnit _ -> accR
=====================================
compiler/GHC/Tc/Utils/Env.hs
=====================================
@@ -180,8 +180,8 @@ lookupGlobal_maybe :: HscEnv -> Name -> IO (MaybeErr (Either Name IfaceMessage)
lookupGlobal_maybe hsc_env name
= do { -- Try local envt
let mod = icInteractiveModule (hsc_IC hsc_env)
- mhome_unit = hsc_home_unit_maybe hsc_env
- tcg_semantic_mod = homeModuleInstantiation mhome_unit mod
+ home_unit = hsc_home_unit hsc_env
+ tcg_semantic_mod = homeModuleInstantiation home_unit mod
; if nameIsLocalOrFrom tcg_semantic_mod name
then return $ Failed $ Left name
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -371,7 +371,7 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc =
; let
-- bangs to avoid leaking the env (#19356)
!dflags = hsc_dflags hsc_env
- !mhome_unit = hsc_home_unit_maybe hsc_env
+ !home_unit = hsc_home_unit hsc_env
!logger = hsc_logger hsc_env
maybe_rn_syntax :: forall a. a -> Maybe a ;
@@ -399,7 +399,7 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc =
, tcg_th_docs = th_docs_var
, tcg_mod = mod
- , tcg_semantic_mod = homeModuleInstantiation mhome_unit mod
+ , tcg_semantic_mod = homeModuleInstantiation home_unit mod
, tcg_src = hsc_src
, tcg_rdr_env = emptyGlobalRdrEnv
, tcg_fix_env = emptyNameEnv
@@ -2574,11 +2574,11 @@ initIfaceTcRn thing_inside
= do { tcg_env <- getGblEnv
; hsc_env <- getTopEnv
-- bangs to avoid leaking the envs (#19356)
- ; let !mhome_unit = hsc_home_unit_maybe hsc_env
+ ; let !home_unit = hsc_home_unit hsc_env
!knot_vars = tcg_knot_vars tcg_env
-- When we are instantiating a signature,
-- we DEFINITELY do not want to knot tie.
- is_instantiate = fromMaybe False (isHomeUnitInstantiating <$> mhome_unit)
+ is_instantiate = isHomeUnitInstantiating home_unit
if_env = IfGblEnv { if_doc = text "initIfaceTcRn"
, if_rec_types = if is_instantiate
=====================================
compiler/GHC/Unit/Env.hs
=====================================
@@ -53,7 +53,6 @@ module GHC.Unit.Env
, ue_unitHomeUnit_maybe
, ue_updateHomeUnitEnv
, ue_all_home_unit_ids
- , ue_unsafeHomeUnit
-- * HUG Re-export
, HomeUnitGraph
@@ -235,14 +234,13 @@ preloadUnitsInfo' unit_env ids0 = all_infos
where
unit_state = HUG.homeUnitEnv_units (ue_currentHomeUnitEnv unit_env)
ids = ids0 ++ inst_ids
- inst_ids = case ue_homeUnit unit_env of
- Nothing -> []
- Just home_unit
- -- An indefinite package will have insts to HOLE,
- -- which is not a real package. Don't look it up.
- -- Fixes #14525
- | isHomeUnitIndefinite home_unit -> []
- | otherwise -> map (toUnitId . moduleUnit . snd) (homeUnitInstantiations home_unit)
+ home_unit = ue_homeUnit unit_env
+ inst_ids
+ -- An indefinite package will have insts to HOLE,
+ -- which is not a real package. Don't look it up.
+ -- Fixes #14525
+ | isHomeUnitIndefinite home_unit = []
+ | otherwise = map (toUnitId . moduleUnit . snd) (homeUnitInstantiations home_unit)
pkg_map = unitInfoMap unit_state
preload = preloadUnits unit_state
@@ -320,20 +318,15 @@ ue_setFlags dflags env =
-- Query and modify home units in HomeUnitEnv
-- -------------------------------------------------------
-ue_homeUnit :: UnitEnv -> Maybe HomeUnit
+ue_homeUnit :: UnitEnv -> HomeUnit
ue_homeUnit = HUG.homeUnitEnv_home_unit . ue_currentHomeUnitEnv
-ue_unsafeHomeUnit :: UnitEnv -> HomeUnit
-ue_unsafeHomeUnit ue = case ue_homeUnit ue of
- Nothing -> panic "ue_unsafeHomeUnit: No home unit"
- Just h -> h
-
ue_unitHomeUnit :: UnitId -> UnitEnv -> HomeUnit
ue_unitHomeUnit uid = expectJust . ue_unitHomeUnit_maybe uid
ue_unitHomeUnit_maybe :: UnitId -> UnitEnv -> Maybe HomeUnit
ue_unitHomeUnit_maybe uid ue_env =
- HUG.homeUnitEnv_home_unit =<< HUG.lookupHugUnitId uid (ue_home_unit_graph ue_env)
+ HUG.homeUnitEnv_home_unit <$> HUG.lookupHugUnitId uid (ue_home_unit_graph ue_env)
-- -------------------------------------------------------
-- Query and modify the currently active unit
=====================================
compiler/GHC/Unit/Finder.hs
=====================================
@@ -5,6 +5,7 @@
{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE MultiWayIf #-}
-- | Module finder
module GHC.Unit.Finder (
@@ -210,7 +211,7 @@ findImportedModule
-> IO FindResult
findImportedModule hsc_env scope mod pkg_qual =
let fc = hsc_FC hsc_env
- mb_home_unit = hsc_home_unit_maybe hsc_env
+ home_unit = hsc_home_unit hsc_env
dflags = hsc_dflags hsc_env
fopts = initFinderOpts dflags
providers = mgHomeModuleNameProvidersMap (hsc_mod_graph hsc_env)
@@ -220,7 +221,7 @@ findImportedModule hsc_env scope mod pkg_qual =
fopts
(hsc_unit_env hsc_env)
providers
- mb_home_unit
+ home_unit
scope
mod
pkg_qual
@@ -230,33 +231,30 @@ findImportedModuleNoHsc
-> FinderOpts
-> UnitEnv
-> HomeModuleNameProvidersMap
- -> Maybe HomeUnit
+ -> HomeUnit
-> ModuleLookupScope
-> ModuleName
-> PkgQual
-> IO FindResult
-findImportedModuleNoHsc fc fopts ue home_module_name_providers_map mb_home_unit scope mod_name mb_pkg =
+findImportedModuleNoHsc fc fopts ue home_module_name_providers_map home_unit scope mod_name mb_pkg =
case mb_pkg of
NoPkgQual -> unqual_import
- ThisPkg uid | (homeUnitId <$> mb_home_unit) == Just uid -> home_import
+ ThisPkg uid | homeUnitId home_unit == uid -> home_import
| Just os <- lookup uid other_fopts -> home_pkg_import (uid, os)
- | otherwise -> pprPanic "findImportModule" (ppr mod_name $$ ppr mb_pkg $$ ppr (homeUnitId <$> mb_home_unit) $$ ppr uid $$ ppr (map fst all_opts))
+ | otherwise -> pprPanic "findImportModule" (ppr mod_name $$ ppr mb_pkg $$ ppr home_unit_id $$ ppr uid $$ ppr (map fst all_opts))
OtherPkg _ -> pkg_import
where
- mb_home_unit_id :: Maybe UnitId
- mb_home_unit_id = homeUnitId <$> mb_home_unit
+ home_unit_id :: UnitId
+ home_unit_id = homeUnitId home_unit
all_opts :: [(UnitId, FinderOpts)]
- all_opts = case mb_home_unit_id of
- Nothing -> other_fopts
- Just home_unit_id -> (home_unit_id, fopts) : other_fopts
+ all_opts =
+ (home_unit_id, fopts) : other_fopts
home_import :: IO FindResult
- home_import = case mb_home_unit of
- Just home_unit -> findHomeModule fc fopts home_unit mod_name
- Nothing -> pure $
- NoPackage (panic "findImportedModule: no home-unit")
+ home_import =
+ findHomeModule fc fopts home_unit mod_name
home_pkg_import :: (UnitId, FinderOpts) -> IO FindResult
home_pkg_import = findHomeUnitDepModule fc ue home_module_name_providers_map scope mod_name
@@ -266,13 +264,11 @@ findImportedModuleNoHsc fc fopts ue home_module_name_providers_map mb_home_unit
unqual_import :: IO FindResult
unqual_import = findHomeOrRegularPackageModule fc fopts ue
- home_module_name_providers_map mb_home_unit scope mod_name
+ home_module_name_providers_map home_unit scope mod_name
unit_state :: UnitState
- unit_state = case mb_home_unit_id of
- Nothing -> ue_homeUnitState ue
- Just home_unit_id -> HUG.homeUnitEnv_units $
- ue_findHomeUnitEnv home_unit_id ue
+ unit_state = HUG.homeUnitEnv_units $
+ ue_findHomeUnitEnv home_unit_id ue
other_fopts :: [(UnitId, FinderOpts)]
other_fopts = homeUnitDepsFinderOpts ue home_module_name_providers_map
@@ -287,28 +283,26 @@ findPluginModuleNoHsc
-> FinderOpts
-> UnitEnv
-> HomeModuleNameProvidersMap
- -> Maybe HomeUnit
+ -> HomeUnit
-> ModuleName
-> IO FindResult
-findPluginModuleNoHsc fc fopts ue home_module_name_providers_map mb_home_unit@(Just home_unit) mod_name =
+findPluginModuleNoHsc fc fopts ue home_module_name_providers_map home_unit mod_name =
findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map
- mb_home_unit LookupUser mod_name
+ home_unit LookupUser mod_name
`orIfNotFound`
findExposedPluginPackageModule fc fopts unit_state mod_name
where
unit_state = HUG.homeUnitEnv_units $
ue_findHomeUnitEnv (homeUnitId home_unit) ue
-findPluginModuleNoHsc fc fopts ue _ Nothing mod_name =
- findExposedPluginPackageModule fc fopts (ue_homeUnitState ue) mod_name
findPluginModule :: HscEnv -> ModuleName -> IO FindResult
findPluginModule hsc_env mod_name = do
let fc = hsc_FC hsc_env
- mb_home_unit = hsc_home_unit_maybe hsc_env
+ home_unit = hsc_home_unit hsc_env
home_module_name_providers_map =
mgHomeModuleNameProvidersMap (hsc_mod_graph hsc_env)
findPluginModuleNoHsc fc (initFinderOpts (hsc_dflags hsc_env))
- (hsc_unit_env hsc_env) home_module_name_providers_map mb_home_unit mod_name
+ (hsc_unit_env hsc_env) home_module_name_providers_map home_unit mod_name
-- -----------------------------------------------------------------------------
-- Home Module Finder Helpers
@@ -380,7 +374,7 @@ findHomeUnitDepModule fc ue home_module_name_providers_map scope mod_name (uid,
| Just real_mod_name
<- lookupUniqMap (finder_reexportedModules opts) mod_name
= findHomeOrRegularPackageModule fc opts ue home_module_name_providers_map
- (Just $ DefiniteHomeUnit uid Nothing)
+ (DefiniteHomeUnit uid Nothing)
scope real_mod_name
| elementOfUniqSet mod_name (finder_hiddenModules opts)
, LookupUser <- scope -- A system lookup is allowed to find hidden modules.
@@ -397,27 +391,22 @@ findHomeModuleAmongDeps
-> FinderOpts
-> UnitEnv
-> HomeModuleNameProvidersMap
- -> Maybe HomeUnit
+ -> HomeUnit
-> ModuleLookupScope
-> ModuleName
-> IO FindResult
-findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map mb_home_unit scope mod_name =
+findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map home_unit scope mod_name =
foldr1 orIfNotFound (home_import :| map home_pkg_import other_fopts)
-- Do not try to be smart and change this to `foldr orIfNotFound home_import
-- (map home_pkg_import other_fopts)`, as that would not be the same.
-- `home_import` is first because we need to first look within the current
-- unit before looking at the other units in order.
where
- home_import = case mb_home_unit of
- Just home_unit -> findHomeModule fc fopts home_unit mod_name
- Nothing -> pure $
- NoPackage (panic "findHomeModuleAmongDeps: no home-unit")
+ home_import = findHomeModule fc fopts home_unit mod_name
+
home_pkg_import = findHomeUnitDepModule fc ue home_module_name_providers_map scope mod_name
- unit_state = case homeUnitId <$> mb_home_unit of
- Nothing -> ue_homeUnitState ue
- Just home_unit_id -> HUG.homeUnitEnv_units $
- ue_findHomeUnitEnv home_unit_id ue
+ unit_state = HUG.homeUnitEnv_units $ ue_findHomeUnitEnv (homeUnitId home_unit) ue
other_fopts = homeUnitDepsFinderOpts ue home_module_name_providers_map
unit_state mod_name
@@ -428,33 +417,31 @@ findHomeOrRegularPackageModule
-> FinderOpts
-> UnitEnv
-> HomeModuleNameProvidersMap
- -> Maybe HomeUnit
+ -> HomeUnit
-> ModuleLookupScope
-> ModuleName
-> IO FindResult
-findHomeOrRegularPackageModule fc fopts ue home_module_name_providers_map mb_home_unit scope mod_name =
+findHomeOrRegularPackageModule fc fopts ue home_module_name_providers_map home_unit scope mod_name =
findHomeModuleAmongDeps fc fopts ue home_module_name_providers_map
- mb_home_unit scope mod_name
+ home_unit scope mod_name
`orIfNotFound`
findExposedPackageModule fc fopts unit_state scope mod_name NoPkgQual
where
- unit_state = case homeUnitId <$> mb_home_unit of
- Nothing -> ue_homeUnitState ue
- Just home_unit_id -> HUG.homeUnitEnv_units $
- ue_findHomeUnitEnv home_unit_id ue
+ unit_state = HUG.homeUnitEnv_units $ ue_findHomeUnitEnv (homeUnitId home_unit) ue
-- | A version of findExactModule which takes the exact parts of the HscEnv it needs
-- directly.
-findExactModuleNoHsc :: FinderCache -> FinderOpts -> UnitEnvGraph FinderOpts -> UnitState -> Maybe HomeUnit -> InstalledModule -> IsBootInterface -> IO InstalledFindResult
-findExactModuleNoHsc fc fopts other_fopts unit_state mb_home_unit mod is_boot = do
- res <- case mb_home_unit of
- Just home_unit
+findExactModuleNoHsc :: FinderCache -> FinderOpts -> UnitEnvGraph FinderOpts -> UnitState -> HomeUnit -> InstalledModule -> IsBootInterface -> IO InstalledFindResult
+findExactModuleNoHsc fc fopts other_fopts unit_state home_unit mod is_boot = do
+ res <-
+ if
| isHomeInstalledModule home_unit mod
-> findInstalledHomeModule fc fopts (homeUnitId home_unit) (moduleName mod)
| Just home_fopts <- HUG.unitEnv_lookup_maybe (moduleUnit mod) other_fopts
-> findInstalledHomeModule fc home_fopts (moduleUnit mod) (moduleName mod)
- _ -> findPackageModule fc unit_state fopts mod
+ | otherwise
+ -> findPackageModule fc unit_state fopts mod
case (res, is_boot) of
(InstalledFound loc, IsBoot) -> return (InstalledFound (addBootSuffixLocn loc))
_ -> return res
@@ -470,7 +457,7 @@ findExactModule hsc_env mod is_boot = do
let dflags = hsc_dflags hsc_env
let fc = hsc_FC hsc_env
let unit_state = hsc_units hsc_env
- let home_unit = hsc_home_unit_maybe hsc_env
+ let home_unit = hsc_home_unit hsc_env
let other_fopts = initFinderOpts . homeUnitEnv_dflags <$> (hsc_HUG hsc_env)
findExactModuleNoHsc fc (initFinderOpts dflags) other_fopts unit_state home_unit mod is_boot
=====================================
compiler/GHC/Unit/Home.hs
=====================================
@@ -18,9 +18,7 @@ module GHC.Unit.Home
, isHomeUnitInstanceOf
, isHomeModule
, isHomeInstalledModule
- , notHomeUnitId
, notHomeModule
- , notHomeModuleMaybe
, notHomeInstalledModule
, notHomeInstalledModuleMaybe
-- * Helpers
@@ -144,11 +142,6 @@ isHomeUnit hu u = u == homeUnitAsUnit hu
isHomeUnitId :: GenHomeUnit u -> UnitId -> Bool
isHomeUnitId hu uid = uid == homeUnitId hu
--- | Test if the unit-id is not the home unit-id
-notHomeUnitId :: Maybe (GenHomeUnit u) -> UnitId -> Bool
-notHomeUnitId Nothing _ = True
-notHomeUnitId (Just hu) uid = not (isHomeUnitId hu uid)
-
-- | Test if the home unit is an instance of the given unit-id
isHomeUnitInstanceOf :: HomeUnit -> UnitId -> Bool
isHomeUnitInstanceOf hu u = homeUnitInstanceOf hu == u
@@ -175,10 +168,6 @@ notHomeInstalledModuleMaybe mh m = fromMaybe True $ fmap (`notHomeInstalledModul
notHomeModule :: HomeUnit -> Module -> Bool
notHomeModule hu m = not (isHomeModule hu m)
--- | Test if a module doesn't come from the given home unit
-notHomeModuleMaybe :: Maybe HomeUnit -> Module -> Bool
-notHomeModuleMaybe mh m = fromMaybe True $ fmap (`notHomeModule` m) mh
-
----------------------------
-- helpers
----------------------------
@@ -211,9 +200,8 @@ homeModuleNameInstantiation hu mod_name =
-- the instantiating module of @r:A@ in @p[A=q[]:B]@ is @r:A@.
-- the instantiating module of @p:A@ in @p@ is @p:A@.
-- the instantiating module of @r:A@ in @p@ is @r:A@.
-homeModuleInstantiation :: Maybe HomeUnit -> Module -> Module
-homeModuleInstantiation mhu mod
- | Just hu <- mhu
- , isHomeModule hu mod = homeModuleNameInstantiation hu (moduleName mod)
+homeModuleInstantiation :: HomeUnit -> Module -> Module
+homeModuleInstantiation hu mod
+ | isHomeModule hu mod = homeModuleNameInstantiation hu (moduleName mod)
| otherwise = mod
=====================================
compiler/GHC/Unit/Home/Graph.hs
=====================================
@@ -50,6 +50,7 @@ module GHC.Unit.Home.Graph
-- * Utilities
, hugSCCs
, hugFromList
+ , hugFromHomeUnitEnvs
-- ** Printing
, pprHomeUnitGraph
@@ -150,11 +151,11 @@ data HomeUnitEnv = HomeUnitEnv
--
-- (This changes a previous invariant: changed Jan 05.)
- , homeUnitEnv_home_unit :: !(Maybe HomeUnit)
+ , homeUnitEnv_home_unit :: !HomeUnit
-- ^ Home-unit
}
-mkHomeUnitEnv :: UnitState -> DynFlags -> HomePackageTable -> Maybe HomeUnit -> HomeUnitEnv
+mkHomeUnitEnv :: UnitState -> DynFlags -> HomePackageTable -> HomeUnit -> HomeUnitEnv
mkHomeUnitEnv us dflags hpt home_unit = HomeUnitEnv
{ homeUnitEnv_units = us
, homeUnitEnv_dflags = dflags
@@ -363,6 +364,9 @@ hugSCCs hug = sccs where
hugFromList :: [(UnitId, HomeUnitEnv)] -> HomeUnitGraph
hugFromList = UnitEnvGraph . Map.fromList
+hugFromHomeUnitEnvs :: [HomeUnitEnv] -> HomeUnitGraph
+hugFromHomeUnitEnvs = hugFromList . fmap (\hue -> (homeUnitId $ homeUnitEnv_home_unit hue, hue))
+
pprHomeUnitGraph :: HomeUnitGraph -> IO SDoc
pprHomeUnitGraph unitEnv = do
docs <- mapM (\(k, v) -> pprHomeUnitEnv k v) $ Map.assocs $ unitEnv_graph unitEnv
@@ -372,6 +376,6 @@ pprHomeUnitEnv :: UnitId -> HomeUnitEnv -> IO SDoc
pprHomeUnitEnv uid env = do
hptDoc <- pprHPT $ homeUnitEnv_hpt env
return $
- ppr uid <+> text "(flags:" <+> ppr (homeUnitId_ $ homeUnitEnv_dflags env) <> text "," <+> ppr (fmap homeUnitId $ homeUnitEnv_home_unit env) <> text ")" <+> text "->"
+ ppr uid <+> text "(flags:" <+> ppr (homeUnitId_ $ homeUnitEnv_dflags env) <> text "," <+> ppr (homeUnitId $ homeUnitEnv_home_unit env) <> text ")" <+> text "->"
$$ nest 4 hptDoc
=====================================
ghc/GHCi/UI.hs
=====================================
@@ -861,7 +861,7 @@ installInteractiveHomeUnits dflags = do
(unit_state,home_unit,_mconstants) <-
liftIO $ initUnits logger dflags unit_index all_home_units
hpt <- liftIO emptyHomePackageTable
- pure (HUG.mkHomeUnitEnv unit_state dflags hpt (Just home_unit))
+ pure (HUG.mkHomeUnitEnv unit_state dflags hpt home_unit)
concatPackageDbStacksUsingLongestCommonPrefix :: [[PackageDBFlag]] -> [PackageDBFlag]
concatPackageDbStacksUsingLongestCommonPrefix stacks =
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/400ee8a1c8ea569ee2442328206b871…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/400ee8a1c8ea569ee2442328206b871…
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/jeltsch/stm-exception-improvements] 30 commits: testsuite: Expect length001 failure in nonmoving_thr_sanity
by Wolfgang Jeltsch (@jeltsch) 26 Aug '26
by Wolfgang Jeltsch (@jeltsch) 26 Aug '26
26 Aug '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/stm-exception-improvements at Glasgow Haskell Compiler / GHC
Commits:
db959f83 by Simon Jakobi at 2026-08-14T15:16:44-04:00
testsuite: Expect length001 failure in nonmoving_thr_sanity
length001 relies on an optimization rule to avoid excessive stack use.
The nonmoving_thr_sanity way does not enable optimization, so classify
its stack overflow as an expected failure, as is already done for the
other unoptimized nonmoving ways.
Assisted-by: gpt-5.6-sol via Codex CLI
- - - - -
4f2b7d90 by Simon Jakobi at 2026-08-14T15:16:44-04:00
testsuite: Omit T22859 in nonmoving threaded ways
T22859 checks allocation-limit handlers with output that depends on
precise allocation behaviour. The nonmoving threaded ways change where
these limits are reached, just as the already-omitted LLVM ways do.
Omit these ways instead of treating their incidental output differences
as test failures.
Assisted-by: gpt-5.6-sol via Codex CLI
- - - - -
c4abddcb by Simon Jakobi at 2026-08-14T15:16:44-04:00
rts/js: Implement eq_thread, and test Eq/Ord ThreadId (#16761)
Since d1f3c63701, Eq ThreadId is implemented via the RTS function
eq_thread, but the JS RTS never provided it, so comparing ThreadIds
for equality on the JS backend crashed with
ReferenceError: h$eq_thread is not defined
Like the C implementation, h$eq_thread uses pointer equality: The JS
RTS has exactly one thread object per thread.
Since previously no test exercised eq_thread directly, this commit
adds a test covering equality, its stability across GC, and agreement
with Ord.
Assisted-by: Claude Fable 5
- - - - -
4a7defa1 by Simon Jakobi at 2026-08-14T15:16:44-04:00
testsuite: Make listThreads1 insensitive to the RTS's own threads
listThreads1 expected `listThreads` to return exactly [ThreadId 1]. That
holds only under a non-threaded RTS. Under a threaded RTS however there
are more threads present, so we change the test to simply check that
`myThreadId` is present in the list.
Assisted-by: Claude Opus 5
- - - - -
b757727a by Vladislav Zavialov at 2026-08-14T15:17:27-04:00
Fix tcLookupId panic with RequiredTypeArguments and PatternSynonyms (#27586)
The arguments declared on the left-hand side of a pattern synonym are looked up
as term variables bound by its right-hand side. Prior to this patch, that lookup
panicked with RequiredTypeArguments:
data T a where
MkT :: forall a -> T a
pattern P :: Int -> T Int
pattern P x = MkT x
On the RHS, `x` looks like a term argument, so the renamer binds it in the term
namespace. Only during type checking does it turn out to be a type variable, so
the lookup on the LHS finds an ATyVar rather than an ATcId. As the lookup was
done with tcLookupId, it resulted in a panic.
Now the arguments are looked up with tcLookupPatSynArg, which reports an illegal
term-level use of `x`, just as an ordinary function definition `f (MkT x) = x`
does.
Test cases: T27586a T27586b T27586c
Assisted-by: Claude Opus 5
- - - - -
c130188d by Rodrigo Mesquita at 2026-08-15T06:29:53-04:00
loopImports: Don't dup ms_uid in summary imports
We were writing the ms_unitid of the mod summary with every single
import of that module
That complicated the code (as though the UnitId in that list could ever
be something else) and also allocates unnecessarily per every mod
import. Very slight allocation decrease measured locally in a few tests:
(MultiComponentModulesRecomp: -0.06%; MultiComponentModulesRecomp100: -0.05%)
Purely a clean up.
- - - - -
c71166a8 by Rodrigo Mesquita at 2026-08-15T06:29:53-04:00
downsweep: make control flow simpler and cache correct
This refactor extracts the control flow of downsweep into a single
function `dfsBuild`, which takes care of iteratively expanding and
traversing all nodes of the in-construction module graph necessary to
build a full `ModuleGraph`.
There are three levels of caching going on, all of which are necessary
to make sure we don't do repeated work (notably, NEVER summarise the
same module twice).
1. `dfsBuild` accumulates the final module graph and never revisits the
same node of the module graph. Cache is keyed by the final
`ModuleGraph`s `NodeKey`s.
2. For Module A in home-unit u1, each import in the list of imports
needs to be *found* (call to `findImportedModuleWithIsBoot`): at this
point, we only have the `ModuleName` of the import, not the `Module`.
This *finding* is somewhat expensive, so we cache it as well
(`ImportsCache`). The cache key is the home-unit to which the module
belongs~[1], the import package qualifier, and the ModuleName.
[1] Different home-units will have different package flags, which means
potentially different `Module` resolution for the same `ModuleName`.
3. The most expensive operation we want to avoid is summarising a
`Module` into a `ModSummary`, which notably involves parsing the
module header from scratch.
The third cache, in essence, maps a `Module` to its `ModSummary`
(named `ModSummaryCache`). This cache upholds the invariant: we NEVER
summarise the same module twice. In practice, the cache key is the
Module's UnitId and the Source path; the reason is we need to
distinguish between `.hs` and `.hs-boot` files, as their summaries
will differ.
Note that (2) can't guarantee this alone: Two ModuleName imports in
separate units can (and likely do) map to the same `Module`.
Note that the previous implementation failed to achieve the
no-duplicate-work summarisation invariant, and we ended up doing a
quadratic amount of processing in scenarios like test
`MultiComponentModules100`.
See also Note [Downsweep Control Flow and Caching]
Fixes #27461
Perf changes:
MultiComponentModules(normal) ghc/alloc 2,097,389,264 1,992,186,736 -5.0% GOOD
MultiComponentModules100(normal) ghc/alloc 24,310,173,770 21,293,867,360 -12.4% GOOD
MultiComponentModulesRecomp(normal) ghc/alloc 602,761,394 498,543,984 -17.3% GOOD
MultiComponentModulesRecomp100(normal) ghc/alloc 11,885,968,240 8,895,404,864 -25.2% GOOD
-------------------------
Metric Decrease:
MultiComponentModules
MultiComponentModules100
MultiComponentModulesRecomp
MultiComponentModulesRecomp100
-------------------------
- - - - -
ebc4047b by Rodrigo Mesquita at 2026-08-15T06:29:53-04:00
implicitRequirementsShallow can never reach HoleUnit
findImportedModule will never return `HoleUnit` for a `ModuleName`
(a `HoleUnit` can only be found as a signature instantiation, never as a
directly *imported* thing)
Therefore, we can drop `[ModuleName]` returned by
`implicitRequirementsShallow`, which makes many things dead code.
Namely, the call to `implicitRequirementsShallow` from
GHC.Driver.Downsweep which was a performance bottleneck (for doing lots
of duplicate work in findImportedModule) is now entirely gone.
Fixes #27053
In an MR with this patch and the downsweep refactor (previous commit), CI says:
MultiComponentModules(normal) ghc/alloc 2,097,396,728 1,943,662,304 -7.3% GOOD
MultiComponentModules100(normal) ghc/alloc 24,310,182,136 17,227,574,440 -29.1% GOOD
MultiComponentModulesRecomp(normal) ghc/alloc 602,769,518 449,973,656 -25.3% GOOD
MultiComponentModulesRecomp100(normal) ghc/alloc 11,885,976,408 4,828,894,160 -59.4% GOOD
-------------------------
Metric Decrease:
MultiComponentModules
MultiComponentModules100
MultiComponentModulesRecomp
MultiComponentModulesRecomp100
-------------------------
- - - - -
85a6ab01 by Rodrigo Mesquita at 2026-08-15T06:29:53-04:00
downsweep: Cache negative results
When traversing a module graph structure, a uniquely identified node
should always expand to the same thing.
I don't see how visiting the same node which failed to be expanded a
first time would ever successfully expand the second time we try to
expand it (eg. when coming from a different edge to it -- it is still
the same node!). The node expansion is local, based just based on the
node itself, not on the path to get there.
Therefore, this patch removes the weird behavior and commentary of
`dfsBuild` wrt to `Nothing` not being cached and being potentially
expanded a second time around to something different, which was
misleading and, ultimately, incorrect.
Now, we have a `MGRes`, which is more explicit about a node being
Skipped just being a node that is ignored whenever it is found (and that
skip is cached) -- and we may want to do this due to failures or due to
just trying nodes which might not work on purpose, like hs-boots.
We uniformly cache positive and negative results and remove the
assumption that there might be an ordering in which the same node
visited at a later time might be expanded differently.
This makes it possible to traverse the module nodes in parallel without
a change in behavior, since there's no longer a hidden ordering
requirement.
- - - - -
56747c3f by Rodrigo Mesquita at 2026-08-15T06:29:53-04:00
Organize and clean-up GHC.Driver.Downsweep
Simply some cosmetic changes, moving definitions around to structure the
module better into its relevant sections
(In go (ns ++ ss), it's not a problem to use ++ because it's a good
producer and we won't have to append fully before processing the next
item in go)
- - - - -
12f64118 by Wolfgang Jeltsch at 2026-08-15T06:31:12-04:00
Add support for textual output of bytecode file content
- - - - -
a737df91 by Brandon Chinn at 2026-08-15T12:40:25-04:00
Add law in qualified strings doc
- - - - -
e3188581 by Zubin Duggal at 2026-08-15T12:41:06-04:00
DmdAnal: Fix maxDmdType
We need to eta expand the smaller DmdType using defaultArgDmd, like in lubDmdType.
Introduce zipDmdType as a common combinator to implement both maxDmdType and lubDmdType
uniformly.
fixes #27626
- - - - -
ca9b0b22 by mangoiv at 2026-08-15T12:41:47-04:00
hadrian: set the executable bit for hie-bios.bat
- - - - -
1aac7095 by sheaf at 2026-08-16T04:37:16-04:00
Avoid wasteful allocations in mkTyConAppCo
The idiom "traverse isReflCo_maybe" followed by "map fst" used in
'GHC.Core.Coercion.mkTyConAppCo' was allocating a lot of waste.
This commit uses 'GHC.Data.Unboxed.traverseMaybeUB' to avoid all these
unnecessary intermediate allocations.
In a quick microbenchmark for 'mkTyConAppCo', this change resulted in:
- refl case (all argument coercions are reflexive):
- -60% runtime
- -80% allocations
- non-refl case:
- from 0% to -12% runtime (depending on which argument is non-refl)
- from 0% to -70% allocations ( -- '' -- )
Fixes #27648
-------------------------
Metric Decrease:
FamAppCachePerf
SimplCastPerf
T12425
T15703
T26426
T3064
T9872a
T9872b
T9872b_defer
T9872c
T9872d
T5321Fun
T9020
T9630
TcPlugin_RewritePerf
Metric Increase:
LinkableUsage02
-------------------------
- - - - -
3915e982 by Alan Zimmerman at 2026-08-16T04:37:58-04:00
EPA: Remove al_trailing from AnnList
It was not being used
- - - - -
fed942ac by Andreas Klebinger at 2026-08-17T12:11:57-04:00
testsuite: Use sigkill in process009.
SIGHUB might have been blocked by a (grand)*parent of the test.
In such cases the test would fail as the python process would simply
exist gracefully instead of committing to a premature end.
By using SIGKILL we can rely on the signal not being blocked, fixing #27578
in the process.
- - - - -
574c875f by Andreas Klebinger at 2026-08-17T12:12:39-04:00
Simplify comparison in DFM.hs
Fixes #27669
- - - - -
d8f1a2a3 by Alan Zimmerman at 2026-08-17T12:13:18-04:00
TTG: Add extension points to BooleanFormula
They are currently unused, but will be used for exact print
annotations next, allowing us to get rid of LocatedBF / SrcSpanAnnBF
- - - - -
93a2b20f by Andreas Klebinger at 2026-08-18T04:31:04-04:00
Fix a number of incorrect module references:
Fix module reference in Note [DataCon wrappers are conlike].
Fix module reference in Note [Detailed InertCans Invariants].
Fix module reference in Note [GHC's data format representations].
Fix module reference in Note [Grand plan for static forms].
Fix module reference in Note [How tuples work].
Fix module reference in Note [Solved dictionaries].
Fix module reference in Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)].
Fix module reference in Note [The VarBndr type and its uses].
Found the incorrect references with a llm.
- - - - -
eb0dfb01 by Simon Jakobi at 2026-08-18T04:31:44-04:00
ci: Run stack-hadrian-build only in full-ci pipelines
The job exists to catch changes that break hadrian/build-stack (#18726),
but nothing in the pipeline depends on it, and it can only break when
hadrian's dependencies change. Restricting it to full-ci (like
hadrian-multi) still covers marge-bot merge batches, so such breakage
cannot reach master unnoticed, while ordinary validate pipelines skip
the job.
Assisted-by: Claude Fable 5
- - - - -
b9160962 by Simon Jakobi at 2026-08-20T14:57:52-04:00
testsuite: Show baseline sample count and range in perf failures
A perf baseline is the mean of all samples recorded for a commit, and
it prints as a single number, hiding how far the samples spread. When
the spread is wide, this can indicate an unstable metric that isn't
actually useful as a signal for the perf tests.
For example, in #27602, T27336's peak_megabytes_allocated baseline
showed as 757 when the underlying samples were 605 and 909.
When the baseline is averaged from more than one sample, say so in the
failure output: the one-line stat-failure reason shows the sample
range, and the detail block lists the raw samples. Single-sample
baselines print exactly as before.
Context: #27602
Assisted-by: Claude Fable 5
- - - - -
a4979877 by Simon Jakobi at 2026-08-20T14:57:52-04:00
testsuite: Fold Baseline into CommitMetric
A Baseline was just a CommitMetric plus the commit it came from, built
by copying fields across. Since get_commit_metric already knows that
commit, record it on CommitMetric itself and drop Baseline. This also
collapses both branches of find_baseline into plain returns.
Assisted-by: Claude Fable 5
- - - - -
99fb8d68 by Simon Jakobi at 2026-08-20T14:57:52-04:00
ci: Clarify comment on pushing perf notes after failures
Context: #27602
Assisted-by: Claude Fable 5
- - - - -
2ca87972 by Alan Zimmerman at 2026-08-20T14:58:36-04:00
EPA: Remove LocatedBC / SrcSpanBF
The custom annotations are now in the BooleanFormula TTG extension
points, so LBooleanFormula can now use the standard LocatedA.
- - - - -
d2bc32aa by Simon Peyton Jones at 2026-08-21T12:59:26-04:00
Better handling of serialisation of wired-in names
Fixes #27501
- - - - -
d2795ffc by Alan Zimmerman at 2026-08-21T13:00:05-04:00
EPA: Remove NoEpTok/NoEpUniTok, using an unhelpful SrcSpan instead
Also introduce helper functions noEpTok and noEpUniTok to serve
as simple replacements in code inserting an token annotation without
location information.
- - - - -
b5d29ab8 by Brandon Chinn at 2026-08-25T18:42:08-04:00
Add Data.RealFloat and Infinity/NegInfinity/NaN pattern synonyms (#26961)
- - - - -
e60eb3bc by Andreas Klebinger at 2026-08-25T18:42:59-04:00
rts linker: Fix pointer arithmetic issue in flushInstructionCacheRISCV64
We accidentally operated over `uint64_t*` when we should use `uint8_t`.
Fixes #27569
- - - - -
c1653dc0 by Wolfgang Jeltsch at 2026-08-26T16:44:58+03:00
Add `rethrowSTM` and improve STM-related documentation
Adding `rethrowSTM` resolves #26758.
The implementation of `rethrowSTM` is completely analogous to the one of
`rethrowIO`.
The following is established for the documentation of `throwSTM` and
`catchSTM`:
* Both operations are directly described as analogs of their `IO`
counterparts.
* There is no reference to `throw` in the documentation of `throwSTM`,
because, although such a reference is great in the documentation of
`throwIO`, it is somewhat out of place in the documentation of
`throwSTM`.
* Instead of repeating part of `throwIO`’s documentation, the
documentation of `throwSTM` just recommends using `throwSTM` instead
of `throw` and references the corresponding arguments in the
documentation of `throwIO`.
- - - - -
142 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- + changelog.d/27626
- + changelog.d/T27586
- + changelog.d/downsweep-refactor
- + changelog.d/rethrow-stm
- + changelog.d/show-byte-code
- compiler/GHC/Builtin.hs
- compiler/GHC/Builtin/WiredIn/Types.hs
- compiler/GHC/ByteCode/Serialize.hs
- + compiler/GHC/ByteCode/Show.hs
- compiler/GHC/CmmToAsm/Format.hs
- compiler/GHC/Core/Class.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/BooleanFormula.hs
- compiler/GHC/Data/Unboxed.hs
- compiler/GHC/Data/Word64Map/Internal.hs
- compiler/GHC/Data/Word64Map/Lazy.hs
- compiler/GHC/Data/Word64Map/Strict.hs
- compiler/GHC/Data/Word64Map/Strict/Internal.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/GenerateCgIPEStub.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/TyCl/Class.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/Env.hs
- compiler/Language/Haskell/Syntax/BooleanFormula.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/ghc.cabal.in
- docs/users_guide/exts/qualified_strings.rst
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Mode.hs
- ghc/Main.hs
- hadrian/hie-bios.bat
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- + libraries/base/src/Data/RealFloat.hs
- libraries/base/src/GHC/Conc.hs
- libraries/base/tests/all.T
- libraries/base/tests/listThreads1.hs
- libraries/base/tests/listThreads1.stdout
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- rts/js/thread.js
- rts/linker/elf_reloc_riscv64.c
- testsuite/driver/perf_notes.py
- testsuite/driver/testglobals.py
- + testsuite/tests/concurrent/should_run/T16761.hs
- + testsuite/tests/concurrent/should_run/T16761.stdout
- testsuite/tests/concurrent/should_run/all.T
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/dmdanal/should_run/M2.hs
- + testsuite/tests/dmdanal/should_run/T27626.hs
- + testsuite/tests/dmdanal/should_run/T27626.stdout
- testsuite/tests/dmdanal/should_run/all.T
- + testsuite/tests/driver/T27461/Main1.hs
- + testsuite/tests/driver/T27461/Main2.hs
- + testsuite/tests/driver/T27461/Makefile
- + testsuite/tests/driver/T27461/T27461a.stderr
- + testsuite/tests/driver/T27461/T27461b.script
- + testsuite/tests/driver/T27461/T27461b.stderr
- + testsuite/tests/driver/T27461/T27461b.stdout
- + testsuite/tests/driver/T27461/all.T
- + testsuite/tests/driver/T27461/src/Bar.hs
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/module/mod185.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15279.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/parser/should_compile/T20718.stderr
- testsuite/tests/parser/should_compile/T20718b.stderr
- testsuite/tests/parser/should_compile/T20846.stderr
- testsuite/tests/parser/should_compile/T23315/T23315.stderr
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- testsuite/tests/process/process009.hs
- testsuite/tests/process/process009.stdout
- testsuite/tests/rts/all.T
- + testsuite/tests/show-bytecode/Example.hs
- + testsuite/tests/show-bytecode/Makefile
- + testsuite/tests/show-bytecode/all.T
- + testsuite/tests/show-bytecode/normalize
- + testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
- + testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout-javascript-unknown-ghcjs
- + testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
- + testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
- + testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout-javascript-unknown-ghcjs
- testsuite/tests/splice-imports/SI35.hs
- + testsuite/tests/vdq-rta/should_fail/T27586a.hs
- + testsuite/tests/vdq-rta/should_fail/T27586a.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586b.hs
- + testsuite/tests/vdq-rta/should_fail/T27586b.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586c.hs
- + testsuite/tests/vdq-rta/should_fail/T27586c.stderr
- testsuite/tests/vdq-rta/should_fail/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/check-ppr/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7cf6d1fc18b1b4085d3c1255fed4d4…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7cf6d1fc18b1b4085d3c1255fed4d4…
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/jeltsch/stm-exception-improvements] Add `rethrowSTM` and improve STM-related documentation
by Wolfgang Jeltsch (@jeltsch) 26 Aug '26
by Wolfgang Jeltsch (@jeltsch) 26 Aug '26
26 Aug '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/stm-exception-improvements at Glasgow Haskell Compiler / GHC
Commits:
7cf6d1fc by Wolfgang Jeltsch at 2026-08-26T16:43:46+03:00
Add `rethrowSTM` and improve STM-related documentation
Adding `rethrowSTM` resolves #26758.
The implementation of `rethrowSTM` is completely analogous to the one of
`rethrowIO`.
The following is established for the documentation of `throwSTM` and
`catchSTM`:
* Both operations are directly described as analogs of their `IO`
counterparts.
* There is no reference to `throw` in the documentation of `throwSTM`,
because, although such a reference is great in the documentation of
`throwIO`, it is somewhat out of place in the documentation of
`throwSTM`.
* Instead of repeating part of `throwIO`’s documentation, the
documentation of `throwSTM` just recommends using `throwSTM` instead
of `throw` and references the corresponding arguments in the
documentation of `throwIO`.
- - - - -
6 changed files:
- + changelog.d/rethrow-stm
- libraries/base/src/GHC/Conc.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
Changes:
=====================================
changelog.d/rethrow-stm
=====================================
@@ -0,0 +1,4 @@
+section: ghc-internal
+synopsis: Add `rethrowSTM`, an `STM` analog of `rethrowIO`
+issues: #26758
+mrs: !16501
=====================================
libraries/base/src/GHC/Conc.hs
=====================================
@@ -79,6 +79,9 @@ module GHC.Conc
, retry
, orElse
, throwSTM
+#if __GLASGOW_HASKELL__ >= 1002
+ , rethrowSTM
+#endif
, catchSTM
, TVar(..)
, newTVar
=====================================
libraries/ghc-internal/src/GHC/Internal/STM.hs
=====================================
@@ -5,6 +5,11 @@
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS_HADDOCK not-home #-}
+-- Make unused imports warnings instead of errors, because there are seemingly
+-- unused imports of `throw`, `throwIO`, and `rethrowIO`, which are actually
+-- used for documentation hyperlinking.
+{-# OPTIONS_GHC -Wwarn=unused-imports #-}
+
module GHC.Internal.STM
(
-- * the 'STM' monad
@@ -13,6 +18,7 @@ module GHC.Internal.STM
, retry
, orElse
, throwSTM
+ , rethrowSTM
, catchSTM
, unsafeIOToSTM
-- * TVars
@@ -28,7 +34,9 @@ import qualified GHC.Internal.Stack.Types as Rebindable
import GHC.Internal.Base
import GHC.Internal.Exception (Exception, toExceptionWithBacktrace, fromException, addExceptionContext)
import GHC.Internal.Exception.Context (ExceptionAnnotation)
-import GHC.Internal.Exception.Type (WhileHandling(..))
+import GHC.Internal.Exception.Type (
+ WhileHandling(..), ExceptionWithContext, NoBacktrace (NoBacktrace),
+ )
import GHC.Internal.Maybe (Maybe(..))
import GHC.Internal.Prim (
RealWorld, State#, TVar#, atomically#, catch#, catchRetry#, catchSTM#,
@@ -37,6 +45,10 @@ import GHC.Internal.Prim (
import GHC.Internal.Prim.PtrEq (sameTVar#)
import GHC.Internal.Stack (HasCallStack, withFrozenCallStack)
+-- Imports for documentation hyperlinking
+import GHC.Internal.Exception (throw)
+import GHC.Internal.IO (throwIO, rethrowIO)
+
-- TVars are shared memory locations which support atomic memory
-- transactions.
@@ -166,7 +178,7 @@ retry = STM $ \s# -> retry# s#
orElse :: STM a -> STM a -> STM a
orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
--- | A variant of 'throw' that can only be used within the 'STM' monad.
+-- | The 'STM' analog of 'throwIO'.
--
-- Throwing an exception in @STM@ aborts the transaction and propagates the
-- exception. If the exception is caught via 'catchSTM', only the changes
@@ -176,19 +188,8 @@ orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
-- If the exception is not caught inside of the 'STM', it is re-thrown by
-- 'atomically', and the entire 'STM' is rolled back.
--
--- Although 'throwSTM' has a type that is an instance of the type of 'throw', the
--- two functions are subtly different:
---
--- > throw e `seq` x ===> throw e
--- > throwSTM e `seq` x ===> x
---
--- The first example will cause the exception @e@ to be raised,
--- whereas the second one won\'t. In fact, 'throwSTM' will only cause
--- an exception to be raised when it is used within the 'STM' monad.
--- The 'throwSTM' variant should be used in preference to 'throw' to
--- raise an exception within the 'STM' monad because it guarantees
--- ordering with respect to other 'STM' operations, whereas 'throw'
--- does not.
+-- Note that 'throwSTM' is preferable to 'throw', for the same reasons that
+-- 'throwIO' is preferable to 'throw'.
throwSTM :: (HasCallStack, Exception e) => e -> STM a
throwSTM e = do
-- N.B. Typically use of unsafeIOToSTM is very much frowned upon as this
@@ -197,7 +198,11 @@ throwSTM e = do
se <- unsafeIOToSTM (withFrozenCallStack $ toExceptionWithBacktrace e)
STM $ raiseIO# se
--- | Exception handling within STM actions.
+-- | The 'STM' analog of 'rethrowIO'.
+rethrowSTM :: Exception e => ExceptionWithContext e -> STM a
+rethrowSTM e = throwSTM (NoBacktrace e)
+
+-- | The 'STM' analog of 'catch'.
--
-- @'catchSTM' m f@ catches any exception thrown by @m@ using 'throwSTM',
-- using the function @f@ to handle the exception. If an exception is
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -5139,6 +5139,7 @@ module GHC.Conc where
reportError :: GHC.Internal.Exception.Type.SomeException -> GHC.Internal.Types.IO ()
reportHeapOverflow :: GHC.Internal.Types.IO ()
reportStackOverflow :: GHC.Internal.Types.IO ()
+ rethrowSTM :: forall e a. GHC.Internal.Exception.Type.Exception e => GHC.Internal.Exception.Type.ExceptionWithContext e -> STM a
retry :: forall a. STM a
runHandlers :: GHC.Internal.ForeignPtr.ForeignPtr GHC.Internal.Word.Word8 -> Signal -> GHC.Internal.Types.IO ()
runSparks :: GHC.Internal.Types.IO ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -5139,6 +5139,7 @@ module GHC.Conc where
reportError :: GHC.Internal.Exception.Type.SomeException -> GHC.Internal.Types.IO ()
reportHeapOverflow :: GHC.Internal.Types.IO ()
reportStackOverflow :: GHC.Internal.Types.IO ()
+ rethrowSTM :: forall e a. GHC.Internal.Exception.Type.Exception e => GHC.Internal.Exception.Type.ExceptionWithContext e -> STM a
retry :: forall a. STM a
runHandlers :: GHC.Internal.ForeignPtr.ForeignPtr GHC.Internal.Word.Word8 -> Signal -> GHC.Internal.Types.IO ()
runSparks :: GHC.Internal.Types.IO ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -5145,6 +5145,7 @@ module GHC.Conc where
reportError :: GHC.Internal.Exception.Type.SomeException -> GHC.Internal.Types.IO ()
reportHeapOverflow :: GHC.Internal.Types.IO ()
reportStackOverflow :: GHC.Internal.Types.IO ()
+ rethrowSTM :: forall e a. GHC.Internal.Exception.Type.Exception e => GHC.Internal.Exception.Type.ExceptionWithContext e -> STM a
retry :: forall a. STM a
runSparks :: GHC.Internal.Types.IO ()
setAllocationCounter :: GHC.Internal.Int.Int64 -> GHC.Internal.Types.IO ()
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cf6d1fc18b1b4085d3c1255fed4d4e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cf6d1fc18b1b4085d3c1255fed4d4e…
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
26 Aug '26
Hannes Siebenhandl pushed new branch wip/fendor/uic-reuse at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/uic-reuse
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/jeltsch/improve-closure-property-check.global-unit-info-map] Reuse the UnitIndexCache after initialising multiple home units
by Hannes Siebenhandl (@fendor) 26 Aug '26
by Hannes Siebenhandl (@fendor) 26 Aug '26
26 Aug '26
Hannes Siebenhandl pushed to branch wip/jeltsch/improve-closure-property-check.global-unit-info-map at Glasgow Haskell Compiler / GHC
Commits:
44ebfb87 by fendor at 2026-08-26T15:39:12+02:00
Reuse the UnitIndexCache after initialising multiple home units
- - - - -
1 changed file:
- compiler/GHC/Driver/Session/Units.hs
Changes:
=====================================
compiler/GHC/Driver/Session/Units.hs
=====================================
@@ -145,8 +145,15 @@ initMulti unitArgsFiles lintDynFlagsAndSrcs = do
checkUnitCycles initial_dflags home_unit_graph
let dflags = homeUnitEnv_dflags $ HUG.unitEnv_lookup mainUnitId home_unit_graph
- unitEnv <- assertUnitEnvInvariant <$> (liftIO $ initUnitEnv mainUnitId home_unit_graph (ghcNameVersion dflags) (targetPlatform dflags))
- let final_hsc_env = hsc_env { hsc_unit_env = unitEnv }
+ newUnitEnv <- do
+ env <- liftIO $ initUnitEnv mainUnitId home_unit_graph (ghcNameVersion dflags) (targetPlatform dflags)
+ -- We need to reuse the 'UnitIndexCache' as we used it above in 'initUnits'.
+ -- See Note [Sharing 'UnitInfo's across the 'UnitEnv'] why this must be shared.
+ pure $ assertUnitEnvInvariant $ env
+ { ue_uic = hscUIC hsc_env
+ }
+
+ let final_hsc_env = hsc_env { hsc_unit_env = newUnitEnv }
GHC.setSession final_hsc_env
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44ebfb87150d73288987bb944a6ed11…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44ebfb87150d73288987bb944a6ed11…
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/jeltsch/stm-exception-improvements] Add `rethrowSTM` and improve STM-related documentation
by Wolfgang Jeltsch (@jeltsch) 26 Aug '26
by Wolfgang Jeltsch (@jeltsch) 26 Aug '26
26 Aug '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/stm-exception-improvements at Glasgow Haskell Compiler / GHC
Commits:
539d1808 by Wolfgang Jeltsch at 2026-08-26T16:38:58+03:00
Add `rethrowSTM` and improve STM-related documentation
Adding `rethrowSTM` resolves #26758.
The implementation of `rethrowSTM` is completely analogous to the one of
`rethrowIO`.
The following is established for the documentation of `throwSTM` and
`catchSTM`:
* Both operations are directly described as analogs of their `IO`
counterparts.
* There is no reference to `throw` in the documentation of `throwSTM`,
because, although such a reference is great in the documentation of
`throwIO`, it is somewhat out of place in the documentation of
`throwSTM`.
* Instead of repeating part of `throwIO`’s documentation, the
documentation of `throwSTM` just recommends using `throwSTM` instead
of `throw` and references the corresponding arguments in the
documentation of `throwIO`.
- - - - -
6 changed files:
- + changelog.d/rethrow-stm
- libraries/base/src/GHC/Conc.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
Changes:
=====================================
changelog.d/rethrow-stm
=====================================
@@ -0,0 +1,4 @@
+section: ghc-internal
+synopsis: Add `rethrowSTM`, an `STM` analog of `rethrowIO`
+issues: #26758
+mrs: !16501
=====================================
libraries/base/src/GHC/Conc.hs
=====================================
@@ -79,6 +79,9 @@ module GHC.Conc
, retry
, orElse
, throwSTM
+#if __GLASGOW_HASKELL__ >= 1002
+ , rethrowSTM
+#endif
, catchSTM
, TVar(..)
, newTVar
=====================================
libraries/ghc-internal/src/GHC/Internal/STM.hs
=====================================
@@ -3,6 +3,7 @@
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
+{-# OPTIONS_GHC -Wwarn=unused-imports #-}
{-# OPTIONS_HADDOCK not-home #-}
module GHC.Internal.STM
@@ -13,6 +14,7 @@ module GHC.Internal.STM
, retry
, orElse
, throwSTM
+ , rethrowSTM
, catchSTM
, unsafeIOToSTM
-- * TVars
@@ -28,7 +30,9 @@ import qualified GHC.Internal.Stack.Types as Rebindable
import GHC.Internal.Base
import GHC.Internal.Exception (Exception, toExceptionWithBacktrace, fromException, addExceptionContext)
import GHC.Internal.Exception.Context (ExceptionAnnotation)
-import GHC.Internal.Exception.Type (WhileHandling(..))
+import GHC.Internal.Exception.Type (
+ WhileHandling(..), ExceptionWithContext, NoBacktrace (NoBacktrace),
+ )
import GHC.Internal.Maybe (Maybe(..))
import GHC.Internal.Prim (
RealWorld, State#, TVar#, atomically#, catch#, catchRetry#, catchSTM#,
@@ -37,6 +41,10 @@ import GHC.Internal.Prim (
import GHC.Internal.Prim.PtrEq (sameTVar#)
import GHC.Internal.Stack (HasCallStack, withFrozenCallStack)
+-- Imports for documentation hyperlinking
+import GHC.Internal.Exception (throw)
+import GHC.Internal.IO (throwIO, rethrowIO)
+
-- TVars are shared memory locations which support atomic memory
-- transactions.
@@ -166,7 +174,7 @@ retry = STM $ \s# -> retry# s#
orElse :: STM a -> STM a -> STM a
orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
--- | A variant of 'throw' that can only be used within the 'STM' monad.
+-- | The 'STM' analog of 'throwIO'.
--
-- Throwing an exception in @STM@ aborts the transaction and propagates the
-- exception. If the exception is caught via 'catchSTM', only the changes
@@ -176,19 +184,8 @@ orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
-- If the exception is not caught inside of the 'STM', it is re-thrown by
-- 'atomically', and the entire 'STM' is rolled back.
--
--- Although 'throwSTM' has a type that is an instance of the type of 'throw', the
--- two functions are subtly different:
---
--- > throw e `seq` x ===> throw e
--- > throwSTM e `seq` x ===> x
---
--- The first example will cause the exception @e@ to be raised,
--- whereas the second one won\'t. In fact, 'throwSTM' will only cause
--- an exception to be raised when it is used within the 'STM' monad.
--- The 'throwSTM' variant should be used in preference to 'throw' to
--- raise an exception within the 'STM' monad because it guarantees
--- ordering with respect to other 'STM' operations, whereas 'throw'
--- does not.
+-- Note that 'throwSTM' is preferable to 'throw', for the same reasons that
+-- 'throwIO' is preferable to 'throw'.
throwSTM :: (HasCallStack, Exception e) => e -> STM a
throwSTM e = do
-- N.B. Typically use of unsafeIOToSTM is very much frowned upon as this
@@ -197,7 +194,11 @@ throwSTM e = do
se <- unsafeIOToSTM (withFrozenCallStack $ toExceptionWithBacktrace e)
STM $ raiseIO# se
--- | Exception handling within STM actions.
+-- | The 'STM' analog of 'rethrowIO'.
+rethrowSTM :: Exception e => ExceptionWithContext e -> STM a
+rethrowSTM e = throwSTM (NoBacktrace e)
+
+-- | The 'STM' analog of 'catch'.
--
-- @'catchSTM' m f@ catches any exception thrown by @m@ using 'throwSTM',
-- using the function @f@ to handle the exception. If an exception is
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -5139,6 +5139,7 @@ module GHC.Conc where
reportError :: GHC.Internal.Exception.Type.SomeException -> GHC.Internal.Types.IO ()
reportHeapOverflow :: GHC.Internal.Types.IO ()
reportStackOverflow :: GHC.Internal.Types.IO ()
+ rethrowSTM :: forall e a. GHC.Internal.Exception.Type.Exception e => GHC.Internal.Exception.Type.ExceptionWithContext e -> STM a
retry :: forall a. STM a
runHandlers :: GHC.Internal.ForeignPtr.ForeignPtr GHC.Internal.Word.Word8 -> Signal -> GHC.Internal.Types.IO ()
runSparks :: GHC.Internal.Types.IO ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -5139,6 +5139,7 @@ module GHC.Conc where
reportError :: GHC.Internal.Exception.Type.SomeException -> GHC.Internal.Types.IO ()
reportHeapOverflow :: GHC.Internal.Types.IO ()
reportStackOverflow :: GHC.Internal.Types.IO ()
+ rethrowSTM :: forall e a. GHC.Internal.Exception.Type.Exception e => GHC.Internal.Exception.Type.ExceptionWithContext e -> STM a
retry :: forall a. STM a
runHandlers :: GHC.Internal.ForeignPtr.ForeignPtr GHC.Internal.Word.Word8 -> Signal -> GHC.Internal.Types.IO ()
runSparks :: GHC.Internal.Types.IO ()
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -5145,6 +5145,7 @@ module GHC.Conc where
reportError :: GHC.Internal.Exception.Type.SomeException -> GHC.Internal.Types.IO ()
reportHeapOverflow :: GHC.Internal.Types.IO ()
reportStackOverflow :: GHC.Internal.Types.IO ()
+ rethrowSTM :: forall e a. GHC.Internal.Exception.Type.Exception e => GHC.Internal.Exception.Type.ExceptionWithContext e -> STM a
retry :: forall a. STM a
runSparks :: GHC.Internal.Types.IO ()
setAllocationCounter :: GHC.Internal.Int.Int64 -> GHC.Internal.Types.IO ()
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/539d18085a32c7c5dc193d9c6c725e0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/539d18085a32c7c5dc193d9c6c725e0…
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/romes/27514] 2 commits: Rule-based deterministic concurrent downsweep
by sheaf (@sheaf) 26 Aug '26
by sheaf (@sheaf) 26 Aug '26
26 Aug '26
sheaf pushed to branch wip/romes/27514 at Glasgow Haskell Compiler / GHC
Commits:
7e6d3b57 by sheaf at 2026-08-26T15:05:00+02:00
Rule-based deterministic concurrent downsweep
This commit rewrites downsweep as a single query-answering rule
(see 'DownsweepRule') that can be executed by concurrent worker threads.
The design allows every expensive operation (preprocessing files with CPP,
parsing headers, reading interfaces) to be performed concurrently
according to the -j<N>/-jsem flags.
See Note [Rules-based downsweep] in GHC.Driver.Downsweep.
To achieve this, the finder cache was slightly restructured in order to
account for modules whose source files are directly specified as targets;
see the new Note [Known home modules] in GHC.Unit.Finder.Types. This
allowed us to remove 'addModuleToFinder', 'addHomeModuleToFinder' and
a few brittle hacks (e.g. in Backpack).
Fixes #27514
- - - - -
68246948 by sheaf at 2026-08-26T15:05:00+02:00
Separate Home/External finder caches
- - - - -
44 changed files:
- + changelog.d/parallel-downsweep
- compiler/GHC.hs
- compiler/GHC/Builtin.hs
- + compiler/GHC/Data/Dependent.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Concurrency.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/LogQueue.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/UnresolvedImport.hs
- compiler/GHC/Unit/Finder.hs
- + compiler/GHC/Unit/Finder/Cache.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Concurrent/Scope.hs
- compiler/ghc.cabal.in
- ghc/GHCi/UI.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/T27461/Makefile
- + testsuite/tests/driver/T27461/T27461c.stderr
- testsuite/tests/driver/T27461/all.T
- + testsuite/tests/driver/T27461/src/Wrong.hs
- testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs
- testsuite/tests/ghc-api/downsweep/OldModLocation.hs
- testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs
- testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- testsuite/tests/splice-imports/SI35.hs
- utils/check-ppr/Main.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2cfd600e365609cf959ef403de94b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2cfd600e365609cf959ef403de94b…
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/romes/27514] 5 commits: Driver: enableCodeGenForTH in load', not downsweep
by sheaf (@sheaf) 26 Aug '26
by sheaf (@sheaf) 26 Aug '26
26 Aug '26
sheaf pushed to branch wip/romes/27514 at Glasgow Haskell Compiler / GHC
Commits:
e6dfba05 by sheaf at 2026-08-26T12:29:01+02:00
Driver: enableCodeGenForTH in load', not downsweep
enableCodeGenForTH modifies the module graph for planning, creating
fresh temporary paths. So it should only be run when we are about to
execute a build plan (e.g. in load'), so that consumers that want to
know facts about the module graph don't go looking for files that don't
exist yet (in particular 'haddock --no-compilation').
- - - - -
48ea8603 by sheaf at 2026-08-26T12:29:04+02:00
2-phase Cache/Search Finder monad
This commit restructures the finder abstraction by introducing the
'FinderM' monad, which splits module lookup operations into two phases:
- a cache-only phase, performing no filesystem access,
- from the first cache miss onwards, a search action which may access
the filesystem.
This allows consumers to distinguish between quick cached results versus
more expensive filesystem search operations.
- - - - -
9ab0fdd8 by sheaf at 2026-08-26T14:20:10+02:00
Driver: structured concurrent worker abstraction
This commits introduces a structured concurrency framework in the style
of the 'ki' library: a collection of threads within a scope.
We implement two kind of concurrent workers on top of this framework:
- Independent workers cannot wait for one another at all. The only
scheduling operation is to wait for quiescence.
- Coordinating workers declare an STM readiness condition (waiting on
other workers to complete) which gates their start.
See Note [Deterministic concurrent workers] in GHC.Driver.Concurrency.
This commit ports upsweep to this new framework, with downsweep being
left as subsequent work.
Further changes along the way:
- Refactoring of how concurrency is acquired to avoid the footgun of
trying to use a no-op 'AbstractSem' as a lock in the serial case.
- The "re-run with -j1" logic for semaphore opening errors no longer
triggers on late semaphore failures (part-way through a lengthy
computation).
- Logger threads are properly cleaned up on exception, with each
concurrent worker's log queue and local TmpFs properly bracketed.
- The 'GhcMessage -> AnyGhcDiagnostic' and 'Maybe Messager'
arguments of 'depanalE', 'depanalPartial' and 'downsweep', which
were all dead in practice, have been dropped.
- - - - -
5105890f by sheaf at 2026-08-26T14:40:13+02:00
Rule-based deterministic concurrent downsweep
This commit rewrites downsweep as a single query-answering rule
(see 'DownsweepRule') that can be executed by concurrent worker threads.
The design allows every expensive operation (preprocessing files with CPP,
parsing headers, reading interfaces) to be performed concurrently
according to the -j<N>/-jsem flags.
See Note [Rules-based downsweep] in GHC.Driver.Downsweep.
To achieve this, the finder cache was slightly restructured in order to
account for modules whose source files are directly specified as targets;
see the new Note [Known home modules] in GHC.Unit.Finder.Types. This
allowed us to remove 'addModuleToFinder', 'addHomeModuleToFinder' and
a few brittle hacks (e.g. in Backpack).
Fixes #27514
- - - - -
c2cfd600 by sheaf at 2026-08-26T14:50:18+02:00
Separate Home/External finder caches
- - - - -
60 changed files:
- + changelog.d/parallel-downsweep
- compiler/GHC.hs
- compiler/GHC/Builtin.hs
- + compiler/GHC/Data/Dependent.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/Concurrency.hs
- + compiler/GHC/Driver/Config/Concurrency.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeAction.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/LogQueue.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/StgToJS/Linker/Linker.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Plugin.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/UnresolvedImport.hs
- compiler/GHC/Unit/Finder.hs
- + compiler/GHC/Unit/Finder/Cache.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- + compiler/GHC/Utils/Concurrent/Scope.hs
- compiler/GHC/Utils/TmpFs.hs
- compiler/ghc.cabal.in
- ghc/GHCi/UI.hs
- ghc/Main.hs
- linters/lint-codes/LintCodes/Static.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/T27461/Makefile
- + testsuite/tests/driver/T27461/T27461c.stderr
- testsuite/tests/driver/T27461/all.T
- + testsuite/tests/driver/T27461/src/Wrong.hs
- testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs
- testsuite/tests/ghc-api/downsweep/OldModLocation.hs
- testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs
- testsuite/tests/ghc-api/fixed-nodes/FixedNodes.hs
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- testsuite/tests/ghc-api/fixed-nodes/ModuleGraphInvariants.hs
- testsuite/tests/plugins/defaulting-plugin/DefaultLifted.hs
- testsuite/tests/splice-imports/SI35.hs
- utils/check-ppr/Main.hs
- utils/haddock/haddock-api/src/Haddock/Interface.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/125e4419567112305f85f29d478731…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/125e4419567112305f85f29d478731…
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