[Git][ghc/ghc][wip/fendor/linkable-usage] 3 commits: Add bytecode linkable regression test
by Hannes Siebenhandl (@fendor) 18 Feb '26
by Hannes Siebenhandl (@fendor) 18 Feb '26
18 Feb '26
Hannes Siebenhandl pushed to branch wip/fendor/linkable-usage at Glasgow Haskell Compiler / GHC
Commits:
09531201 by fendor at 2026-02-18T14:24:53+01:00
Add bytecode linkable regression test
- - - - -
e74f4f1a by fendor at 2026-02-18T14:24:54+01:00
WIP: LinkableUsage
- - - - -
fbe69319 by fendor at 2026-02-18T16:51:06+01:00
WIP: debug memory usage
- - - - -
26 changed files:
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Driver/Hooks.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Linker/ByteCode.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Unit/Home/ModInfo.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Utils/Binary.hs
- ghc/GHCi/Leak.hs
- + testsuite/ghc-config/ghc-config
- + testsuite/tests/bytecode/TLinkable/Makefile
- + testsuite/tests/bytecode/TLinkable/all.T
- + testsuite/tests/bytecode/TLinkable/genSplices
- + testsuite/tests/bytecode/TLinkable/genSplices2
- + testsuite/tests/bytecode/TLinkable/linkable_bytecodelib.stdout
Changes:
=====================================
compiler/GHC/ByteCode/Serialize.hs
=====================================
@@ -14,6 +14,7 @@ module GHC.ByteCode.Serialize
, InterpreterLibraryContents(..)
, writeBytecodeLib
, readBytecodeLib
+ , fingerprintModuleByteCodeContents
, decodeOnDiskModuleByteCode
, decodeOnDiskBytecodeLib
)
@@ -48,6 +49,7 @@ import GHC.Utils.Logger
import GHC.Linker.Types
import System.IO.Unsafe (unsafeInterleaveIO)
import GHC.Utils.Outputable
+import GHC.Utils.Fingerprint (Fingerprint, fingerprintByteString)
{- Note [Overview of persistent bytecode]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -94,6 +96,7 @@ See Note [Recompilation avoidance with bytecode objects]
-- contained by 'ModuleByteCode' are stored in-memory rather than as file paths to
-- temporary files.
data OnDiskModuleByteCode = OnDiskModuleByteCode { odgbc_module :: Module
+ , odgbc_hash :: Fingerprint
, odgbc_compiled_byte_code :: CompiledByteCode
, odgbc_foreign :: [ByteString] -- ^ Contents of object files
}
@@ -154,7 +157,6 @@ instance Binary OnDiskBytecodeLib where
put_ bh bytecodeLibForeign
-
writeBytecodeLib :: BytecodeLib -> FilePath -> IO ()
writeBytecodeLib lib path = do
odbco <- encodeBytecodeLib lib
@@ -174,12 +176,14 @@ readBytecodeLib hsc_env path = do
instance Binary OnDiskModuleByteCode where
get bh = do
odgbc_module <- get bh
+ odgbc_hash <- get bh
odgbc_compiled_byte_code <- get bh
odgbc_foreign <- get bh
pure OnDiskModuleByteCode {..}
put_ bh OnDiskModuleByteCode {..} = do
put_ bh odgbc_module
+ put_ bh odgbc_hash
put_ bh odgbc_compiled_byte_code
put_ bh odgbc_foreign
@@ -197,7 +201,8 @@ decodeOnDiskModuleByteCode hsc_env odbco = do
pure $ ModuleByteCode {
gbc_module = odgbc_module odbco,
gbc_compiled_byte_code = odgbc_compiled_byte_code odbco,
- gbc_foreign_files = foreign_files
+ gbc_foreign_files = foreign_files,
+ gbc_hash = odgbc_hash odbco
}
decodeOnDiskBytecodeLib :: HscEnv -> OnDiskBytecodeLib -> IO BytecodeLib
@@ -256,7 +261,8 @@ encodeOnDiskModuleByteCode bco = do
pure $ OnDiskModuleByteCode {
odgbc_module = gbc_module bco,
odgbc_compiled_byte_code = gbc_compiled_byte_code bco,
- odgbc_foreign = foreign_contents
+ odgbc_foreign = foreign_contents,
+ odgbc_hash = gbc_hash bco
}
-- | Read a 'ModuleByteCode' from a file.
@@ -281,6 +287,15 @@ writeBinByteCode f cbc = do
putWithUserData QuietBinIFace NormalCompression bh odbco
writeBinMem bh f
+fingerprintModuleByteCodeContents :: Module -> CompiledByteCode -> [FilePath] -> IO Fingerprint
+fingerprintModuleByteCodeContents modl cbc foreign_files = do
+ bh' <- openBinMem (1024 * 1024)
+ bh <- addBinNameWriter bh'
+ foreign_contents <- readObjectFiles foreign_files
+ putWithUserData QuietBinIFace NormalCompression bh
+ (modl, cbc, foreign_contents)
+ withBinBuffer bh (pure . fingerprintByteString)
+
instance Binary CompiledByteCode where
get bh = do
bc_bcos <- get bh
=====================================
compiler/GHC/Driver/Hooks.hs
=====================================
@@ -137,7 +137,7 @@ data Hooks = Hooks
, tcForeignExportsHook :: !(Maybe ([LForeignDecl GhcRn]
-> TcM (LHsBinds GhcTc, [LForeignDecl GhcTc], Bag GlobalRdrElt)))
, hscFrontendHook :: !(Maybe (ModSummary -> Hsc FrontendResult))
- , hscCompileCoreExprHook :: !(Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)))
+ , hscCompileCoreExprHook :: !(Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)))
, ghcPrimIfaceHook :: !(Maybe ModIface)
, runPhaseHook :: !(Maybe PhaseHook)
, runMetaHook :: !(Maybe (MetaHook TcM))
@@ -145,7 +145,7 @@ data Hooks = Hooks
-> HomePackageTable -> IO SuccessFlag))
, runRnSpliceHook :: !(Maybe (HsUntypedSplice GhcRn -> RnM (HsUntypedSplice GhcRn)))
, getValueSafelyHook :: !(Maybe (HscEnv -> Name -> Type
- -> IO (Either Type (HValue, [Linkable], PkgsLoaded))))
+ -> IO (Either Type (HValue, [LinkableWithUsage], PkgsLoaded))))
, createIservProcessHook :: !(Maybe (CreateProcess -> IO ProcessHandle))
, stgToCmmHook :: !(Maybe (StgToCmmConfig -> InfoTableProvMap -> [TyCon] -> CollectedCCs
-> [CgStgTopBinding] -> CgStream CmmGroup ModuleLFInfos))
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -866,7 +866,7 @@ hscRecompStatus
| otherwise -> do
-- Check the status of all the linkable types we might need.
-- 1. The in-memory linkable we had at hand.
- bc_in_memory_linkable <- checkByteCodeInMemory hsc_env mod_summary (homeMod_bytecode old_linkable)
+ bc_in_memory_linkable <- checkByteCodeInMemory hsc_env mod_summary (homeModLinkableByteCode old_linkable)
-- 2. The bytecode object file
bc_obj_linkable <- checkByteCodeFromObject hsc_env mod_summary
-- 3. Bytecode from an interface's whole core bindings.
@@ -1098,7 +1098,7 @@ loadIfaceByteCodeLazy ::
ModIface ->
ModLocation ->
TypeEnv ->
- IO (Maybe Linkable)
+ IO (Maybe (LinkableWith ModuleByteCode))
loadIfaceByteCodeLazy hsc_env iface location type_env =
case iface_core_bindings iface location of
Nothing -> return Nothing
@@ -1106,8 +1106,9 @@ loadIfaceByteCodeLazy hsc_env iface location type_env =
Just <$> compile wcb
where
compile decls = do
- bco <- unsafeInterleaveIO $ compileWholeCoreBindings hsc_env type_env decls
- linkable $ NE.singleton (DotGBC bco)
+ bco <- unsafeInterleaveIO $ do
+ compileWholeCoreBindings hsc_env type_env decls
+ linkable bco
linkable parts = do
if_time <- modificationTimeIfExists (ml_hi_file_ospath location)
@@ -1148,14 +1149,14 @@ initWholeCoreBindings hsc_env iface details (RecompLinkables bc o) = do
where
type_env = md_types details
- go :: RecompBytecodeLinkable -> IO (Maybe Linkable)
+ go :: RecompBytecodeLinkable -> IO (Maybe (LinkableWith ModuleByteCode))
go (NormalLinkable l) = pure l
go (WholeCoreBindingsLinkable wcbl) =
fmap Just $ for wcbl $ \wcb -> do
add_iface_to_hpt iface details hsc_env
- bco <- unsafeInterleaveIO $
- compileWholeCoreBindings hsc_env type_env wcb
- pure $ NE.singleton (DotGBC bco)
+ bco <- unsafeInterleaveIO $ do
+ compileWholeCoreBindings hsc_env type_env wcb
+ pure bco
-- | Hydrate interface Core bindings and compile them to bytecode.
--
@@ -2232,20 +2233,21 @@ make user's opt into writing the files.
-}
-- | Generate a 'ModuleByteCode' and write it to disk if `-fwrite-byte-code` is enabled.
-generateAndWriteByteCodeLinkable :: HscEnv -> CgInteractiveGuts -> ModLocation -> IO Linkable
+generateAndWriteByteCodeLinkable :: HscEnv -> CgInteractiveGuts -> ModLocation -> IO (LinkableWith ModuleByteCode)
generateAndWriteByteCodeLinkable hsc_env cgguts mod_location = do
bco_object <- generateAndWriteByteCode hsc_env cgguts mod_location
-- Either, get the same time as the .gbc file if it exists, or just the current time.
-- It's important the time of the linkable matches the time of the .gbc file for recompilation
-- checking.
bco_time <- maybe getCurrentTime pure =<< modificationTimeIfExists (ml_bytecode_file_ospath mod_location)
- return $ mkModuleByteCodeLinkable bco_time bco_object
+ return $ mkOnlyModuleByteCodeLinkable bco_time bco_object
mkModuleByteCode :: HscEnv -> Module -> ModLocation -> CgInteractiveGuts -> IO ModuleByteCode
mkModuleByteCode hsc_env mod mod_location cgguts = do
bcos <- hscGenerateByteCode hsc_env cgguts mod_location
objs <- outputAndCompileForeign hsc_env mod mod_location (cgi_foreign_files cgguts) (cgi_foreign cgguts)
- return $! ModuleByteCode mod bcos objs
+ !bcos_hash <- fingerprintModuleByteCodeContents mod bcos objs
+ return $! ModuleByteCode mod bcos objs bcos_hash
-- | Generate a fresh 'ModuleByteCode' for a given module but do not write it to disk.
generateFreshByteCodeLinkable :: HscEnv
@@ -2767,13 +2769,13 @@ hscTidy hsc_env guts = do
%* *
%********************************************************************* -}
-hscCompileCoreExpr :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+hscCompileCoreExpr :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
hscCompileCoreExpr hsc_env loc expr =
case hscCompileCoreExprHook (hsc_hooks hsc_env) of
Nothing -> hscCompileCoreExpr' hsc_env loc expr
Just h -> h hsc_env loc expr
-hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
hscCompileCoreExpr' hsc_env srcspan ds_expr = do
{- Simplify it -}
-- Question: should we call SimpleOpt.simpleOptExpr here instead?
@@ -2859,8 +2861,10 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do
{- load it -}
bco_time <- getCurrentTime
+ !bco_hash <- fingerprintModuleByteCodeContents this_mod bcos []
+ let mbc = ModuleByteCode this_mod bcos [] bco_hash
(mods_needed, units_needed) <- loadDecls interp hsc_env srcspan $
- Linkable bco_time this_mod $ NE.singleton $ DotGBC (ModuleByteCode this_mod bcos [])
+ Linkable bco_time this_mod $ NE.singleton (DotGBC mbc)
-- Get the foreign reference to the name we should have just loaded.
mhvs <- lookupFromLoadedEnv interp (idName binding_id)
{- Get the HValue for the root -}
@@ -2876,7 +2880,7 @@ jsCodeGen
-> Module
-> [(CgStgTopBinding,IdSet)]
-> Id
- -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+ -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id = do
let logger = hsc_logger hsc_env
tmpfs = hsc_tmpfs hsc_env
=====================================
compiler/GHC/Driver/Pipeline.hs
=====================================
@@ -430,7 +430,7 @@ link' hsc_env batch_attempt_linking mHscMessager hpt
let obj_files = concatMap linkableObjs linkables
in action obj_files
linkBytecodeLinkable action =
- checkLinkablesUpToDate hsc_env mHscMessager home_mods pkg_deps staticLink checkBytecodeLibraryLinkingNeeded homeMod_bytecode $ \linkables ->
+ checkLinkablesUpToDate hsc_env mHscMessager home_mods pkg_deps staticLink checkBytecodeLibraryLinkingNeeded homeModLinkableByteCode $ \linkables ->
let bytecode = concatMap linkableModuleByteCodes linkables
in action bytecode
=====================================
compiler/GHC/Driver/Plugins.hs
=====================================
@@ -342,7 +342,7 @@ data Plugins = Plugins
-- The purpose of this field is to cache the plugins so they
-- don't have to be loaded each time they are needed. See
-- 'GHC.Runtime.Loader.initializePlugins'.
- , loadedPluginDeps :: !([Linkable], PkgsLoaded)
+ , loadedPluginDeps :: !([LinkableWithUsage], PkgsLoaded)
-- ^ The object files required by the loaded plugins
-- See Note [Plugin dependencies]
}
=====================================
compiler/GHC/HsToCore/Usage.hs
=====================================
@@ -7,8 +7,6 @@ module GHC.HsToCore.Usage (
import GHC.Prelude
-import GHC.Driver.Env
-
import GHC.Tc.Types
import GHC.Iface.Load
@@ -27,7 +25,6 @@ import GHC.Types.Unique.Set
import GHC.Unit
import GHC.Unit.Env
-import GHC.Unit.External
import GHC.Unit.Module.Imported
import GHC.Unit.Module.ModIface
import GHC.Unit.Module.Deps
@@ -35,18 +32,17 @@ import GHC.Unit.Module.Deps
import GHC.Data.Maybe
import GHC.Data.FastString
-import Data.IORef
import Data.List (sortBy)
import Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set
-import qualified Data.List.NonEmpty as NE
import GHC.Linker.Types
import GHC.Unit.Finder
import GHC.Types.Unique.DFM
import GHC.Driver.Plugins
import qualified GHC.Unit.Home.Graph as HUG
+import qualified Data.List.NonEmpty as NE
{- Note [Module self-dependency]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -75,19 +71,17 @@ data UsageConfig = UsageConfig
mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv
-> Module -> ImportedMods -> [ImportUserSpec] -> NameSet
- -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded
+ -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [LinkableWithUsage] -> PkgsLoaded
-> IfG [Usage]
mkUsageInfo uc plugins fc unit_env
this_mod dir_imp_mods imp_decls used_names
dependent_files dependent_dirs merged needed_links needed_pkgs
= do
- eps <- liftIO $ readIORef (euc_eps (ue_eps unit_env))
file_hashes <- liftIO $ mapM getFileHash dependent_files
dirs_hashes <- liftIO $ mapM getDirHash dependent_dirs
let hu = ue_unsafeHomeUnit unit_env
- hug = ue_home_unit_graph unit_env
-- Dependencies on object files due to TH and plugins
- object_usages <- liftIO $ mkObjectUsage (eps_PIT eps) plugins fc hug needed_links needed_pkgs
+ object_usages <- liftIO $ mkObjectUsage plugins fc needed_links needed_pkgs
let all_home_ids = HUG.allUnits (ue_home_unit_graph unit_env)
mod_usages <- mk_mod_usage_info uc hu all_home_ids this_mod
dir_imp_mods imp_decls used_names
@@ -190,31 +184,31 @@ for a module or not. This is similar to how the recompilation checking for the l
-- | Find object files corresponding to the transitive closure of given home
-- modules and direct object files for pkg dependencies
-mkObjectUsage :: PackageIfaceTable -> Plugins -> FinderCache -> HomeUnitGraph-> [Linkable] -> PkgsLoaded -> IO [Usage]
-mkObjectUsage pit plugins fc hug th_links_needed th_pkgs_needed = do
- let ls = ordNubOn linkableModule (th_links_needed ++ plugins_links_needed)
+mkObjectUsage :: Plugins -> FinderCache -> [LinkableWithUsage] -> PkgsLoaded -> IO [Usage]
+mkObjectUsage plugins fc th_links_needed th_pkgs_needed = do
+ let ls = th_links_needed ++ plugins_links_needed
ds = concatMap loaded_pkg_hs_objs $ eltsUDFM (plusUDFM th_pkgs_needed plugin_pkgs_needed) -- TODO possibly record loaded_pkg_non_hs_objs as well
(plugins_links_needed, plugin_pkgs_needed) = loadedPluginDeps plugins
concat <$> sequence (map linkableToUsage ls ++ map librarySpecToUsage ds)
where
- linkableToUsage (Linkable _ m uls) = mapM (partToUsage m) (NE.toList uls)
-
- msg m = moduleNameString (moduleName m) ++ "[TH] changed"
+ linkableToUsage :: LinkableWithUsage -> IO [Usage]
+ linkableToUsage (Linkable _ _m parts) = traverse partToUsage (NE.toList parts)
+
+ partToUsage link_usage =
+ case link_usage of
+ FileLinkableUsage{flu_file, flu_message} -> do
+ fing flu_message flu_file
+
+ ByteCodeLinkableUsage{bclu_module, bclu_hash} ->
+ pure $
+ UsageHomeModuleBytecode
+ { usg_mod_name = moduleName bclu_module
+ , usg_unit_id = toUnitId $ moduleUnit bclu_module
+ , usg_bytecode_hash = bclu_hash
+ }
fing mmsg fn = UsageFile (mkFastString fn) <$> lookupFileCache fc fn <*> pure mmsg
- partToUsage m part =
- case linkablePartPath part of
- Just fn -> fing (Just (msg m)) fn
- Nothing -> do
- -- This should only happen for home package things but oneshot puts
- -- home package ifaces in the PIT.
- miface <- lookupIfaceByModule hug pit m
- case miface of
- Nothing -> pprPanic "linkableToUsage" (ppr m)
- Just iface ->
- return $ UsageHomeModuleInterface (moduleName m) (toUnitId $ moduleUnit m) (mi_iface_hash iface)
-
librarySpecToUsage :: LibrarySpec -> IO [Usage]
librarySpecToUsage (Objects os) = traverse (fing Nothing) os
librarySpecToUsage (Archive fn) = traverse (fing Nothing) [fn]
=====================================
compiler/GHC/Iface/Recomp.hs
=====================================
@@ -88,6 +88,10 @@ import GHC.Iface.Errors.Ppr
import Data.Functor
import Data.Bifunctor (first)
import GHC.Types.PkgQual
+import GHC.ByteCode.Serialize (ModuleByteCode, gbc_hash)
+import GHC.Unit.Home.Graph (lookupHugByModule)
+import GHC.Unit.Home.ModInfo (HomeModLinkable(..), HomeModInfo (..))
+import GHC.Linker.Types (linkableParts)
{-
-----------------------------------------------
@@ -190,6 +194,7 @@ data RecompReason
| ModuleAdded (ImportLevel, UnitId, ModuleName)
| ModuleChangedRaw ModuleName
| ModuleChangedIface ModuleName
+ | ModuleChangedBytecode ModuleName
| FileChanged FilePath
| DirChanged FilePath
| CustomReason String
@@ -224,7 +229,8 @@ instance Outputable RecompReason where
SigsMergeChanged -> text "Signatures to merge in changed"
ModuleChanged m -> ppr m <+> text "changed"
ModuleChangedRaw m -> ppr m <+> text "changed (raw)"
- ModuleChangedIface m -> ppr m <+> text "changed (interface)"
+ ModuleChangedIface m -> ppr m <+> text "changed (bytecode)"
+ ModuleChangedBytecode m -> ppr m <+> text "changed (interface)"
ModuleRemoved (_st, _uid, m) -> ppr m <+> text "removed"
ModuleAdded (_st, _uid, m) -> ppr m <+> text "added"
FileChanged fp -> text fp <+> text "changed"
@@ -718,6 +724,15 @@ needInterface mod continue
Nothing -> return $ NeedsRecompile MustCompile
Just iface -> liftIO $ continue iface
+needBytecode :: Module -> (ModuleByteCode -> IO RecompileRequired)
+ -> IfG RecompileRequired
+needBytecode mod continue
+ = do
+ mb_recomp <- tryGetBytecode mod
+ case mb_recomp of
+ Nothing -> return $ NeedsRecompile MustCompile
+ Just mbc -> liftIO $ continue mbc
+
tryGetModIface :: String -> Module -> IfG (Maybe ModIface)
tryGetModIface doc_msg mod
= do -- Load the imported interface if possible
@@ -739,6 +754,27 @@ tryGetModIface doc_msg mod
-- import and it's been deleted
Succeeded iface -> pure $ Just iface
+tryGetBytecode :: Module -> IfG (Maybe ModuleByteCode)
+tryGetBytecode mod
+ = do -- Load the imported bytecode if possible
+ logger <- getLogger
+ liftIO $ trace_hi_diffs logger (text "Checking bytecode hash for module" <+> ppr mod <+> ppr (moduleUnit mod))
+
+ mb_module_bytecode <- do
+ env <- getTopEnv
+ liftIO (lookupHugByModule mod (hsc_HUG env)) >>= \ case
+ Nothing -> pure Nothing
+ Just hmi ->
+ case homeMod_bytecode (hm_linkable hmi) of
+ Nothing -> pure Nothing
+ Just gbc_linkable -> pure $ Just $ linkableParts gbc_linkable
+
+ case mb_module_bytecode of
+ Nothing -> do
+ liftIO $ trace_hi_diffs logger (sep [text "Couldn't find bytecode for module", ppr mod])
+ return Nothing
+ Just module_bytecode -> pure $ Just module_bytecode
+
-- | Given the usage information extracted from the old
-- M.hi file for the module being compiled, figure out
-- whether M needs to be recompiled.
@@ -760,14 +796,14 @@ checkModUsage _ UsageMergedRequirement{ usg_mod = mod, usg_mod_hash = old_mod_ha
needInterface mod $ \iface -> do
let reason = ModuleChangedRaw (moduleName mod)
checkModuleFingerprint logger reason old_mod_hash (mi_mod_hash iface)
-checkModUsage _ UsageHomeModuleInterface{ usg_mod_name = mod_name
+checkModUsage _ UsageHomeModuleBytecode{ usg_mod_name = mod_name
, usg_unit_id = uid
- , usg_iface_hash = old_mod_hash } = do
+ , usg_bytecode_hash = old_bytecode_hash } = do
let mod = mkModule (RealUnit (Definite uid)) mod_name
logger <- getLogger
- needInterface mod $ \iface -> do
- let reason = ModuleChangedIface mod_name
- checkIfaceFingerprint logger reason old_mod_hash (mi_iface_hash iface)
+ needBytecode mod $ \cbc -> do
+ let reason = ModuleChangedBytecode mod_name
+ checkBytecodeFingerprint logger reason old_bytecode_hash (gbc_hash cbc)
checkModUsage _ UsageHomeModule{
usg_mod_name = mod_name,
@@ -1032,19 +1068,18 @@ checkModuleFingerprint logger reason old_mod_hash new_mod_hash
= out_of_date_hash logger reason (text " Module fingerprint has changed")
old_mod_hash new_mod_hash
-checkIfaceFingerprint
+checkBytecodeFingerprint
:: Logger
-> RecompReason
-> Fingerprint
-> Fingerprint
-> IO RecompileRequired
-checkIfaceFingerprint logger reason old_mod_hash new_mod_hash
- | new_mod_hash == old_mod_hash
- = up_to_date logger (text "Iface fingerprint unchanged")
-
+checkBytecodeFingerprint logger reason old_bytecode_hash new_bytecode_hash
+ | old_bytecode_hash == new_bytecode_hash
+ = up_to_date logger (text "Bytecode fingerprint unchanged")
| otherwise
- = out_of_date_hash logger reason (text " Iface fingerprint has changed")
- old_mod_hash new_mod_hash
+ = out_of_date_hash logger reason (text " Bytecode fingerprint has changed")
+ old_bytecode_hash new_bytecode_hash
------------------------
checkEntityUsage :: Logger
=====================================
compiler/GHC/Iface/Recomp/Types.hs
=====================================
@@ -146,10 +146,10 @@ pprUsage usage@UsageDirectory{}
ppr (usg_dir_hash usage)]
pprUsage usage@UsageMergedRequirement{}
= hsep [text "merged", ppr (usg_mod usage), ppr (usg_mod_hash usage)]
-pprUsage usage@UsageHomeModuleInterface{}
- = hsep [text "implementation", ppr (usg_mod_name usage)
+pprUsage usage@UsageHomeModuleBytecode{}
+ = hsep [text "Bytecode", ppr (usg_mod_name usage)
, ppr (usg_unit_id usage)
- , ppr (usg_iface_hash usage)]
+ , ppr (usg_bytecode_hash usage)]
pprUsageImport :: Outputable mod => mod -> Fingerprint -> IsSafeImport -> SDoc
pprUsageImport mod hash safe
@@ -157,4 +157,4 @@ pprUsageImport mod hash safe
, ppr hash ]
where
pp_safe | safe = text "safe"
- | otherwise = text " -/ "
\ No newline at end of file
+ | otherwise = text " -/ "
=====================================
compiler/GHC/Linker/ByteCode.hs
=====================================
@@ -31,7 +31,7 @@ linkBytecodeLib hsc_env gbcs = do
on_disk_bcos <- mapM (readBinByteCode hsc_env) bytecodeObjects
- let (all_cbcs, foreign_stubs) = unzip [ (bs, fs) | ModuleByteCode _m bs fs <- on_disk_bcos ++ gbcs]
+ let (all_cbcs, foreign_stubs) = unzip [ (bs, fs) | ModuleByteCode _m bs fs _hash <- on_disk_bcos ++ gbcs]
interpreter_foreign_lib <- mkInterpreterLib hsc_env (concat foreign_stubs ++ objectFiles)
@@ -67,4 +67,4 @@ mkInterpreterLib hsc_env files =
return $ Just (InterpreterSharedObject foreign_stub_lib_path foreign_stub_lib_dir foreign_stub_lib_name)
Nothing -> pure Nothing
False -> do
- pure $ Just (InterpreterStaticObjects files)
\ No newline at end of file
+ pure $ Just (InterpreterStaticObjects files)
=====================================
compiler/GHC/Linker/Deps.hs
=====================================
@@ -63,7 +63,7 @@ data LinkDepsOpts = LinkDepsOpts
data LinkDeps = LinkDeps
{ ldNeededLinkables :: [Linkable]
- , ldAllLinkables :: [Linkable]
+ , ldAllLinkables :: [LinkableWithUsage]
, ldUnits :: [UnitId]
, ldNeededUnits :: UniqDSet UnitId
}
@@ -126,7 +126,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
return $ LinkDeps
{ ldNeededLinkables = lnks_needed
- , ldAllLinkables = links_got ++ lnks_needed
+ , ldAllLinkables = links_got ++ mkLinkablesUsage lnks_needed
, ldUnits = pkgs_needed
, ldNeededUnits = pkgs_s
}
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -135,6 +135,7 @@ import qualified Data.IntMap.Strict as IM
import qualified Data.Map.Strict as M
import Foreign.Ptr (nullPtr)
import GHC.ByteCode.Serialize
+import Control.DeepSeq (force)
-- Note [Linkers and loaders]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -228,7 +229,7 @@ lookupFromLoadedEnv interp name = do
-- | Load the module containing the given Name and get its associated 'HValue'.
--
-- Throws a 'ProgramError' if loading fails or the name cannot be found.
-loadName :: Interp -> HscEnv -> Name -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+loadName :: Interp -> HscEnv -> Name -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
loadName interp hsc_env name = do
initLoaderState interp hsc_env
modifyLoaderState interp $ \pls0 -> do
@@ -258,7 +259,7 @@ loadDependencies
-> LoaderState
-> SrcSpan
-> [Module]
- -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required
+ -> IO (LoaderState, SuccessFlag, [LinkableWithUsage], PkgsLoaded) -- ^ returns the set of linkables required
-- When called, the loader state must have been initialized (see `initLoaderState`)
loadDependencies interp hsc_env pls span needed_mods = do
let opts = initLinkDepsOpts hsc_env
@@ -667,6 +668,7 @@ findBytecodeLinkableMaybe hsc_env mod locn = do
case maybe_bytecode_time of
Nothing -> return Nothing
Just bytecode_time -> do
+ -- TODO: @fendor This must go
-- Also load the interface, for reasons to do with recompilation avoidance.
-- See Note [Recompilation avoidance with bytecode objects]
_ <- initIfaceLoad hsc_env $
@@ -723,7 +725,7 @@ get_reachable_nodes hsc_env mods
********************************************************************* -}
-- | Load the dependencies of a linkable, and then load the linkable itself.
-loadDecls :: Interp -> HscEnv -> SrcSpan -> Linkable -> IO ([Linkable], PkgsLoaded)
+loadDecls :: Interp -> HscEnv -> SrcSpan -> Linkable -> IO ([LinkableWithUsage], PkgsLoaded)
loadDecls interp hsc_env span linkable = do
-- Initialise the linker (if it's not been done already)
initLoaderState interp hsc_env
@@ -823,7 +825,7 @@ loadModuleLinkables interp hsc_env pls keep_spec linkables
(objs, bcos) = partitionLinkables linkables
-linkableInSet :: Linkable -> LinkableSet -> Bool
+linkableInSet :: Linkable -> LinkableSet LinkableWithUsage -> Bool
linkableInSet l objs_loaded =
case lookupModuleEnv objs_loaded (linkableModule l) of
Nothing -> False
@@ -952,17 +954,17 @@ dynLoadObjs interp hsc_env pls objs = do
then addWay WayProf
else id
-rmDupLinkables :: LinkableSet -- Already loaded
+rmDupLinkables :: LinkableSet LinkableWithUsage -- Already loaded
-> [Linkable] -- New linkables
- -> (LinkableSet, -- New loaded set (including new ones)
+ -> (LinkableSet LinkableWithUsage, -- New loaded set (including new ones)
[Linkable]) -- New linkables (excluding dups)
rmDupLinkables already ls
= go already [] ls
where
- go already extras [] = (already, extras)
- go already extras (l:ls)
+ go !already extras [] = (already, extras)
+ go !already extras (l:ls)
| linkableInSet l already = go already extras ls
- | otherwise = go (extendModuleEnv already (linkableModule l) l) (l:extras) ls
+ | otherwise = go (extendModuleEnv already (linkableModule l) $! force $ mkLinkableUsage l) (l:extras) ls
{- **********************************************************************
@@ -974,7 +976,7 @@ rmDupLinkables already ls
dynLinkBCOs :: Interp -> LoaderState -> KeepModuleLinkableDefinitions -> [Linkable] -> IO LoaderState
dynLinkBCOs interp pls keep_spec bcos =
- let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos
+ let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos -- TODO: @fendor, convert to linkable usage here?
pls1 = pls { bcos_loaded = bcos_loaded' }
cbcs :: [CompiledByteCode]
@@ -1109,13 +1111,13 @@ unload_wkr interp pls@LoaderState{..} = do
-- we're unloading some code. -fghci-leak-check with the tests in
-- testsuite/ghci can detect space leaks here.
- let linkables_to_unload = moduleEnvElts objs_loaded ++ moduleEnvElts bcos_loaded
+ let linkables_to_unload = moduleEnvElts objs_loaded ++ moduleEnvElts bcos_loaded -- TODO: @fendor LinkableUsage here already?
mapM_ unloadObjs linkables_to_unload
-- If we unloaded any object files at all, we need to purge the cache
-- of lookupSymbol results.
- when (not (null (filter (not . null . linkableObjs) linkables_to_unload))) $
+ when (not (null (filter (not . null . linkableUsageObjs) linkables_to_unload))) $
purgeLookupSymbolCache interp
let !new_pls = pls { bco_loader_state = modifyHomePackageBytecodeState bco_loader_state $ \_ -> emptyBytecodeState,
@@ -1125,7 +1127,7 @@ unload_wkr interp pls@LoaderState{..} = do
return new_pls
where
- unloadObjs :: Linkable -> IO ()
+ unloadObjs :: LinkableWithUsage -> IO ()
unloadObjs lnk
| interpreterDynamic interp = return ()
-- We don't do any cleanup when linking objects with the
@@ -1133,7 +1135,7 @@ unload_wkr interp pls@LoaderState{..} = do
-- not much benefit.
| otherwise
- = mapM_ (unloadObj interp) (linkableObjs lnk)
+ = mapM_ (unloadObj interp) (linkableUsageObjs lnk)
-- The components of a BCO linkable may contain
-- dot-o files (generated from C stubs).
--
=====================================
compiler/GHC/Linker/Types.hs
=====================================
@@ -49,6 +49,7 @@ module GHC.Linker.Types
, WholeCoreBindingsLinkable
, LinkableWith(..)
, mkModuleByteCodeLinkable
+ , mkOnlyModuleByteCodeLinkable
, LinkablePart(..)
, LinkableObjectSort (..)
, linkableIsNativeCodeOnly
@@ -67,12 +68,17 @@ module GHC.Linker.Types
, linkableFilterNative
, partitionLinkables
+ , LinkableWithUsage
+ , linkableUsageObjs
+ , mkLinkablesUsage
+ , mkLinkableUsage
+
, ModuleByteCode(..)
)
where
import GHC.Prelude
-import GHC.Unit ( UnitId, Module )
+import GHC.Unit ( UnitId, Module, moduleNameString, moduleName )
import GHC.ByteCode.Types
import GHCi.BreakArray
import GHCi.RemoteTypes
@@ -97,6 +103,11 @@ import Data.List.NonEmpty (NonEmpty, nonEmpty)
import qualified Data.List.NonEmpty as NE
import Control.Applicative ((<|>))
import Data.Functor.Identity
+import GHC.Unit.Module.Deps (LinkableUsage (..), linkableUsageObjectPaths)
+import GHC.Fingerprint (Fingerprint)
+import qualified GHC.Data.OsPath as OsPath
+import qualified GHC.Data.FlatBag as FlatBag
+import Control.DeepSeq (NFData(..))
{- **********************************************************************
@@ -172,10 +183,10 @@ data LoaderState = LoaderState
-- ^ Information about bytecode objects we have loaded into the
-- interpreter.
- , bcos_loaded :: !LinkableSet
+ , bcos_loaded :: !(LinkableSet LinkableWithUsage)
-- ^ The currently loaded interpreted modules (home package)
- , objs_loaded :: !LinkableSet
+ , objs_loaded :: !(LinkableSet LinkableWithUsage)
-- ^ And the currently-loaded compiled modules (home package)
, pkgs_loaded :: !PkgsLoaded
@@ -380,19 +391,25 @@ data LinkableWith parts = Linkable
-- ^ Files and chunks of code to link.
} deriving (Functor, Traversable, Foldable)
+instance NFData a => NFData (LinkableWith a) where
+ rnf Linkable{linkableTime,linkableModule,linkableParts} =
+ rnf linkableTime `seq` rnf linkableModule `seq` rnf linkableParts `seq` ()
+
type Linkable = LinkableWith (NonEmpty LinkablePart)
type WholeCoreBindingsLinkable = LinkableWith WholeCoreBindings
-type LinkableSet = ModuleEnv Linkable
+type LinkableWithUsage = LinkableWith (NonEmpty LinkableUsage)
+
+type LinkableSet = ModuleEnv
-mkLinkableSet :: [Linkable] -> LinkableSet
+mkLinkableSet :: [Linkable] -> LinkableSet Linkable
mkLinkableSet ls = mkModuleEnv [(linkableModule l, l) | l <- ls]
-- | Union of LinkableSets.
--
-- In case of conflict, keep the most recent Linkable (as per linkableTime)
-unionLinkableSet :: LinkableSet -> LinkableSet -> LinkableSet
+unionLinkableSet :: LinkableSet (LinkableWith a) -> LinkableSet (LinkableWith a) -> LinkableSet (LinkableWith a)
unionLinkableSet = plusModuleEnv_C go
where
go l1 l2
@@ -435,8 +452,9 @@ data LinkablePart
| DotDLL FilePath
-- ^ Dynamically linked library file (.so, .dll, .dylib)
- | DotGBC ModuleByteCode
- -- ^ A byte-code object, lives only in memory.
+ | DotGBC
+ -- ^ A byte-code object, lives only in memory.
+ ModuleByteCode
-- | The in-memory representation of a bytecode object
@@ -444,14 +462,19 @@ data LinkablePart
data ModuleByteCode = ModuleByteCode { gbc_module :: Module
, gbc_compiled_byte_code :: CompiledByteCode
, gbc_foreign_files :: [FilePath] -- ^ Path to object files
+ , gbc_hash :: !Fingerprint
}
mkModuleByteCodeLinkable :: UTCTime -> ModuleByteCode -> Linkable
-mkModuleByteCodeLinkable linkable_time bco =
+mkModuleByteCodeLinkable linkable_time bco = do
Linkable linkable_time (gbc_module bco) (pure (DotGBC bco))
+mkOnlyModuleByteCodeLinkable :: UTCTime -> ModuleByteCode -> LinkableWith ModuleByteCode
+mkOnlyModuleByteCodeLinkable linkable_time bco = do
+ Linkable linkable_time (gbc_module bco) bco
+
instance Outputable ModuleByteCode where
- ppr (ModuleByteCode mod _cbc _fos) = text "ModuleByteCode" <+> ppr mod
+ ppr (ModuleByteCode mod _cbc _fos _) = text "ModuleByteCode" <+> ppr mod
instance Outputable LinkablePart where
ppr (DotO path sort) = text "DotO" <+> text path <+> pprSort sort
@@ -544,8 +567,8 @@ linkablePartObjectPaths = \case
-- Contrary to linkableBCOs, this includes byte-code from LazyBCOs.
linkablePartBCOs :: LinkablePart -> [CompiledByteCode]
linkablePartBCOs = \case
- DotGBC bco -> [gbc_compiled_byte_code bco]
- _ -> []
+ DotGBC bco -> [gbc_compiled_byte_code bco]
+ _ -> []
linkableFilter :: (LinkablePart -> [LinkablePart]) -> Linkable -> Maybe Linkable
linkableFilter f linkable = do
@@ -586,6 +609,48 @@ partitionLinkables linkables =
mapMaybe linkableFilterByteCode linkables
)
+
+mkLinkableUsage :: Linkable -> LinkableWithUsage
+mkLinkableUsage linkables = do
+ linkableUsage linkables
+ where
+ msg m = moduleNameString (moduleName m) ++ "[TH] changed"
+
+ linkableUsage lnk@Linkable{linkableParts} =
+ setLinkableParts lnk linkableParts
+
+ mkFileLinkableUsage m fp objs =
+ FileLinkableUsage
+ { flu_file = fp
+ , flu_message = Just $ msg m
+ , flu_linkable_objs = FlatBag.fromList (strictGenericLength objs) [ OsPath.unsafeEncodeUtf obj | obj <- objs ]
+ }
+
+ mkByteCodeLinkableUsage m fp objs =
+ ByteCodeLinkableUsage
+ { bclu_module = m
+ , bclu_hash = fp
+ , bclu_linkable_objs = FlatBag.fromList (strictGenericLength objs) [ OsPath.unsafeEncodeUtf obj | obj <- objs ]
+ }
+
+ setLinkableParts lnk@(Linkable{linkableModule}) parts =
+ lnk
+ { linkableParts = fmap (go linkableModule) parts
+ }
+
+ go :: Module -> LinkablePart -> LinkableUsage
+ go m lnkPart = case lnkPart of
+ DotO fn _ -> mkFileLinkableUsage m fn (linkablePartObjectPaths lnkPart)
+ DotA fn -> mkFileLinkableUsage m fn (linkablePartObjectPaths lnkPart)
+ DotDLL fn -> mkFileLinkableUsage m fn (linkablePartObjectPaths lnkPart)
+ DotGBC mbc -> mkByteCodeLinkableUsage m (gbc_hash mbc) (linkablePartObjectPaths lnkPart)
+
+mkLinkablesUsage :: [Linkable] -> [LinkableWithUsage]
+mkLinkablesUsage linkables = map mkLinkableUsage linkables
+
+linkableUsageObjs :: LinkableWithUsage -> [FilePath]
+linkableUsageObjs lnkWithUsage = concatMap linkableUsageObjectPaths (linkableParts lnkWithUsage)
+
{- **********************************************************************
Loading packages
=====================================
compiler/GHC/Runtime/Loader.hs
=====================================
@@ -153,7 +153,7 @@ initializePlugins hsc_env
([] , _ ) -> False -- some external plugin added
(p:ps,s:ss) -> check_external_plugin p s && check_external_plugins ps ss
-loadPlugins :: HscEnv -> IO ([LoadedPlugin], [Linkable], PkgsLoaded)
+loadPlugins :: HscEnv -> IO ([LoadedPlugin], [LinkableWithUsage], PkgsLoaded)
loadPlugins hsc_env
= do { unless (null to_load) $
checkExternalInterpreter hsc_env
@@ -173,7 +173,7 @@ loadPlugins hsc_env
loadPlugin = loadPlugin' (mkVarOccFS (fsLit "plugin")) pluginTyConName hsc_env
-loadFrontendPlugin :: HscEnv -> ModuleName -> IO (FrontendPlugin, [Linkable], PkgsLoaded)
+loadFrontendPlugin :: HscEnv -> ModuleName -> IO (FrontendPlugin, [LinkableWithUsage], PkgsLoaded)
loadFrontendPlugin hsc_env mod_name = do
checkExternalInterpreter hsc_env
(plugin, _iface, links, pkgs)
@@ -188,7 +188,7 @@ checkExternalInterpreter hsc_env = case interpInstance <$> hsc_interp hsc_env of
-> throwIO (InstallationError "Plugins require -fno-external-interpreter")
_ -> pure ()
-loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [Linkable], PkgsLoaded)
+loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [LinkableWithUsage], PkgsLoaded)
loadPlugin' occ_name plugin_name hsc_env mod_name
= do { let plugin_rdr_name = mkRdrQual mod_name occ_name
dflags = hsc_dflags hsc_env
@@ -266,7 +266,7 @@ forceLoadTyCon hsc_env con_name = do
-- * If the Name does not exist in the module
-- * If the link failed
-getValueSafely :: HscEnv -> Name -> Type -> IO (Either Type (a, [Linkable], PkgsLoaded))
+getValueSafely :: HscEnv -> Name -> Type -> IO (Either Type (a, [LinkableWithUsage], PkgsLoaded))
getValueSafely hsc_env val_name expected_type = do
eith_hval <- case getValueSafelyHook hooks of
Nothing -> getHValueSafely interp hsc_env val_name expected_type
@@ -281,7 +281,7 @@ getValueSafely hsc_env val_name expected_type = do
logger = hsc_logger hsc_env
hooks = hsc_hooks hsc_env
-getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Either Type (HValue, [Linkable], PkgsLoaded))
+getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Either Type (HValue, [LinkableWithUsage], PkgsLoaded))
getHValueSafely interp hsc_env val_name expected_type = do
forceLoadNameModuleInterface hsc_env (text "contains a name used in an invocation of getHValueSafely") val_name
-- Now look up the names for the value and type constructor in the type environment
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -562,7 +562,7 @@ data TcGblEnv
-- is implicit rather than explicit, so we have to zap a
-- mutable variable.
- tcg_th_needed_deps :: TcRef ([Linkable], PkgsLoaded),
+ tcg_th_needed_deps :: TcRef ([LinkableWithUsage], PkgsLoaded),
-- ^ The set of runtime dependencies required by this module
-- See Note [Object File Dependencies]
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -2259,7 +2259,7 @@ fillCoercionHole (CH { ch_ref = ref, ch_co_var = cv }) co
recordThUse :: TcM ()
recordThUse = do { env <- getGblEnv; writeTcRef (tcg_th_used env) True }
-recordThNeededRuntimeDeps :: [Linkable] -> PkgsLoaded -> TcM ()
+recordThNeededRuntimeDeps :: [LinkableWithUsage] -> PkgsLoaded -> TcM ()
recordThNeededRuntimeDeps new_links new_pkgs
= do { env <- getGblEnv
; updTcRef (tcg_th_needed_deps env) $ \(needed_links, needed_pkgs) ->
=====================================
compiler/GHC/Unit/Home/ModInfo.hs
=====================================
@@ -3,9 +3,11 @@
module GHC.Unit.Home.ModInfo
(
HomeModInfo (..)
- , HomeModLinkable (..)
, homeModInfoObject
, homeModInfoByteCode
+ , HomeModLinkable (..)
+ , homeModLinkableByteCode
+ , homeModLinkableObject
, emptyHomeModInfoLinkable
)
where
@@ -15,9 +17,10 @@ import GHC.Prelude
import GHC.Unit.Module.ModIface
import GHC.Unit.Module.ModDetails
-import GHC.Linker.Types ( Linkable )
+import GHC.Linker.Types ( Linkable, LinkableWith, ModuleByteCode, LinkablePart (..) )
import GHC.Utils.Outputable
+import qualified Data.List.NonEmpty as NE
-- | Information about modules in the package being compiled
data HomeModInfo = HomeModInfo
@@ -48,18 +51,24 @@ data HomeModInfo = HomeModInfo
}
homeModInfoByteCode :: HomeModInfo -> Maybe Linkable
-homeModInfoByteCode = homeMod_bytecode . hm_linkable
+homeModInfoByteCode = homeModLinkableByteCode . hm_linkable
homeModInfoObject :: HomeModInfo -> Maybe Linkable
-homeModInfoObject = homeMod_object . hm_linkable
+homeModInfoObject = homeModLinkableObject . hm_linkable
emptyHomeModInfoLinkable :: HomeModLinkable
emptyHomeModInfoLinkable = HomeModLinkable Nothing Nothing
-- See Note [Home module build products]
-data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe Linkable)
+data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe (LinkableWith ModuleByteCode))
, homeMod_object :: !(Maybe Linkable) }
+homeModLinkableByteCode :: HomeModLinkable -> Maybe Linkable
+homeModLinkableByteCode = fmap (fmap (NE.singleton . DotGBC)) . homeMod_bytecode
+
+homeModLinkableObject :: HomeModLinkable -> Maybe Linkable
+homeModLinkableObject = homeMod_object
+
instance Outputable HomeModLinkable where
ppr (HomeModLinkable l1 l2) = ppr l1 $$ ppr l2
=====================================
compiler/GHC/Unit/Module/Deps.hs
=====================================
@@ -22,6 +22,10 @@ module GHC.Unit.Module.Deps
, ImportAvails (..)
, IfaceImportLevel(..)
, tcImportLevel
+ , LinkableUsage(..)
+ , linkableUsageObjectPaths
+ , noLinkableUsage
+ , combineLinkableUsage
)
where
@@ -49,7 +53,10 @@ import qualified Data.Set as Set
import Data.Bifunctor
import Control.DeepSeq
import GHC.Types.Name.Set
-
+import GHC.ByteCode.Types (FlatBag)
+import GHC.Data.OsPath
+import qualified Data.Foldable as Foldable
+import qualified GHC.Data.OsPath as OsPath
-- | Dependency information about ALL modules and packages below this one
@@ -372,12 +379,12 @@ data Usage
-- we won't spot it here. If you do want to spot that, the caller
-- should recursively add them to their useage.
}
- | UsageHomeModuleInterface {
+ | UsageHomeModuleBytecode {
usg_mod_name :: ModuleName
-- ^ Name of the module
, usg_unit_id :: UnitId
-- ^ UnitId of the HomeUnit the module is from
- , usg_iface_hash :: Fingerprint
+ , usg_bytecode_hash :: Fingerprint
-- ^ The *interface* hash of the module, not the ABI hash.
-- This changes when anything about the interface (and hence the
-- module) has changed.
@@ -412,7 +419,7 @@ instance NFData Usage where
rnf (UsageFile file hash label) = rnf file `seq` rnf hash `seq` rnf label `seq` ()
rnf (UsageDirectory dir hash label) = rnf dir `seq` rnf hash `seq` rnf label `seq` ()
rnf (UsageMergedRequirement mod hash) = rnf mod `seq` rnf hash `seq` ()
- rnf (UsageHomeModuleInterface mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
+ rnf (UsageHomeModuleBytecode mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
instance Binary Usage where
put_ bh usg@UsagePackageModule{} = do
@@ -441,11 +448,11 @@ instance Binary Usage where
put_ bh (usg_mod usg)
put_ bh (usg_mod_hash usg)
- put_ bh usg@UsageHomeModuleInterface{} = do
+ put_ bh usg@UsageHomeModuleBytecode{} = do
putByte bh 4
put_ bh (usg_mod_name usg)
put_ bh (usg_unit_id usg)
- put_ bh (usg_iface_hash usg)
+ put_ bh (usg_bytecode_hash usg)
put_ bh usg@UsageDirectory{} = do
putByte bh 5
@@ -483,7 +490,7 @@ instance Binary Usage where
mod <- get bh
uid <- get bh
hash <- get bh
- return UsageHomeModuleInterface { usg_mod_name = mod, usg_unit_id = uid, usg_iface_hash = hash }
+ return UsageHomeModuleBytecode { usg_mod_name = mod, usg_unit_id = uid, usg_bytecode_hash = hash }
5 -> do
dp <- get bh
hash <- get bh
@@ -695,3 +702,41 @@ data ImportAvails
-- ^ Family instance modules below us in the import tree (and maybe
-- including us for imported modules)
}
+
+data LinkableUsage
+ = FileLinkableUsage
+ { flu_file :: !FilePath
+ , flu_message :: !(Maybe String)
+ , flu_linkable_objs :: !(FlatBag OsPath)
+ }
+ | ByteCodeLinkableUsage
+ { bclu_module :: !Module
+ , bclu_hash :: !Fingerprint
+ , bclu_linkable_objs :: !(FlatBag OsPath)
+ }
+
+instance Outputable LinkableUsage where
+ ppr = \ case
+ FileLinkableUsage fp mmsg _objs ->
+ text "FileLinkableUsage" <+> text fp <> maybe empty (\ msg -> text " " <> text msg) mmsg
+ ByteCodeLinkableUsage modl hash _objs ->
+ text "ByteCodeLinkableUsage" <+> ppr modl <+> ppr hash
+
+instance NFData LinkableUsage where
+ rnf FileLinkableUsage{} = ()
+ rnf ByteCodeLinkableUsage{} = ()
+
+linkableUsageObjectPaths :: LinkableUsage -> [FilePath]
+linkableUsageObjectPaths lnkUsage =
+ map OsPath.unsafeDecodeUtf . Foldable.toList $ linkableUsageObjectOsPaths lnkUsage
+
+linkableUsageObjectOsPaths :: LinkableUsage -> FlatBag OsPath
+linkableUsageObjectOsPaths lnkUsage = case lnkUsage of
+ FileLinkableUsage{flu_linkable_objs} -> flu_linkable_objs
+ ByteCodeLinkableUsage{bclu_linkable_objs} -> bclu_linkable_objs
+
+noLinkableUsage :: [LinkableUsage]
+noLinkableUsage = []
+
+combineLinkableUsage :: [LinkableUsage] -> [LinkableUsage] -> [LinkableUsage]
+combineLinkableUsage a b = a ++ b
=====================================
compiler/GHC/Unit/Module/Status.hs
=====================================
@@ -18,7 +18,7 @@ import GHC.Unit.Home.ModInfo
import GHC.Unit.Module.ModGuts
import GHC.Unit.Module.ModIface
-import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly )
+import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly, ModuleByteCode, LinkableWith, linkableBCOs, linkableModuleByteCodes )
import GHC.Utils.Fingerprint
import GHC.Utils.Outputable
@@ -59,7 +59,7 @@ data RecompLinkables = RecompLinkables { recompLinkables_bytecode :: !RecompByte
, recompLinkables_object :: !(Maybe Linkable) }
data RecompBytecodeLinkable
- = NormalLinkable !(Maybe Linkable)
+ = NormalLinkable !(Maybe (LinkableWith ModuleByteCode))
| WholeCoreBindingsLinkable !WholeCoreBindingsLinkable
instance Outputable HscRecompStatus where
@@ -87,7 +87,8 @@ justBytecode :: Either Linkable WholeCoreBindingsLinkable -> RecompLinkables
justBytecode = \case
Left lm ->
assertPpr (not (linkableIsNativeCodeOnly lm)) (ppr lm)
- $ emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just lm) }
+ $ assertPpr (length (linkableBCOs lm) == 1) (text "Expected 1 DotGBC linkable" $$ ppr lm )
+ $ emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just (head (linkableModuleByteCodes lm) <$ lm)) }
Right lm -> emptyRecompLinkables { recompLinkables_bytecode = WholeCoreBindingsLinkable lm }
justObjects :: Linkable -> RecompLinkables
@@ -99,7 +100,8 @@ bytecodeAndObjects :: Either Linkable WholeCoreBindingsLinkable -> Linkable -> R
bytecodeAndObjects either_bc o = case either_bc of
Left bc ->
assertPpr (not (linkableIsNativeCodeOnly bc) && linkableIsNativeCodeOnly o) (ppr bc $$ ppr o)
- $ RecompLinkables (NormalLinkable (Just bc)) (Just o)
+ $ assertPpr (length (linkableBCOs bc) == 1) (text "Expected 1 DotGBC linkable" $$ ppr bc )
+ $ RecompLinkables (NormalLinkable (Just (head (linkableModuleByteCodes bc) <$ bc))) (Just o)
Right bc ->
assertPpr (linkableIsNativeCodeOnly o) (ppr o)
$ RecompLinkables (WholeCoreBindingsLinkable bc) (Just o)
=====================================
compiler/GHC/Utils/Binary.hs
=====================================
@@ -37,6 +37,7 @@ module GHC.Utils.Binary
tellBinWriter,
castBin,
withBinBuffer,
+ withReadBinBuffer,
freezeWriteHandle,
shrinkBinBuffer,
thawReadHandle,
@@ -349,6 +350,12 @@ withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do
arr <- readIORef arr_r
action $ BS.fromForeignPtr arr 0 ix
+-- | Get access to the underlying buffer.
+withReadBinBuffer :: ReadBinHandle -> (ByteString -> IO a) -> IO a
+withReadBinBuffer (ReadBinMem _ ix_r _ arr) action = do
+ ix <- readFastMutInt ix_r
+ action $ BS.fromForeignPtr arr 0 ix
+
unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle
unsafeUnpackBinBuffer (BS.BS arr len) = do
ix_r <- newFastMutInt 0
=====================================
ghc/GHCi/Leak.hs
=====================================
@@ -52,8 +52,11 @@ getLeakIndicators hsc_env =
return $ LeakModIndicators{..}
where
mkWeakLinkables :: HomeModLinkable -> IO [Maybe (Weak Linkable)]
- mkWeakLinkables (HomeModLinkable mbc mo) =
- mapM (\ln -> traverse (flip mkWeakPtr Nothing <=< evaluate) ln) [mbc, mo]
+ mkWeakLinkables hml =
+ mapM (\ln -> traverse (flip mkWeakPtr Nothing <=< evaluate) ln)
+ [ homeModLinkableByteCode hml
+ , homeModLinkableObject hml
+ ]
-- | Look at the LeakIndicators collected by an earlier call to
-- `getLeakIndicators`, and print messasges if any of them are still
=====================================
testsuite/ghc-config/ghc-config
=====================================
Binary files /dev/null and b/testsuite/ghc-config/ghc-config differ
=====================================
testsuite/tests/bytecode/TLinkable/Makefile
=====================================
@@ -0,0 +1,30 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+.PHONY: TLinkable_Prep
+TLinkable_Prep:
+ ./genSplices TLinkable
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -fprefer-byte-code -v0 TLinkable.hs
+
+.PHONY: TLinkable2_Prep
+TLinkable2_Prep:
+ ./genSplices TLinkable2
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -fprefer-byte-code -fwrite-byte-code -v0 TLinkable2.hs
+
+.PHONY: linkable_bytecodelib_Prep linkable_bytecodelib
+PKGCONF01=bytecode.package.conf
+LOCAL_GHC_PKG01='$(GHC_PKG)' --no-user-package-db -f $(PKGCONF01)
+MAIN_MOD=BytecodeUsage
+linkable_bytecodelib_Prep:
+ $(LOCAL_GHC_PKG01) init $(PKGCONF01)
+ mkdir outdir
+ cd outdir && ../genSplices2 $(MAIN_MOD) 50 500
+ mv outdir/$(MAIN_MOD).hs $(MAIN_MOD).hs
+ cd outdir && $(TEST_HC) -bytecodelib -hisuf=$(ghciWayExt) $(ghciWayFlags) \
+ -o testpkg-1.2.3.4-XXX.bytecodelib -fbyte-code -fwrite-interface -fwrite-byte-code -this-unit-id=testpkg-1.2.3.4-XXX \
+ *.hs
+ $(LOCAL_GHC_PKG01) register --force outdir/bytecode.pkg
+
+linkable_bytecodelib:
+ $(TEST_HC) $(TEST_HC_OPTS) $(ghcThWayFlags) --make -fprefer-byte-code $(MAIN_MOD) -package testpkg -package-db $(PKGCONF01) +RTS -l -hT -i0.001 -RTS
=====================================
testsuite/tests/bytecode/TLinkable/all.T
=====================================
@@ -0,0 +1,34 @@
+# Test ideas
+# Bytecode libraries
+# Depend on that bytecode, look at the bytecode library tests to make sure this ends up in the EPS
+
+def normaliseDynlibNames(str):
+ return re.sub(r'-ghc[0-9.]+\.', '-ghc<VERSION>.', str)
+
+test('TLinkable',
+ [ collect_compiler_stats('bytes allocated',2),
+ pre_cmd('$MAKE -s --no-print-directory TLinkable_Prep'),
+ extra_files(['genSplices']),
+ compile_timeout_multiplier(5),
+ ],
+ compile,
+ ['-fprefer-byte-code -fforce-recomp ' + config.ghc_th_way_flags])
+
+test('TLinkable2',
+ [ collect_compiler_stats('bytes allocated',2),
+ pre_cmd('$MAKE -s --no-print-directory TLinkable2_Prep'),
+ extra_files(['genSplices']),
+ compile_timeout_multiplier(5),
+ ],
+ compile,
+ ['-fprefer-byte-code -fforce-recomp ' + config.ghc_th_way_flags])
+
+test('linkable_bytecodelib',
+ [ extra_files(["genSplices2"])
+ , when(have_profiling(), extra_ways(['prof']))
+ , normalise_errmsg_fun(normaliseDynlibNames)
+ , pre_cmd('$MAKE -s --no-print-directory linkable_bytecodelib_Prep')
+ , copy_files
+ , req_bco ],
+ makefile_test,
+ [])
=====================================
testsuite/tests/bytecode/TLinkable/genSplices
=====================================
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# Generate NMOD Haskell modules, each with NDEF NOINLINE functions
+# Usage: ./genSplices <MODNAME> <NMOD> <NDEF>
+
+MODNAME=${1}
+NMOD=${2:-20} # Default 20 modules
+NDEF=${3:-50} # Default 50 functions per module
+
+# Generate the modules
+for ((i=1; i<=NMOD; i++)); do
+ module_name="Module$(printf "%03d" $i)"
+ file_path="${module_name}.hs"
+
+ cat > "$file_path" << EOF
+module ${module_name} where
+
+EOF
+
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ cat >> "$file_path" << EOF
+{-# NOINLINE ${func_name} #-}
+${func_name} :: Int -> Int
+${func_name} x = x + ${j}
+
+EOF
+ done
+done
+
+# Generate imports section
+imports=""
+for ((i=1; i<=NMOD; i++)); do
+ imports="${imports}import splice Module$(printf "%03d" $i)
+"
+done
+
+# Generate the hard-coded TH expression
+# Build: Module001.func001 1 + Module001.func002 2 + ... + Module{NMOD}.func{NDEF} {NMOD*NDEF}
+expression=""
+count=1
+for ((i=1; i<=NMOD; i++)); do
+ mod_name="Module$(printf "%03d" $i)"
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ if [ $count -gt 1 ]; then
+ expression="${expression} + "
+ fi
+ expression="${expression}${mod_name}.${func_name} ${count}"
+ ((count++))
+ done
+done
+
+# Generate the TH splice file
+cat > "${MODNAME}".hs << EOF
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE NumericUnderscores #-}
+{-# LANGUAGE ExplicitLevelImports #-}
+
+module ${MODNAME} where
+
+import splice Language.Haskell.TH.Syntax (Lift(..))
+import Control.Concurrent (threadDelay)
+import splice Prelude (Num(..), ($), Monad(..), pure)
+
+-- Import all generated modules
+${imports}
+-- Hard-coded splice that references ALL functions from ALL modules
+result :: Int
+result = \$(lift \$ ${expression})
+
+result_test :: IO Int
+result_test = \$( [| threadDelay 1_000_000 >> pure 50 |] )
+
+main :: IO ()
+main = do
+ putStrLn \$ "Result: " ++ show result
+ putStrLn . ("Other result: " ++) . show =<< result_test
+EOF
=====================================
testsuite/tests/bytecode/TLinkable/genSplices2
=====================================
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+MODNAME=${1}
+NMOD=${2:-20} # Default 20 modules
+NDEF=${3:-50} # Default 50 functions per module
+
+# Generate the modules
+for ((i=1; i<=NMOD; i++)); do
+ module_name="Module$(printf "%03d" $i)"
+ file_path="${module_name}.hs"
+
+ cat > "$file_path" << EOF
+module ${module_name} where
+
+EOF
+
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ cat >> "$file_path" << EOF
+{-# NOINLINE ${func_name} #-}
+${func_name} :: Int -> Int
+${func_name} x = x + ${j}
+
+EOF
+ done
+done
+
+# Generate imports section
+imports=""
+for ((i=1; i<=NMOD; i++)); do
+ imports="${imports}import splice Module$(printf "%03d" $i)
+"
+done
+
+# Generate the hard-coded TH expression
+# Build: Module001.func001 1 + Module001.func002 2 + ... + Module{NMOD}.func{NDEF} {NMOD*NDEF}
+expressions=""
+all_mods=""
+for ((i=1; i<=NMOD; i++)); do
+ mod_name="Module$(printf "%03d" $i)"
+ all_mods="${all_mods} ${mod_name}"
+ single_expression=""
+ count=1
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ if [ $count -gt 1 ]; then
+ single_expression="${single_expression} + "
+ fi
+ single_expression="${single_expression}${mod_name}.${func_name} ${count}"
+ ((count++))
+ done
+
+ expressions="comp$(printf "%03d" $i) = \$(lift \$ ${single_expression})\\n\\n${expressions}"
+done
+
+# Generate the TH splice file
+cat > bytecode.pkg << EOF
+name: testpkg
+version: 1.2.3.4
+id: testpkg-1.2.3.4-XXX
+key: testpkg-1.2.3.4-XXX
+license: BSD3
+copyright: (c) The Univsersity of Glasgow 2004
+maintainer: glasgow-haskell-users(a)haskell.org
+stability: stable
+homepage: http://www.haskell.org/ghc
+package-url: http://www.haskell.org/ghc
+description: A Test Package
+category: none
+author: simonmar(a)microsoft.com
+exposed: True
+exposed-modules: ${all_mods}
+import-dirs: \${pkgroot}/outdir
+library-dirs: \${pkgroot}/outdir
+include-dirs:
+bytecode-library-dirs: \${pkgroot}/outdir
+hs-libraries: testpkg-1.2.3.4-XXX
+EOF
+
+# Generate the TH splice file
+cat > "${MODNAME}".hs << EOF
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE NumericUnderscores #-}
+{-# LANGUAGE ExplicitLevelImports #-}
+
+module ${MODNAME} where
+
+import splice Language.Haskell.TH.Syntax (Lift(..))
+import Control.Concurrent (threadDelay)
+import splice Prelude (Num(..), ($), Monad(..), pure)
+
+-- Import all generated modules
+${imports}
+
+-- Use from each module
+$(echo -e -n "${expressions}")
+
+EOF
=====================================
testsuite/tests/bytecode/TLinkable/linkable_bytecodelib.stdout
=====================================
@@ -0,0 +1 @@
+[1 of 1] Compiling BytecodeUsage ( BytecodeUsage.hs, BytecodeUsage.o )
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcdba7cde905a3f4758132b038c0f9…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcdba7cde905a3f4758132b038c0f9…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/control-monad-zip-to-base] Move the implementation of `Control.Monad.Zip` to `base`
by Wolfgang Jeltsch (@jeltsch) 18 Feb '26
by Wolfgang Jeltsch (@jeltsch) 18 Feb '26
18 Feb '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/control-monad-zip-to-base at Glasgow Haskell Compiler / GHC
Commits:
02490385 by Wolfgang Jeltsch at 2026-02-18T16:53:00+02:00
Move the implementation of `Control.Monad.Zip` to `base`
- - - - -
7 changed files:
- libraries/base/src/Control/Monad/Zip.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.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
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
Changes:
=====================================
libraries/base/src/Control/Monad/Zip.hs
=====================================
@@ -18,4 +18,127 @@
module Control.Monad.Zip ( MonadZip(..) ) where
-import GHC.Internal.Control.Monad.Zip(MonadZip(..))
+import GHC.Internal.Control.Monad (liftM, liftM2, Monad(..))
+import GHC.Internal.Data.Functor.Identity
+import qualified GHC.Internal.Data.Functor
+import GHC.Internal.Data.Monoid
+import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
+import GHC.Internal.Data.Ord ( Down(..) )
+import GHC.Internal.Data.Proxy
+--import qualified Data.List.NonEmpty as NE
+import GHC.Internal.Generics
+import qualified GHC.Internal.Data.List.NonEmpty as NE
+import qualified GHC.Internal.Data.List as List
+import GHC.Internal.Data.Maybe
+import GHC.Internal.Data.Tuple
+--import Prelude
+
+-- | Instances should satisfy the laws:
+--
+-- [Naturality]
+--
+-- @'liftM' (f 'Control.Arrow.***' g) ('mzip' ma mb)
+-- = 'mzip' ('liftM' f ma) ('liftM' g mb)@
+--
+-- [Information Preservation]
+--
+-- @'liftM' ('Prelude.const' ()) ma = 'liftM' ('Prelude.const' ()) mb@
+-- implies
+-- @'munzip' ('mzip' ma mb) = (ma, mb)@
+--
+class Monad m => MonadZip m where
+ {-# MINIMAL mzip | mzipWith #-}
+
+ mzip :: m a -> m b -> m (a,b)
+ mzip = mzipWith (,)
+
+ mzipWith :: (a -> b -> c) -> m a -> m b -> m c
+ mzipWith f ma mb = liftM (uncurry f) (mzip ma mb)
+
+ munzip :: m (a,b) -> (m a, m b)
+ munzip mab = (liftM fst mab, liftM snd mab)
+ -- munzip is a member of the class because sometimes
+ -- you can implement it more efficiently than the
+ -- above default code. See #4370 comment by giorgidze
+
+-- | @since 4.3.1.0
+instance MonadZip [] where
+ mzip = List.zip
+ mzipWith = List.zipWith
+ munzip = List.unzip
+
+-- | @since 4.9.0.0
+instance MonadZip NonEmpty where
+ mzip = NE.zip
+ mzipWith = NE.zipWith
+ munzip = GHC.Internal.Data.Functor.unzip
+
+-- | @since 4.8.0.0
+instance MonadZip Identity where
+ mzipWith = liftM2
+ munzip (Identity (a, b)) = (Identity a, Identity b)
+
+-- | @since 4.15.0.0
+instance MonadZip Solo where
+ mzipWith = liftM2
+ munzip (MkSolo (a, b)) = (MkSolo a, MkSolo b)
+
+-- | @since 4.8.0.0
+instance MonadZip Dual where
+ -- Cannot use coerce, it's unsafe
+ mzipWith = liftM2
+
+-- | @since 4.8.0.0
+instance MonadZip Sum where
+ mzipWith = liftM2
+
+-- | @since 4.8.0.0
+instance MonadZip Product where
+ mzipWith = liftM2
+
+-- | @since 4.8.0.0
+instance MonadZip Maybe where
+ mzipWith = liftM2
+
+-- | @since 4.8.0.0
+instance MonadZip First where
+ mzipWith = liftM2
+
+-- | @since 4.8.0.0
+instance MonadZip Last where
+ mzipWith = liftM2
+
+-- | @since 4.8.0.0
+instance MonadZip f => MonadZip (Alt f) where
+ mzipWith f (Alt ma) (Alt mb) = Alt (mzipWith f ma mb)
+
+-- | @since 4.9.0.0
+instance MonadZip Proxy where
+ mzipWith _ _ _ = Proxy
+
+-- Instances for GHC.Generics
+-- | @since 4.9.0.0
+instance MonadZip U1 where
+ mzipWith _ _ _ = U1
+
+-- | @since 4.9.0.0
+instance MonadZip Par1 where
+ mzipWith = liftM2
+
+-- | @since 4.9.0.0
+instance MonadZip f => MonadZip (Rec1 f) where
+ mzipWith f (Rec1 fa) (Rec1 fb) = Rec1 (mzipWith f fa fb)
+
+-- | @since 4.9.0.0
+instance MonadZip f => MonadZip (M1 i c f) where
+ mzipWith f (M1 fa) (M1 fb) = M1 (mzipWith f fa fb)
+
+-- | @since 4.9.0.0
+instance (MonadZip f, MonadZip g) => MonadZip (f :*: g) where
+ mzipWith f (x1 :*: y1) (x2 :*: y2) = mzipWith f x1 x2 :*: mzipWith f y1 y2
+
+-- instances for GHC.Internal.Data.Ord
+
+-- | @since 4.12.0.0
+instance MonadZip Down where
+ mzipWith = liftM2
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -135,7 +135,6 @@ Library
GHC.Internal.Control.Monad.Fix
GHC.Internal.Control.Monad.IO.Class
GHC.Internal.Control.Monad.ST
- GHC.Internal.Control.Monad.Zip
GHC.Internal.Control.Monad.ST.Lazy
GHC.Internal.Control.Monad.ST.Imp
GHC.Internal.Control.Monad.ST.Lazy.Imp
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs deleted
=====================================
@@ -1,144 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE TypeOperators #-}
-
------------------------------------------------------------------------------
--- |
--- Module : Control.Monad.Zip
--- Copyright : (c) Nils Schweinsberg 2011,
--- (c) George Giorgidze 2011
--- (c) University Tuebingen 2011
--- License : BSD-style (see the file libraries/base/LICENSE)
--- Maintainer : libraries(a)haskell.org
--- Stability : stable
--- Portability : portable
---
--- Monadic zipping (used for monad comprehensions)
---
------------------------------------------------------------------------------
-
-module GHC.Internal.Control.Monad.Zip ( MonadZip(..) ) where
-
-import GHC.Internal.Control.Monad (liftM, liftM2, Monad(..))
-import GHC.Internal.Data.Functor.Identity
-import qualified GHC.Internal.Data.Functor
-import GHC.Internal.Data.Monoid
-import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
-import GHC.Internal.Data.Ord ( Down(..) )
-import GHC.Internal.Data.Proxy
---import qualified Data.List.NonEmpty as NE
-import GHC.Internal.Generics
-import qualified GHC.Internal.Data.List.NonEmpty as NE
-import qualified GHC.Internal.Data.List as List
-import GHC.Internal.Data.Maybe
-import GHC.Internal.Data.Tuple
---import Prelude
-
--- | Instances should satisfy the laws:
---
--- [Naturality]
---
--- @'liftM' (f 'Control.Arrow.***' g) ('mzip' ma mb)
--- = 'mzip' ('liftM' f ma) ('liftM' g mb)@
---
--- [Information Preservation]
---
--- @'liftM' ('Prelude.const' ()) ma = 'liftM' ('Prelude.const' ()) mb@
--- implies
--- @'munzip' ('mzip' ma mb) = (ma, mb)@
---
-class Monad m => MonadZip m where
- {-# MINIMAL mzip | mzipWith #-}
-
- mzip :: m a -> m b -> m (a,b)
- mzip = mzipWith (,)
-
- mzipWith :: (a -> b -> c) -> m a -> m b -> m c
- mzipWith f ma mb = liftM (uncurry f) (mzip ma mb)
-
- munzip :: m (a,b) -> (m a, m b)
- munzip mab = (liftM fst mab, liftM snd mab)
- -- munzip is a member of the class because sometimes
- -- you can implement it more efficiently than the
- -- above default code. See #4370 comment by giorgidze
-
--- | @since 4.3.1.0
-instance MonadZip [] where
- mzip = List.zip
- mzipWith = List.zipWith
- munzip = List.unzip
-
--- | @since 4.9.0.0
-instance MonadZip NonEmpty where
- mzip = NE.zip
- mzipWith = NE.zipWith
- munzip = GHC.Internal.Data.Functor.unzip
-
--- | @since 4.8.0.0
-instance MonadZip Identity where
- mzipWith = liftM2
- munzip (Identity (a, b)) = (Identity a, Identity b)
-
--- | @since 4.15.0.0
-instance MonadZip Solo where
- mzipWith = liftM2
- munzip (MkSolo (a, b)) = (MkSolo a, MkSolo b)
-
--- | @since 4.8.0.0
-instance MonadZip Dual where
- -- Cannot use coerce, it's unsafe
- mzipWith = liftM2
-
--- | @since 4.8.0.0
-instance MonadZip Sum where
- mzipWith = liftM2
-
--- | @since 4.8.0.0
-instance MonadZip Product where
- mzipWith = liftM2
-
--- | @since 4.8.0.0
-instance MonadZip Maybe where
- mzipWith = liftM2
-
--- | @since 4.8.0.0
-instance MonadZip First where
- mzipWith = liftM2
-
--- | @since 4.8.0.0
-instance MonadZip Last where
- mzipWith = liftM2
-
--- | @since 4.8.0.0
-instance MonadZip f => MonadZip (Alt f) where
- mzipWith f (Alt ma) (Alt mb) = Alt (mzipWith f ma mb)
-
--- | @since 4.9.0.0
-instance MonadZip Proxy where
- mzipWith _ _ _ = Proxy
-
--- Instances for GHC.Generics
--- | @since 4.9.0.0
-instance MonadZip U1 where
- mzipWith _ _ _ = U1
-
--- | @since 4.9.0.0
-instance MonadZip Par1 where
- mzipWith = liftM2
-
--- | @since 4.9.0.0
-instance MonadZip f => MonadZip (Rec1 f) where
- mzipWith f (Rec1 fa) (Rec1 fb) = Rec1 (mzipWith f fa fb)
-
--- | @since 4.9.0.0
-instance MonadZip f => MonadZip (M1 i c f) where
- mzipWith f (M1 fa) (M1 fb) = M1 (mzipWith f fa fb)
-
--- | @since 4.9.0.0
-instance (MonadZip f, MonadZip g) => MonadZip (f :*: g) where
- mzipWith f (x1 :*: y1) (x2 :*: y2) = mzipWith f x1 x2 :*: mzipWith f y1 y2
-
--- instances for GHC.Internal.Data.Ord
-
--- | @since 4.12.0.0
-instance MonadZip Down where
- mzipWith = liftM2
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -10532,6 +10532,26 @@ module Unsafe.Coerce where
-- Instances:
+instance forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip [] -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Solo -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
+instance [safe] forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Functor.Const.Const -- Defined in ‘Data.Bifoldable’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Either.Either -- Defined in ‘Data.Bifoldable’
instance [safe] forall i. Data.Bifoldable.Bifoldable (GHC.Internal.Generics.K1 i) -- Defined in ‘Data.Bifoldable’
@@ -11574,26 +11594,6 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Last -- Defined
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Max -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Min -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.IO.Class.MonadIO GHC.Internal.Types.IO -- Defined in ‘GHC.Internal.Control.Monad.IO.Class’
-instance forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip [] -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Solo -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
-instance [safe] forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance forall (a :: * -> * -> *) b c. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’
instance forall (m :: * -> *) a. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’
instance GHC.Internal.Data.Data.Data Data.Array.Byte.ByteArray -- Defined in ‘Data.Array.Byte’
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -10570,6 +10570,26 @@ module Unsafe.Coerce where
-- Instances:
+instance forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip [] -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Solo -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
+instance [safe] forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Functor.Const.Const -- Defined in ‘Data.Bifoldable’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Either.Either -- Defined in ‘Data.Bifoldable’
instance [safe] forall i. Data.Bifoldable.Bifoldable (GHC.Internal.Generics.K1 i) -- Defined in ‘Data.Bifoldable’
@@ -11601,26 +11621,6 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Last -- Defined
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Max -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Min -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.IO.Class.MonadIO GHC.Internal.Types.IO -- Defined in ‘GHC.Internal.Control.Monad.IO.Class’
-instance forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip [] -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Solo -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
-instance [safe] forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance forall (a :: * -> * -> *) b c. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’
instance forall (m :: * -> *) a. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’
instance GHC.Internal.Data.Data.Data Data.Array.Byte.ByteArray -- Defined in ‘Data.Array.Byte’
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -10794,6 +10794,26 @@ module Unsafe.Coerce where
-- Instances:
+instance forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip [] -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Solo -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
+instance [safe] forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Functor.Const.Const -- Defined in ‘Data.Bifoldable’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Either.Either -- Defined in ‘Data.Bifoldable’
instance [safe] forall i. Data.Bifoldable.Bifoldable (GHC.Internal.Generics.K1 i) -- Defined in ‘Data.Bifoldable’
@@ -11832,26 +11852,6 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Last -- Defined
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Max -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Min -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.IO.Class.MonadIO GHC.Internal.Types.IO -- Defined in ‘GHC.Internal.Control.Monad.IO.Class’
-instance forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip [] -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Solo -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
-instance [safe] forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance forall (a :: * -> * -> *) b c. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’
instance forall (m :: * -> *) a. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’
instance GHC.Internal.Data.Data.Data Data.Array.Byte.ByteArray -- Defined in ‘Data.Array.Byte’
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -10532,6 +10532,26 @@ module Unsafe.Coerce where
-- Instances:
+instance forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip [] -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘Control.Monad.Zip’
+instance forall (f :: * -> *). Control.Monad.Zip.MonadZip f => Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Solo -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘Control.Monad.Zip’
+instance Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
+instance [safe] forall (f :: * -> *) (g :: * -> *). (Control.Monad.Zip.MonadZip f, Control.Monad.Zip.MonadZip g) => Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Functor.Const.Const -- Defined in ‘Data.Bifoldable’
instance [safe] Data.Bifoldable.Bifoldable GHC.Internal.Data.Either.Either -- Defined in ‘Data.Bifoldable’
instance [safe] forall i. Data.Bifoldable.Bifoldable (GHC.Internal.Generics.K1 i) -- Defined in ‘Data.Bifoldable’
@@ -11574,26 +11594,6 @@ instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Last -- Defined
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Max -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Semigroup.Min -- Defined in ‘Data.Semigroup’
instance GHC.Internal.Control.Monad.IO.Class.MonadIO GHC.Internal.Types.IO -- Defined in ‘GHC.Internal.Control.Monad.IO.Class’
-instance forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (f GHC.Internal.Generics.:*: g) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Data.Semigroup.Internal.Alt f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Ord.Down -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.First -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Monoid.Last -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip [] -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *) i (c :: GHC.Internal.Generics.Meta). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.M1 i c f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.Par1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Proxy.Proxy -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance forall (f :: * -> *). GHC.Internal.Control.Monad.Zip.MonadZip f => GHC.Internal.Control.Monad.Zip.MonadZip (GHC.Internal.Generics.Rec1 f) -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Solo -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip GHC.Internal.Generics.U1 -- Defined in ‘GHC.Internal.Control.Monad.Zip’
-instance GHC.Internal.Control.Monad.Zip.MonadZip Data.Complex.Complex -- Defined in ‘Data.Complex’
-instance [safe] forall (f :: * -> *) (g :: * -> *). (GHC.Internal.Control.Monad.Zip.MonadZip f, GHC.Internal.Control.Monad.Zip.MonadZip g) => GHC.Internal.Control.Monad.Zip.MonadZip (Data.Functor.Product.Product f g) -- Defined in ‘Data.Functor.Product’
instance forall (a :: * -> * -> *) b c. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable b, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable c, GHC.Internal.Data.Data.Data (a b c)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedArrow a b c) -- Defined in ‘Control.Applicative’
instance forall (m :: * -> *) a. (ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable m, ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a, GHC.Internal.Data.Data.Data (m a)) => GHC.Internal.Data.Data.Data (Control.Applicative.WrappedMonad m a) -- Defined in ‘Control.Applicative’
instance GHC.Internal.Data.Data.Data Data.Array.Byte.ByteArray -- Defined in ‘Data.Array.Byte’
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0249038508def6edcc5a2e79d471f5e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0249038508def6edcc5a2e79d471f5e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/duplex-readability-and-writability] 15 commits: Fix subtle bug in cast worker/wrapper
by Wolfgang Jeltsch (@jeltsch) 18 Feb '26
by Wolfgang Jeltsch (@jeltsch) 18 Feb '26
18 Feb '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/duplex-readability-and-writability at Glasgow Haskell Compiler / GHC
Commits:
99d8c146 by Simon Peyton Jones at 2026-02-12T17:36:59+00:00
Fix subtle bug in cast worker/wrapper
See (CWw4) in Note [Cast worker/wrapper].
The true payload is in the change to the definition of
GHC.Types.Id.Info.hasInlineUnfolding
Everthing else is just documentation.
There is a 2% compile time decrease for T13056;
I'll take the win!
Metric Decrease:
T13056
- - - - -
530e8e58 by Simon Peyton Jones at 2026-02-12T20:17:23-05:00
Add regression tests for four StaticPtr bugs
Tickets #26545, #24464, #24773, #16981 are all solved by the
recently-landed MR
commit 318ee13bcffa6aa8df42ba442ccd92aa0f7e210c
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Oct 20 23:07:20 2025 +0100
Simplify the treatment of static forms
This MR just adds regression tests for them.
- - - - -
4157160f by Cheng Shao at 2026-02-13T06:27:04-05:00
ci: remove unused hlint-ghc-and-base job definition
This patch removes the unused `hlint-ghc-and-base` job definition,
it's never run since !9806. Note that hadrian lint rules still work
locally, so anyone that wishes to run hlint on the codebase can
continue to do so in their local worktree.
- - - - -
039f1977 by Cheng Shao at 2026-02-13T06:27:47-05:00
wasm: use import.meta.main for proper distinction of nodejs main modules
This patch uses `import.meta.main` for proper distinction of nodejs
main modules, especially when the main module might be installed as a
symlink. Fixes #26916.
- - - - -
14f485ee by ARATA Mizuki at 2026-02-17T09:09:24+09:00
Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
Also, mark AVX-512 ER and PF as deprecated.
AVX-512 instructions can be used for certain 64-bit integer vector operations.
GFNI can be used to implement bitReverse (currently not used by NCG, but LLVM may use it).
Closes #26406
Addresses #26509
- - - - -
016f79d5 by fendor at 2026-02-17T09:16:16-05:00
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
- - - - -
4f2840f2 by Brian J. Cardiff at 2026-02-17T17:04:08-05:00
configure: Accept happy-2.2
In Jan 2026 happy-2.2 was released. The most sensible change is https://github.com/haskell/happy/issues/335 which didn't trigger in a fresh build
- - - - -
10b4d364 by Duncan Coutts at 2026-02-17T17:04:52-05:00
Fix errors in the documentation of the eventlog STOP_THREAD status codes
Fix the code for BlockedOnMsgThrowTo.
Document all the known historical warts.
Fixes issue #26867
- - - - -
c5e15b8b by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: use snippets for all list examples
- generate snippet output for docs
- reduce font size to better fit snippets
- Use only directive to guard html snippets
- Add latex snippets for lists
- - - - -
d388bac1 by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: Place the snippet input and output together
- Put the output seemingly inside the example box
- - - - -
016fa306 by Samuel Thibault at 2026-02-18T05:08:35-05:00
Fix linking against libm by moving the -lm option
For those systems that need -lm for getting math functions, this is
currently added on the link line very early, before the object files being
linked together. Newer toolchains enable --as-needed by default, which means
-lm is ignored at that point because no object requires a math function
yet. With such toolchains, we thus have to add -lm after the objects, so the
linker actually includes libm in the link.
- - - - -
68bd0805 by Teo Camarasu at 2026-02-18T05:09:19-05:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
77342519 by Wolfgang Jeltsch at 2026-02-18T15:42:21+02:00
Correct `hIsReadable` and `hIsWritable` for duplex handles
This contribution implements CLC proposal #371. It changes `hIsReadable`
and `hIsWritable` such that they always throw a respective exception
when encountering a closed or semi-closed handle, not just in the case
of a file handle.
- - - - -
6682c7d3 by Wolfgang Jeltsch at 2026-02-18T15:42:25+02:00
Document `SemiClosedHandle`
- - - - -
6df86909 by Wolfgang Jeltsch at 2026-02-18T15:42:25+02:00
Tell users what “semi-closed” means for duplex handles
- - - - -
130 changed files:
- .gitlab-ci.yml
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/Types/Id/Info.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/phases.rst
- docs/users_guide/using.rst
- libraries/base/changelog.md
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Exts.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- m4/fptools_happy.m4
- testsuite/driver/cpu_features.py
- testsuite/tests/arrows/should_compile/T21301.stderr
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.hs
- testsuite/tests/deSugar/should_fail/DsStrictFail.stderr
- testsuite/tests/deSugar/should_run/T20024.stderr
- testsuite/tests/deSugar/should_run/dsrun005.stderr
- testsuite/tests/deSugar/should_run/dsrun007.stderr
- testsuite/tests/deSugar/should_run/dsrun008.stderr
- testsuite/tests/deriving/should_run/T9576.stderr
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/patsyn/should_run/ghci.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- + testsuite/tests/rename/should_fail/T26545.hs
- + testsuite/tests/rename/should_fail/T26545.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simplCore/should_compile/T26903.hs
- + testsuite/tests/simplCore/should_compile/T26903.stderr
- testsuite/tests/simplCore/should_compile/T8331.stderr
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- + testsuite/tests/typecheck/should_compile/T24464.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- + testsuite/tests/typecheck/should_run/T16981.hs
- + testsuite/tests/typecheck/should_run/T16981.stdout
- + testsuite/tests/typecheck/should_run/T24773.hs
- + testsuite/tests/typecheck/should_run/T24773.stdout
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/typecheck/should_run/all.T
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- utils/haddock/doc/.gitignore
- utils/haddock/doc/Makefile
- + utils/haddock/doc/_static/haddock-custom.css
- utils/haddock/doc/conf.py
- utils/haddock/doc/markup.rst
- + utils/haddock/doc/snippets/.gitignore
- + utils/haddock/doc/snippets/Lists.hs
- + utils/haddock/doc/snippets/Makefile
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.html
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
- + utils/haddock/doc/snippets/Snippet-List-Definition.html
- + utils/haddock/doc/snippets/Snippet-List-Definition.tex
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.html
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
- + utils/haddock/doc/snippets/Snippet-List-Indentation.html
- + utils/haddock/doc/snippets/Snippet-List-Indentation.tex
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
- utils/haddock/html-test/ref/A.html
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1033.html
- utils/haddock/html-test/ref/Bug1103.html
- utils/haddock/html-test/ref/Bug548.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/FunArgs.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Instances.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/RedactTypeSynonyms.html
- utils/haddock/html-test/ref/T23616.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
- utils/jsffi/dyld.mjs
- utils/jsffi/post-link.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/628441f417d7c2f5bedc7be3ab5e81…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/628441f417d7c2f5bedc7be3ab5e81…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/linkable-usage] 2 commits: Add bytecode linkable regression test
by Hannes Siebenhandl (@fendor) 18 Feb '26
by Hannes Siebenhandl (@fendor) 18 Feb '26
18 Feb '26
Hannes Siebenhandl pushed to branch wip/fendor/linkable-usage at Glasgow Haskell Compiler / GHC
Commits:
708fdb9b by fendor at 2026-02-18T14:21:00+01:00
Add bytecode linkable regression test
- - - - -
fcdba7cd by fendor at 2026-02-18T14:21:00+01:00
WIP: LinkableUsage
- - - - -
26 changed files:
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Driver/Hooks.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Linker/ByteCode.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Unit/Home/ModInfo.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Utils/Binary.hs
- ghc/GHCi/Leak.hs
- + testsuite/ghc-config/ghc-config
- + testsuite/tests/bytecode/TLinkable/Makefile
- + testsuite/tests/bytecode/TLinkable/all.T
- + testsuite/tests/bytecode/TLinkable/genSplices
- + testsuite/tests/bytecode/TLinkable/genSplices2
- + testsuite/tests/bytecode/TLinkable/linkable_bytecodelib.stdout
Changes:
=====================================
compiler/GHC/ByteCode/Serialize.hs
=====================================
@@ -14,6 +14,7 @@ module GHC.ByteCode.Serialize
, InterpreterLibraryContents(..)
, writeBytecodeLib
, readBytecodeLib
+ , fingerprintModuleByteCodeContents
, decodeOnDiskModuleByteCode
, decodeOnDiskBytecodeLib
)
@@ -48,6 +49,7 @@ import GHC.Utils.Logger
import GHC.Linker.Types
import System.IO.Unsafe (unsafeInterleaveIO)
import GHC.Utils.Outputable
+import GHC.Utils.Fingerprint (Fingerprint, fingerprintByteString)
{- Note [Overview of persistent bytecode]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -94,6 +96,7 @@ See Note [Recompilation avoidance with bytecode objects]
-- contained by 'ModuleByteCode' are stored in-memory rather than as file paths to
-- temporary files.
data OnDiskModuleByteCode = OnDiskModuleByteCode { odgbc_module :: Module
+ , odgbc_hash :: Fingerprint
, odgbc_compiled_byte_code :: CompiledByteCode
, odgbc_foreign :: [ByteString] -- ^ Contents of object files
}
@@ -154,7 +157,6 @@ instance Binary OnDiskBytecodeLib where
put_ bh bytecodeLibForeign
-
writeBytecodeLib :: BytecodeLib -> FilePath -> IO ()
writeBytecodeLib lib path = do
odbco <- encodeBytecodeLib lib
@@ -174,12 +176,14 @@ readBytecodeLib hsc_env path = do
instance Binary OnDiskModuleByteCode where
get bh = do
odgbc_module <- get bh
+ odgbc_hash <- get bh
odgbc_compiled_byte_code <- get bh
odgbc_foreign <- get bh
pure OnDiskModuleByteCode {..}
put_ bh OnDiskModuleByteCode {..} = do
put_ bh odgbc_module
+ put_ bh odgbc_hash
put_ bh odgbc_compiled_byte_code
put_ bh odgbc_foreign
@@ -197,7 +201,8 @@ decodeOnDiskModuleByteCode hsc_env odbco = do
pure $ ModuleByteCode {
gbc_module = odgbc_module odbco,
gbc_compiled_byte_code = odgbc_compiled_byte_code odbco,
- gbc_foreign_files = foreign_files
+ gbc_foreign_files = foreign_files,
+ gbc_hash = odgbc_hash odbco
}
decodeOnDiskBytecodeLib :: HscEnv -> OnDiskBytecodeLib -> IO BytecodeLib
@@ -256,7 +261,8 @@ encodeOnDiskModuleByteCode bco = do
pure $ OnDiskModuleByteCode {
odgbc_module = gbc_module bco,
odgbc_compiled_byte_code = gbc_compiled_byte_code bco,
- odgbc_foreign = foreign_contents
+ odgbc_foreign = foreign_contents,
+ odgbc_hash = gbc_hash bco
}
-- | Read a 'ModuleByteCode' from a file.
@@ -281,6 +287,15 @@ writeBinByteCode f cbc = do
putWithUserData QuietBinIFace NormalCompression bh odbco
writeBinMem bh f
+fingerprintModuleByteCodeContents :: Module -> CompiledByteCode -> [FilePath] -> IO Fingerprint
+fingerprintModuleByteCodeContents modl cbc foreign_files = do
+ bh' <- openBinMem (1024 * 1024)
+ bh <- addBinNameWriter bh'
+ foreign_contents <- readObjectFiles foreign_files
+ putWithUserData QuietBinIFace NormalCompression bh
+ (modl, cbc, foreign_contents)
+ withBinBuffer bh (pure . fingerprintByteString)
+
instance Binary CompiledByteCode where
get bh = do
bc_bcos <- get bh
=====================================
compiler/GHC/Driver/Hooks.hs
=====================================
@@ -137,7 +137,7 @@ data Hooks = Hooks
, tcForeignExportsHook :: !(Maybe ([LForeignDecl GhcRn]
-> TcM (LHsBinds GhcTc, [LForeignDecl GhcTc], Bag GlobalRdrElt)))
, hscFrontendHook :: !(Maybe (ModSummary -> Hsc FrontendResult))
- , hscCompileCoreExprHook :: !(Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)))
+ , hscCompileCoreExprHook :: !(Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)))
, ghcPrimIfaceHook :: !(Maybe ModIface)
, runPhaseHook :: !(Maybe PhaseHook)
, runMetaHook :: !(Maybe (MetaHook TcM))
@@ -145,7 +145,7 @@ data Hooks = Hooks
-> HomePackageTable -> IO SuccessFlag))
, runRnSpliceHook :: !(Maybe (HsUntypedSplice GhcRn -> RnM (HsUntypedSplice GhcRn)))
, getValueSafelyHook :: !(Maybe (HscEnv -> Name -> Type
- -> IO (Either Type (HValue, [Linkable], PkgsLoaded))))
+ -> IO (Either Type (HValue, [LinkableWithUsage], PkgsLoaded))))
, createIservProcessHook :: !(Maybe (CreateProcess -> IO ProcessHandle))
, stgToCmmHook :: !(Maybe (StgToCmmConfig -> InfoTableProvMap -> [TyCon] -> CollectedCCs
-> [CgStgTopBinding] -> CgStream CmmGroup ModuleLFInfos))
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -866,7 +866,7 @@ hscRecompStatus
| otherwise -> do
-- Check the status of all the linkable types we might need.
-- 1. The in-memory linkable we had at hand.
- bc_in_memory_linkable <- checkByteCodeInMemory hsc_env mod_summary (homeMod_bytecode old_linkable)
+ bc_in_memory_linkable <- checkByteCodeInMemory hsc_env mod_summary (homeModLinkableByteCode old_linkable)
-- 2. The bytecode object file
bc_obj_linkable <- checkByteCodeFromObject hsc_env mod_summary
-- 3. Bytecode from an interface's whole core bindings.
@@ -1098,7 +1098,7 @@ loadIfaceByteCodeLazy ::
ModIface ->
ModLocation ->
TypeEnv ->
- IO (Maybe Linkable)
+ IO (Maybe (LinkableWith ModuleByteCode))
loadIfaceByteCodeLazy hsc_env iface location type_env =
case iface_core_bindings iface location of
Nothing -> return Nothing
@@ -1106,8 +1106,9 @@ loadIfaceByteCodeLazy hsc_env iface location type_env =
Just <$> compile wcb
where
compile decls = do
- bco <- unsafeInterleaveIO $ compileWholeCoreBindings hsc_env type_env decls
- linkable $ NE.singleton (DotGBC bco)
+ bco <- unsafeInterleaveIO $ do
+ compileWholeCoreBindings hsc_env type_env decls
+ linkable bco
linkable parts = do
if_time <- modificationTimeIfExists (ml_hi_file_ospath location)
@@ -1148,14 +1149,14 @@ initWholeCoreBindings hsc_env iface details (RecompLinkables bc o) = do
where
type_env = md_types details
- go :: RecompBytecodeLinkable -> IO (Maybe Linkable)
+ go :: RecompBytecodeLinkable -> IO (Maybe (LinkableWith ModuleByteCode))
go (NormalLinkable l) = pure l
go (WholeCoreBindingsLinkable wcbl) =
fmap Just $ for wcbl $ \wcb -> do
add_iface_to_hpt iface details hsc_env
- bco <- unsafeInterleaveIO $
- compileWholeCoreBindings hsc_env type_env wcb
- pure $ NE.singleton (DotGBC bco)
+ bco <- unsafeInterleaveIO $ do
+ compileWholeCoreBindings hsc_env type_env wcb
+ pure bco
-- | Hydrate interface Core bindings and compile them to bytecode.
--
@@ -2232,20 +2233,21 @@ make user's opt into writing the files.
-}
-- | Generate a 'ModuleByteCode' and write it to disk if `-fwrite-byte-code` is enabled.
-generateAndWriteByteCodeLinkable :: HscEnv -> CgInteractiveGuts -> ModLocation -> IO Linkable
+generateAndWriteByteCodeLinkable :: HscEnv -> CgInteractiveGuts -> ModLocation -> IO (LinkableWith ModuleByteCode)
generateAndWriteByteCodeLinkable hsc_env cgguts mod_location = do
bco_object <- generateAndWriteByteCode hsc_env cgguts mod_location
-- Either, get the same time as the .gbc file if it exists, or just the current time.
-- It's important the time of the linkable matches the time of the .gbc file for recompilation
-- checking.
bco_time <- maybe getCurrentTime pure =<< modificationTimeIfExists (ml_bytecode_file_ospath mod_location)
- return $ mkModuleByteCodeLinkable bco_time bco_object
+ return $ mkOnlyModuleByteCodeLinkable bco_time bco_object
mkModuleByteCode :: HscEnv -> Module -> ModLocation -> CgInteractiveGuts -> IO ModuleByteCode
mkModuleByteCode hsc_env mod mod_location cgguts = do
bcos <- hscGenerateByteCode hsc_env cgguts mod_location
objs <- outputAndCompileForeign hsc_env mod mod_location (cgi_foreign_files cgguts) (cgi_foreign cgguts)
- return $! ModuleByteCode mod bcos objs
+ !bcos_hash <- fingerprintModuleByteCodeContents mod bcos objs
+ return $! ModuleByteCode mod bcos objs bcos_hash
-- | Generate a fresh 'ModuleByteCode' for a given module but do not write it to disk.
generateFreshByteCodeLinkable :: HscEnv
@@ -2767,13 +2769,13 @@ hscTidy hsc_env guts = do
%* *
%********************************************************************* -}
-hscCompileCoreExpr :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+hscCompileCoreExpr :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
hscCompileCoreExpr hsc_env loc expr =
case hscCompileCoreExprHook (hsc_hooks hsc_env) of
Nothing -> hscCompileCoreExpr' hsc_env loc expr
Just h -> h hsc_env loc expr
-hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+hscCompileCoreExpr' :: HscEnv -> SrcSpan -> CoreExpr -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
hscCompileCoreExpr' hsc_env srcspan ds_expr = do
{- Simplify it -}
-- Question: should we call SimpleOpt.simpleOptExpr here instead?
@@ -2859,8 +2861,10 @@ hscCompileCoreExpr' hsc_env srcspan ds_expr = do
{- load it -}
bco_time <- getCurrentTime
+ !bco_hash <- fingerprintModuleByteCodeContents this_mod bcos []
+ let mbc = ModuleByteCode this_mod bcos [] bco_hash
(mods_needed, units_needed) <- loadDecls interp hsc_env srcspan $
- Linkable bco_time this_mod $ NE.singleton $ DotGBC (ModuleByteCode this_mod bcos [])
+ Linkable bco_time this_mod $ NE.singleton (DotGBC mbc)
-- Get the foreign reference to the name we should have just loaded.
mhvs <- lookupFromLoadedEnv interp (idName binding_id)
{- Get the HValue for the root -}
@@ -2876,7 +2880,7 @@ jsCodeGen
-> Module
-> [(CgStgTopBinding,IdSet)]
-> Id
- -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+ -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id = do
let logger = hsc_logger hsc_env
tmpfs = hsc_tmpfs hsc_env
=====================================
compiler/GHC/Driver/Pipeline.hs
=====================================
@@ -430,7 +430,7 @@ link' hsc_env batch_attempt_linking mHscMessager hpt
let obj_files = concatMap linkableObjs linkables
in action obj_files
linkBytecodeLinkable action =
- checkLinkablesUpToDate hsc_env mHscMessager home_mods pkg_deps staticLink checkBytecodeLibraryLinkingNeeded homeMod_bytecode $ \linkables ->
+ checkLinkablesUpToDate hsc_env mHscMessager home_mods pkg_deps staticLink checkBytecodeLibraryLinkingNeeded homeModLinkableByteCode $ \linkables ->
let bytecode = concatMap linkableModuleByteCodes linkables
in action bytecode
=====================================
compiler/GHC/Driver/Plugins.hs
=====================================
@@ -342,7 +342,7 @@ data Plugins = Plugins
-- The purpose of this field is to cache the plugins so they
-- don't have to be loaded each time they are needed. See
-- 'GHC.Runtime.Loader.initializePlugins'.
- , loadedPluginDeps :: !([Linkable], PkgsLoaded)
+ , loadedPluginDeps :: !([LinkableWithUsage], PkgsLoaded)
-- ^ The object files required by the loaded plugins
-- See Note [Plugin dependencies]
}
=====================================
compiler/GHC/HsToCore/Usage.hs
=====================================
@@ -7,8 +7,6 @@ module GHC.HsToCore.Usage (
import GHC.Prelude
-import GHC.Driver.Env
-
import GHC.Tc.Types
import GHC.Iface.Load
@@ -27,7 +25,6 @@ import GHC.Types.Unique.Set
import GHC.Unit
import GHC.Unit.Env
-import GHC.Unit.External
import GHC.Unit.Module.Imported
import GHC.Unit.Module.ModIface
import GHC.Unit.Module.Deps
@@ -35,18 +32,17 @@ import GHC.Unit.Module.Deps
import GHC.Data.Maybe
import GHC.Data.FastString
-import Data.IORef
import Data.List (sortBy)
import Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set
-import qualified Data.List.NonEmpty as NE
import GHC.Linker.Types
import GHC.Unit.Finder
import GHC.Types.Unique.DFM
import GHC.Driver.Plugins
import qualified GHC.Unit.Home.Graph as HUG
+import qualified Data.List.NonEmpty as NE
{- Note [Module self-dependency]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -75,19 +71,17 @@ data UsageConfig = UsageConfig
mkUsageInfo :: UsageConfig -> Plugins -> FinderCache -> UnitEnv
-> Module -> ImportedMods -> [ImportUserSpec] -> NameSet
- -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [Linkable] -> PkgsLoaded
+ -> [FilePath] -> [FilePath] -> [(Module, Fingerprint)] -> [LinkableWithUsage] -> PkgsLoaded
-> IfG [Usage]
mkUsageInfo uc plugins fc unit_env
this_mod dir_imp_mods imp_decls used_names
dependent_files dependent_dirs merged needed_links needed_pkgs
= do
- eps <- liftIO $ readIORef (euc_eps (ue_eps unit_env))
file_hashes <- liftIO $ mapM getFileHash dependent_files
dirs_hashes <- liftIO $ mapM getDirHash dependent_dirs
let hu = ue_unsafeHomeUnit unit_env
- hug = ue_home_unit_graph unit_env
-- Dependencies on object files due to TH and plugins
- object_usages <- liftIO $ mkObjectUsage (eps_PIT eps) plugins fc hug needed_links needed_pkgs
+ object_usages <- liftIO $ mkObjectUsage plugins fc needed_links needed_pkgs
let all_home_ids = HUG.allUnits (ue_home_unit_graph unit_env)
mod_usages <- mk_mod_usage_info uc hu all_home_ids this_mod
dir_imp_mods imp_decls used_names
@@ -190,31 +184,31 @@ for a module or not. This is similar to how the recompilation checking for the l
-- | Find object files corresponding to the transitive closure of given home
-- modules and direct object files for pkg dependencies
-mkObjectUsage :: PackageIfaceTable -> Plugins -> FinderCache -> HomeUnitGraph-> [Linkable] -> PkgsLoaded -> IO [Usage]
-mkObjectUsage pit plugins fc hug th_links_needed th_pkgs_needed = do
- let ls = ordNubOn linkableModule (th_links_needed ++ plugins_links_needed)
+mkObjectUsage :: Plugins -> FinderCache -> [LinkableWithUsage] -> PkgsLoaded -> IO [Usage]
+mkObjectUsage plugins fc th_links_needed th_pkgs_needed = do
+ let ls = th_links_needed ++ plugins_links_needed
ds = concatMap loaded_pkg_hs_objs $ eltsUDFM (plusUDFM th_pkgs_needed plugin_pkgs_needed) -- TODO possibly record loaded_pkg_non_hs_objs as well
(plugins_links_needed, plugin_pkgs_needed) = loadedPluginDeps plugins
concat <$> sequence (map linkableToUsage ls ++ map librarySpecToUsage ds)
where
- linkableToUsage (Linkable _ m uls) = mapM (partToUsage m) (NE.toList uls)
-
- msg m = moduleNameString (moduleName m) ++ "[TH] changed"
+ linkableToUsage :: LinkableWithUsage -> IO [Usage]
+ linkableToUsage (Linkable _ _m parts) = traverse partToUsage (NE.toList parts)
+
+ partToUsage link_usage =
+ case link_usage of
+ FileLinkableUsage{flu_file, flu_message} -> do
+ fing flu_message flu_file
+
+ ByteCodeLinkableUsage{bclu_module, bclu_hash} ->
+ pure $
+ UsageHomeModuleBytecode
+ { usg_mod_name = moduleName bclu_module
+ , usg_unit_id = toUnitId $ moduleUnit bclu_module
+ , usg_bytecode_hash = bclu_hash
+ }
fing mmsg fn = UsageFile (mkFastString fn) <$> lookupFileCache fc fn <*> pure mmsg
- partToUsage m part =
- case linkablePartPath part of
- Just fn -> fing (Just (msg m)) fn
- Nothing -> do
- -- This should only happen for home package things but oneshot puts
- -- home package ifaces in the PIT.
- miface <- lookupIfaceByModule hug pit m
- case miface of
- Nothing -> pprPanic "linkableToUsage" (ppr m)
- Just iface ->
- return $ UsageHomeModuleInterface (moduleName m) (toUnitId $ moduleUnit m) (mi_iface_hash iface)
-
librarySpecToUsage :: LibrarySpec -> IO [Usage]
librarySpecToUsage (Objects os) = traverse (fing Nothing) os
librarySpecToUsage (Archive fn) = traverse (fing Nothing) [fn]
=====================================
compiler/GHC/Iface/Recomp.hs
=====================================
@@ -88,6 +88,10 @@ import GHC.Iface.Errors.Ppr
import Data.Functor
import Data.Bifunctor (first)
import GHC.Types.PkgQual
+import GHC.ByteCode.Serialize (ModuleByteCode, gbc_hash)
+import GHC.Unit.Home.Graph (lookupHugByModule)
+import GHC.Unit.Home.ModInfo (HomeModLinkable(..), HomeModInfo (..))
+import GHC.Linker.Types (linkableParts)
{-
-----------------------------------------------
@@ -190,6 +194,7 @@ data RecompReason
| ModuleAdded (ImportLevel, UnitId, ModuleName)
| ModuleChangedRaw ModuleName
| ModuleChangedIface ModuleName
+ | ModuleChangedBytecode ModuleName
| FileChanged FilePath
| DirChanged FilePath
| CustomReason String
@@ -224,7 +229,8 @@ instance Outputable RecompReason where
SigsMergeChanged -> text "Signatures to merge in changed"
ModuleChanged m -> ppr m <+> text "changed"
ModuleChangedRaw m -> ppr m <+> text "changed (raw)"
- ModuleChangedIface m -> ppr m <+> text "changed (interface)"
+ ModuleChangedIface m -> ppr m <+> text "changed (bytecode)"
+ ModuleChangedBytecode m -> ppr m <+> text "changed (interface)"
ModuleRemoved (_st, _uid, m) -> ppr m <+> text "removed"
ModuleAdded (_st, _uid, m) -> ppr m <+> text "added"
FileChanged fp -> text fp <+> text "changed"
@@ -718,6 +724,15 @@ needInterface mod continue
Nothing -> return $ NeedsRecompile MustCompile
Just iface -> liftIO $ continue iface
+needBytecode :: Module -> (ModuleByteCode -> IO RecompileRequired)
+ -> IfG RecompileRequired
+needBytecode mod continue
+ = do
+ mb_recomp <- tryGetBytecode mod
+ case mb_recomp of
+ Nothing -> return $ NeedsRecompile MustCompile
+ Just mbc -> liftIO $ continue mbc
+
tryGetModIface :: String -> Module -> IfG (Maybe ModIface)
tryGetModIface doc_msg mod
= do -- Load the imported interface if possible
@@ -739,6 +754,27 @@ tryGetModIface doc_msg mod
-- import and it's been deleted
Succeeded iface -> pure $ Just iface
+tryGetBytecode :: Module -> IfG (Maybe ModuleByteCode)
+tryGetBytecode mod
+ = do -- Load the imported bytecode if possible
+ logger <- getLogger
+ liftIO $ trace_hi_diffs logger (text "Checking bytecode hash for module" <+> ppr mod <+> ppr (moduleUnit mod))
+
+ mb_module_bytecode <- do
+ env <- getTopEnv
+ liftIO (lookupHugByModule mod (hsc_HUG env)) >>= \ case
+ Nothing -> pure Nothing
+ Just hmi ->
+ case homeMod_bytecode (hm_linkable hmi) of
+ Nothing -> pure Nothing
+ Just gbc_linkable -> pure $ Just $ linkableParts gbc_linkable
+
+ case mb_module_bytecode of
+ Nothing -> do
+ liftIO $ trace_hi_diffs logger (sep [text "Couldn't find bytecode for module", ppr mod])
+ return Nothing
+ Just module_bytecode -> pure $ Just module_bytecode
+
-- | Given the usage information extracted from the old
-- M.hi file for the module being compiled, figure out
-- whether M needs to be recompiled.
@@ -760,14 +796,14 @@ checkModUsage _ UsageMergedRequirement{ usg_mod = mod, usg_mod_hash = old_mod_ha
needInterface mod $ \iface -> do
let reason = ModuleChangedRaw (moduleName mod)
checkModuleFingerprint logger reason old_mod_hash (mi_mod_hash iface)
-checkModUsage _ UsageHomeModuleInterface{ usg_mod_name = mod_name
+checkModUsage _ UsageHomeModuleBytecode{ usg_mod_name = mod_name
, usg_unit_id = uid
- , usg_iface_hash = old_mod_hash } = do
+ , usg_bytecode_hash = old_bytecode_hash } = do
let mod = mkModule (RealUnit (Definite uid)) mod_name
logger <- getLogger
- needInterface mod $ \iface -> do
- let reason = ModuleChangedIface mod_name
- checkIfaceFingerprint logger reason old_mod_hash (mi_iface_hash iface)
+ needBytecode mod $ \cbc -> do
+ let reason = ModuleChangedBytecode mod_name
+ checkBytecodeFingerprint logger reason old_bytecode_hash (gbc_hash cbc)
checkModUsage _ UsageHomeModule{
usg_mod_name = mod_name,
@@ -1032,19 +1068,18 @@ checkModuleFingerprint logger reason old_mod_hash new_mod_hash
= out_of_date_hash logger reason (text " Module fingerprint has changed")
old_mod_hash new_mod_hash
-checkIfaceFingerprint
+checkBytecodeFingerprint
:: Logger
-> RecompReason
-> Fingerprint
-> Fingerprint
-> IO RecompileRequired
-checkIfaceFingerprint logger reason old_mod_hash new_mod_hash
- | new_mod_hash == old_mod_hash
- = up_to_date logger (text "Iface fingerprint unchanged")
-
+checkBytecodeFingerprint logger reason old_bytecode_hash new_bytecode_hash
+ | old_bytecode_hash == new_bytecode_hash
+ = up_to_date logger (text "Bytecode fingerprint unchanged")
| otherwise
- = out_of_date_hash logger reason (text " Iface fingerprint has changed")
- old_mod_hash new_mod_hash
+ = out_of_date_hash logger reason (text " Bytecode fingerprint has changed")
+ old_bytecode_hash new_bytecode_hash
------------------------
checkEntityUsage :: Logger
=====================================
compiler/GHC/Iface/Recomp/Types.hs
=====================================
@@ -146,10 +146,10 @@ pprUsage usage@UsageDirectory{}
ppr (usg_dir_hash usage)]
pprUsage usage@UsageMergedRequirement{}
= hsep [text "merged", ppr (usg_mod usage), ppr (usg_mod_hash usage)]
-pprUsage usage@UsageHomeModuleInterface{}
- = hsep [text "implementation", ppr (usg_mod_name usage)
+pprUsage usage@UsageHomeModuleBytecode{}
+ = hsep [text "Bytecode", ppr (usg_mod_name usage)
, ppr (usg_unit_id usage)
- , ppr (usg_iface_hash usage)]
+ , ppr (usg_bytecode_hash usage)]
pprUsageImport :: Outputable mod => mod -> Fingerprint -> IsSafeImport -> SDoc
pprUsageImport mod hash safe
@@ -157,4 +157,4 @@ pprUsageImport mod hash safe
, ppr hash ]
where
pp_safe | safe = text "safe"
- | otherwise = text " -/ "
\ No newline at end of file
+ | otherwise = text " -/ "
=====================================
compiler/GHC/Linker/ByteCode.hs
=====================================
@@ -31,7 +31,7 @@ linkBytecodeLib hsc_env gbcs = do
on_disk_bcos <- mapM (readBinByteCode hsc_env) bytecodeObjects
- let (all_cbcs, foreign_stubs) = unzip [ (bs, fs) | ModuleByteCode _m bs fs <- on_disk_bcos ++ gbcs]
+ let (all_cbcs, foreign_stubs) = unzip [ (bs, fs) | ModuleByteCode _m bs fs _hash <- on_disk_bcos ++ gbcs]
interpreter_foreign_lib <- mkInterpreterLib hsc_env (concat foreign_stubs ++ objectFiles)
@@ -67,4 +67,4 @@ mkInterpreterLib hsc_env files =
return $ Just (InterpreterSharedObject foreign_stub_lib_path foreign_stub_lib_dir foreign_stub_lib_name)
Nothing -> pure Nothing
False -> do
- pure $ Just (InterpreterStaticObjects files)
\ No newline at end of file
+ pure $ Just (InterpreterStaticObjects files)
=====================================
compiler/GHC/Linker/Deps.hs
=====================================
@@ -63,7 +63,7 @@ data LinkDepsOpts = LinkDepsOpts
data LinkDeps = LinkDeps
{ ldNeededLinkables :: [Linkable]
- , ldAllLinkables :: [Linkable]
+ , ldAllLinkables :: [LinkableWithUsage]
, ldUnits :: [UnitId]
, ldNeededUnits :: UniqDSet UnitId
}
@@ -126,7 +126,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do
return $ LinkDeps
{ ldNeededLinkables = lnks_needed
- , ldAllLinkables = links_got ++ lnks_needed
+ , ldAllLinkables = links_got ++ mkLinkablesUsage lnks_needed
, ldUnits = pkgs_needed
, ldNeededUnits = pkgs_s
}
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -135,6 +135,7 @@ import qualified Data.IntMap.Strict as IM
import qualified Data.Map.Strict as M
import Foreign.Ptr (nullPtr)
import GHC.ByteCode.Serialize
+import Control.DeepSeq (force)
-- Note [Linkers and loaders]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -228,7 +229,7 @@ lookupFromLoadedEnv interp name = do
-- | Load the module containing the given Name and get its associated 'HValue'.
--
-- Throws a 'ProgramError' if loading fails or the name cannot be found.
-loadName :: Interp -> HscEnv -> Name -> IO (ForeignHValue, [Linkable], PkgsLoaded)
+loadName :: Interp -> HscEnv -> Name -> IO (ForeignHValue, [LinkableWithUsage], PkgsLoaded)
loadName interp hsc_env name = do
initLoaderState interp hsc_env
modifyLoaderState interp $ \pls0 -> do
@@ -258,7 +259,7 @@ loadDependencies
-> LoaderState
-> SrcSpan
-> [Module]
- -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required
+ -> IO (LoaderState, SuccessFlag, [LinkableWithUsage], PkgsLoaded) -- ^ returns the set of linkables required
-- When called, the loader state must have been initialized (see `initLoaderState`)
loadDependencies interp hsc_env pls span needed_mods = do
let opts = initLinkDepsOpts hsc_env
@@ -667,6 +668,7 @@ findBytecodeLinkableMaybe hsc_env mod locn = do
case maybe_bytecode_time of
Nothing -> return Nothing
Just bytecode_time -> do
+ -- TODO: @fendor This must go
-- Also load the interface, for reasons to do with recompilation avoidance.
-- See Note [Recompilation avoidance with bytecode objects]
_ <- initIfaceLoad hsc_env $
@@ -723,7 +725,7 @@ get_reachable_nodes hsc_env mods
********************************************************************* -}
-- | Load the dependencies of a linkable, and then load the linkable itself.
-loadDecls :: Interp -> HscEnv -> SrcSpan -> Linkable -> IO ([Linkable], PkgsLoaded)
+loadDecls :: Interp -> HscEnv -> SrcSpan -> Linkable -> IO ([LinkableWithUsage], PkgsLoaded)
loadDecls interp hsc_env span linkable = do
-- Initialise the linker (if it's not been done already)
initLoaderState interp hsc_env
@@ -823,7 +825,7 @@ loadModuleLinkables interp hsc_env pls keep_spec linkables
(objs, bcos) = partitionLinkables linkables
-linkableInSet :: Linkable -> LinkableSet -> Bool
+linkableInSet :: Linkable -> LinkableSet LinkableWithUsage -> Bool
linkableInSet l objs_loaded =
case lookupModuleEnv objs_loaded (linkableModule l) of
Nothing -> False
@@ -952,17 +954,17 @@ dynLoadObjs interp hsc_env pls objs = do
then addWay WayProf
else id
-rmDupLinkables :: LinkableSet -- Already loaded
+rmDupLinkables :: LinkableSet LinkableWithUsage -- Already loaded
-> [Linkable] -- New linkables
- -> (LinkableSet, -- New loaded set (including new ones)
+ -> (LinkableSet LinkableWithUsage, -- New loaded set (including new ones)
[Linkable]) -- New linkables (excluding dups)
rmDupLinkables already ls
= go already [] ls
where
- go already extras [] = (already, extras)
- go already extras (l:ls)
+ go !already extras [] = (already, extras)
+ go !already extras (l:ls)
| linkableInSet l already = go already extras ls
- | otherwise = go (extendModuleEnv already (linkableModule l) l) (l:extras) ls
+ | otherwise = go (extendModuleEnv already (linkableModule l) $! force $ mkLinkableUsage l) (l:extras) ls
{- **********************************************************************
@@ -974,7 +976,7 @@ rmDupLinkables already ls
dynLinkBCOs :: Interp -> LoaderState -> KeepModuleLinkableDefinitions -> [Linkable] -> IO LoaderState
dynLinkBCOs interp pls keep_spec bcos =
- let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos
+ let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos -- TODO: @fendor, convert to linkable usage here?
pls1 = pls { bcos_loaded = bcos_loaded' }
cbcs :: [CompiledByteCode]
@@ -1109,13 +1111,13 @@ unload_wkr interp pls@LoaderState{..} = do
-- we're unloading some code. -fghci-leak-check with the tests in
-- testsuite/ghci can detect space leaks here.
- let linkables_to_unload = moduleEnvElts objs_loaded ++ moduleEnvElts bcos_loaded
+ let linkables_to_unload = moduleEnvElts objs_loaded ++ moduleEnvElts bcos_loaded -- TODO: @fendor LinkableUsage here already?
mapM_ unloadObjs linkables_to_unload
-- If we unloaded any object files at all, we need to purge the cache
-- of lookupSymbol results.
- when (not (null (filter (not . null . linkableObjs) linkables_to_unload))) $
+ when (not (null (filter (not . null . linkableUsageObjs) linkables_to_unload))) $
purgeLookupSymbolCache interp
let !new_pls = pls { bco_loader_state = modifyHomePackageBytecodeState bco_loader_state $ \_ -> emptyBytecodeState,
@@ -1125,7 +1127,7 @@ unload_wkr interp pls@LoaderState{..} = do
return new_pls
where
- unloadObjs :: Linkable -> IO ()
+ unloadObjs :: LinkableWithUsage -> IO ()
unloadObjs lnk
| interpreterDynamic interp = return ()
-- We don't do any cleanup when linking objects with the
@@ -1133,7 +1135,7 @@ unload_wkr interp pls@LoaderState{..} = do
-- not much benefit.
| otherwise
- = mapM_ (unloadObj interp) (linkableObjs lnk)
+ = mapM_ (unloadObj interp) (linkableUsageObjs lnk)
-- The components of a BCO linkable may contain
-- dot-o files (generated from C stubs).
--
=====================================
compiler/GHC/Linker/Types.hs
=====================================
@@ -49,6 +49,7 @@ module GHC.Linker.Types
, WholeCoreBindingsLinkable
, LinkableWith(..)
, mkModuleByteCodeLinkable
+ , mkOnlyModuleByteCodeLinkable
, LinkablePart(..)
, LinkableObjectSort (..)
, linkableIsNativeCodeOnly
@@ -67,12 +68,17 @@ module GHC.Linker.Types
, linkableFilterNative
, partitionLinkables
+ , LinkableWithUsage
+ , linkableUsageObjs
+ , mkLinkablesUsage
+ , mkLinkableUsage
+
, ModuleByteCode(..)
)
where
import GHC.Prelude
-import GHC.Unit ( UnitId, Module )
+import GHC.Unit ( UnitId, Module, moduleNameString, moduleName )
import GHC.ByteCode.Types
import GHCi.BreakArray
import GHCi.RemoteTypes
@@ -97,6 +103,11 @@ import Data.List.NonEmpty (NonEmpty, nonEmpty)
import qualified Data.List.NonEmpty as NE
import Control.Applicative ((<|>))
import Data.Functor.Identity
+import GHC.Unit.Module.Deps (LinkableUsage (..), linkableUsageObjectPaths)
+import GHC.Fingerprint (Fingerprint)
+import qualified GHC.Data.OsPath as OsPath
+import qualified GHC.Data.FlatBag as FlatBag
+import Control.DeepSeq (NFData(..))
{- **********************************************************************
@@ -172,10 +183,10 @@ data LoaderState = LoaderState
-- ^ Information about bytecode objects we have loaded into the
-- interpreter.
- , bcos_loaded :: !LinkableSet
+ , bcos_loaded :: !(LinkableSet LinkableWithUsage)
-- ^ The currently loaded interpreted modules (home package)
- , objs_loaded :: !LinkableSet
+ , objs_loaded :: !(LinkableSet LinkableWithUsage)
-- ^ And the currently-loaded compiled modules (home package)
, pkgs_loaded :: !PkgsLoaded
@@ -380,19 +391,25 @@ data LinkableWith parts = Linkable
-- ^ Files and chunks of code to link.
} deriving (Functor, Traversable, Foldable)
+instance NFData a => NFData (LinkableWith a) where
+ rnf Linkable{linkableTime,linkableModule,linkableParts} =
+ rnf linkableTime `seq` rnf linkableModule `seq` rnf linkableParts `seq` ()
+
type Linkable = LinkableWith (NonEmpty LinkablePart)
type WholeCoreBindingsLinkable = LinkableWith WholeCoreBindings
-type LinkableSet = ModuleEnv Linkable
+type LinkableWithUsage = LinkableWith (NonEmpty LinkableUsage)
+
+type LinkableSet = ModuleEnv
-mkLinkableSet :: [Linkable] -> LinkableSet
+mkLinkableSet :: [Linkable] -> LinkableSet Linkable
mkLinkableSet ls = mkModuleEnv [(linkableModule l, l) | l <- ls]
-- | Union of LinkableSets.
--
-- In case of conflict, keep the most recent Linkable (as per linkableTime)
-unionLinkableSet :: LinkableSet -> LinkableSet -> LinkableSet
+unionLinkableSet :: LinkableSet (LinkableWith a) -> LinkableSet (LinkableWith a) -> LinkableSet (LinkableWith a)
unionLinkableSet = plusModuleEnv_C go
where
go l1 l2
@@ -435,8 +452,9 @@ data LinkablePart
| DotDLL FilePath
-- ^ Dynamically linked library file (.so, .dll, .dylib)
- | DotGBC ModuleByteCode
- -- ^ A byte-code object, lives only in memory.
+ | DotGBC
+ -- ^ A byte-code object, lives only in memory.
+ ModuleByteCode
-- | The in-memory representation of a bytecode object
@@ -444,14 +462,19 @@ data LinkablePart
data ModuleByteCode = ModuleByteCode { gbc_module :: Module
, gbc_compiled_byte_code :: CompiledByteCode
, gbc_foreign_files :: [FilePath] -- ^ Path to object files
+ , gbc_hash :: !Fingerprint
}
mkModuleByteCodeLinkable :: UTCTime -> ModuleByteCode -> Linkable
-mkModuleByteCodeLinkable linkable_time bco =
+mkModuleByteCodeLinkable linkable_time bco = do
Linkable linkable_time (gbc_module bco) (pure (DotGBC bco))
+mkOnlyModuleByteCodeLinkable :: UTCTime -> ModuleByteCode -> LinkableWith ModuleByteCode
+mkOnlyModuleByteCodeLinkable linkable_time bco = do
+ Linkable linkable_time (gbc_module bco) bco
+
instance Outputable ModuleByteCode where
- ppr (ModuleByteCode mod _cbc _fos) = text "ModuleByteCode" <+> ppr mod
+ ppr (ModuleByteCode mod _cbc _fos _) = text "ModuleByteCode" <+> ppr mod
instance Outputable LinkablePart where
ppr (DotO path sort) = text "DotO" <+> text path <+> pprSort sort
@@ -544,8 +567,8 @@ linkablePartObjectPaths = \case
-- Contrary to linkableBCOs, this includes byte-code from LazyBCOs.
linkablePartBCOs :: LinkablePart -> [CompiledByteCode]
linkablePartBCOs = \case
- DotGBC bco -> [gbc_compiled_byte_code bco]
- _ -> []
+ DotGBC bco -> [gbc_compiled_byte_code bco]
+ _ -> []
linkableFilter :: (LinkablePart -> [LinkablePart]) -> Linkable -> Maybe Linkable
linkableFilter f linkable = do
@@ -586,6 +609,48 @@ partitionLinkables linkables =
mapMaybe linkableFilterByteCode linkables
)
+
+mkLinkableUsage :: Linkable -> LinkableWithUsage
+mkLinkableUsage linkables = do
+ linkableUsage linkables
+ where
+ msg m = moduleNameString (moduleName m) ++ "[TH] changed"
+
+ linkableUsage lnk@Linkable{linkableParts} =
+ setLinkableParts lnk linkableParts
+
+ mkFileLinkableUsage m fp objs =
+ FileLinkableUsage
+ { flu_file = fp
+ , flu_message = Just $ msg m
+ , flu_linkable_objs = FlatBag.fromList (strictGenericLength objs) [ OsPath.unsafeEncodeUtf obj | obj <- objs ]
+ }
+
+ mkByteCodeLinkableUsage m fp objs =
+ ByteCodeLinkableUsage
+ { bclu_module = m
+ , bclu_hash = fp
+ , bclu_linkable_objs = FlatBag.fromList (strictGenericLength objs) [ OsPath.unsafeEncodeUtf obj | obj <- objs ]
+ }
+
+ setLinkableParts lnk@(Linkable{linkableModule}) parts =
+ lnk
+ { linkableParts = fmap (go linkableModule) parts
+ }
+
+ go :: Module -> LinkablePart -> LinkableUsage
+ go m lnkPart = case lnkPart of
+ DotO fn _ -> mkFileLinkableUsage m fn (linkablePartObjectPaths lnkPart)
+ DotA fn -> mkFileLinkableUsage m fn (linkablePartObjectPaths lnkPart)
+ DotDLL fn -> mkFileLinkableUsage m fn (linkablePartObjectPaths lnkPart)
+ DotGBC mbc -> mkByteCodeLinkableUsage m (gbc_hash mbc) (linkablePartObjectPaths lnkPart)
+
+mkLinkablesUsage :: [Linkable] -> [LinkableWithUsage]
+mkLinkablesUsage linkables = map mkLinkableUsage linkables
+
+linkableUsageObjs :: LinkableWithUsage -> [FilePath]
+linkableUsageObjs lnkWithUsage = concatMap linkableUsageObjectPaths (linkableParts lnkWithUsage)
+
{- **********************************************************************
Loading packages
=====================================
compiler/GHC/Runtime/Loader.hs
=====================================
@@ -153,7 +153,7 @@ initializePlugins hsc_env
([] , _ ) -> False -- some external plugin added
(p:ps,s:ss) -> check_external_plugin p s && check_external_plugins ps ss
-loadPlugins :: HscEnv -> IO ([LoadedPlugin], [Linkable], PkgsLoaded)
+loadPlugins :: HscEnv -> IO ([LoadedPlugin], [LinkableWithUsage], PkgsLoaded)
loadPlugins hsc_env
= do { unless (null to_load) $
checkExternalInterpreter hsc_env
@@ -173,7 +173,7 @@ loadPlugins hsc_env
loadPlugin = loadPlugin' (mkVarOccFS (fsLit "plugin")) pluginTyConName hsc_env
-loadFrontendPlugin :: HscEnv -> ModuleName -> IO (FrontendPlugin, [Linkable], PkgsLoaded)
+loadFrontendPlugin :: HscEnv -> ModuleName -> IO (FrontendPlugin, [LinkableWithUsage], PkgsLoaded)
loadFrontendPlugin hsc_env mod_name = do
checkExternalInterpreter hsc_env
(plugin, _iface, links, pkgs)
@@ -188,7 +188,7 @@ checkExternalInterpreter hsc_env = case interpInstance <$> hsc_interp hsc_env of
-> throwIO (InstallationError "Plugins require -fno-external-interpreter")
_ -> pure ()
-loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [Linkable], PkgsLoaded)
+loadPlugin' :: OccName -> Name -> HscEnv -> ModuleName -> IO (a, ModIface, [LinkableWithUsage], PkgsLoaded)
loadPlugin' occ_name plugin_name hsc_env mod_name
= do { let plugin_rdr_name = mkRdrQual mod_name occ_name
dflags = hsc_dflags hsc_env
@@ -266,7 +266,7 @@ forceLoadTyCon hsc_env con_name = do
-- * If the Name does not exist in the module
-- * If the link failed
-getValueSafely :: HscEnv -> Name -> Type -> IO (Either Type (a, [Linkable], PkgsLoaded))
+getValueSafely :: HscEnv -> Name -> Type -> IO (Either Type (a, [LinkableWithUsage], PkgsLoaded))
getValueSafely hsc_env val_name expected_type = do
eith_hval <- case getValueSafelyHook hooks of
Nothing -> getHValueSafely interp hsc_env val_name expected_type
@@ -281,7 +281,7 @@ getValueSafely hsc_env val_name expected_type = do
logger = hsc_logger hsc_env
hooks = hsc_hooks hsc_env
-getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Either Type (HValue, [Linkable], PkgsLoaded))
+getHValueSafely :: Interp -> HscEnv -> Name -> Type -> IO (Either Type (HValue, [LinkableWithUsage], PkgsLoaded))
getHValueSafely interp hsc_env val_name expected_type = do
forceLoadNameModuleInterface hsc_env (text "contains a name used in an invocation of getHValueSafely") val_name
-- Now look up the names for the value and type constructor in the type environment
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -562,7 +562,7 @@ data TcGblEnv
-- is implicit rather than explicit, so we have to zap a
-- mutable variable.
- tcg_th_needed_deps :: TcRef ([Linkable], PkgsLoaded),
+ tcg_th_needed_deps :: TcRef ([LinkableWithUsage], PkgsLoaded),
-- ^ The set of runtime dependencies required by this module
-- See Note [Object File Dependencies]
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -2259,7 +2259,7 @@ fillCoercionHole (CH { ch_ref = ref, ch_co_var = cv }) co
recordThUse :: TcM ()
recordThUse = do { env <- getGblEnv; writeTcRef (tcg_th_used env) True }
-recordThNeededRuntimeDeps :: [Linkable] -> PkgsLoaded -> TcM ()
+recordThNeededRuntimeDeps :: [LinkableWithUsage] -> PkgsLoaded -> TcM ()
recordThNeededRuntimeDeps new_links new_pkgs
= do { env <- getGblEnv
; updTcRef (tcg_th_needed_deps env) $ \(needed_links, needed_pkgs) ->
=====================================
compiler/GHC/Unit/Home/ModInfo.hs
=====================================
@@ -3,9 +3,11 @@
module GHC.Unit.Home.ModInfo
(
HomeModInfo (..)
- , HomeModLinkable (..)
, homeModInfoObject
, homeModInfoByteCode
+ , HomeModLinkable (..)
+ , homeModLinkableByteCode
+ , homeModLinkableObject
, emptyHomeModInfoLinkable
)
where
@@ -15,9 +17,10 @@ import GHC.Prelude
import GHC.Unit.Module.ModIface
import GHC.Unit.Module.ModDetails
-import GHC.Linker.Types ( Linkable )
+import GHC.Linker.Types ( Linkable, LinkableWith, ModuleByteCode, LinkablePart (..) )
import GHC.Utils.Outputable
+import qualified Data.List.NonEmpty as NE
-- | Information about modules in the package being compiled
data HomeModInfo = HomeModInfo
@@ -48,18 +51,24 @@ data HomeModInfo = HomeModInfo
}
homeModInfoByteCode :: HomeModInfo -> Maybe Linkable
-homeModInfoByteCode = homeMod_bytecode . hm_linkable
+homeModInfoByteCode = homeModLinkableByteCode . hm_linkable
homeModInfoObject :: HomeModInfo -> Maybe Linkable
-homeModInfoObject = homeMod_object . hm_linkable
+homeModInfoObject = homeModLinkableObject . hm_linkable
emptyHomeModInfoLinkable :: HomeModLinkable
emptyHomeModInfoLinkable = HomeModLinkable Nothing Nothing
-- See Note [Home module build products]
-data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe Linkable)
+data HomeModLinkable = HomeModLinkable { homeMod_bytecode :: !(Maybe (LinkableWith ModuleByteCode))
, homeMod_object :: !(Maybe Linkable) }
+homeModLinkableByteCode :: HomeModLinkable -> Maybe Linkable
+homeModLinkableByteCode = fmap (fmap (NE.singleton . DotGBC)) . homeMod_bytecode
+
+homeModLinkableObject :: HomeModLinkable -> Maybe Linkable
+homeModLinkableObject = homeMod_object
+
instance Outputable HomeModLinkable where
ppr (HomeModLinkable l1 l2) = ppr l1 $$ ppr l2
=====================================
compiler/GHC/Unit/Module/Deps.hs
=====================================
@@ -22,6 +22,10 @@ module GHC.Unit.Module.Deps
, ImportAvails (..)
, IfaceImportLevel(..)
, tcImportLevel
+ , LinkableUsage(..)
+ , linkableUsageObjectPaths
+ , noLinkableUsage
+ , combineLinkableUsage
)
where
@@ -49,7 +53,10 @@ import qualified Data.Set as Set
import Data.Bifunctor
import Control.DeepSeq
import GHC.Types.Name.Set
-
+import GHC.ByteCode.Types (FlatBag)
+import GHC.Data.OsPath
+import qualified Data.Foldable as Foldable
+import qualified GHC.Data.OsPath as OsPath
-- | Dependency information about ALL modules and packages below this one
@@ -372,12 +379,12 @@ data Usage
-- we won't spot it here. If you do want to spot that, the caller
-- should recursively add them to their useage.
}
- | UsageHomeModuleInterface {
+ | UsageHomeModuleBytecode {
usg_mod_name :: ModuleName
-- ^ Name of the module
, usg_unit_id :: UnitId
-- ^ UnitId of the HomeUnit the module is from
- , usg_iface_hash :: Fingerprint
+ , usg_bytecode_hash :: Fingerprint
-- ^ The *interface* hash of the module, not the ABI hash.
-- This changes when anything about the interface (and hence the
-- module) has changed.
@@ -412,7 +419,7 @@ instance NFData Usage where
rnf (UsageFile file hash label) = rnf file `seq` rnf hash `seq` rnf label `seq` ()
rnf (UsageDirectory dir hash label) = rnf dir `seq` rnf hash `seq` rnf label `seq` ()
rnf (UsageMergedRequirement mod hash) = rnf mod `seq` rnf hash `seq` ()
- rnf (UsageHomeModuleInterface mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
+ rnf (UsageHomeModuleBytecode mod uid hash) = rnf mod `seq` rnf uid `seq` rnf hash `seq` ()
instance Binary Usage where
put_ bh usg@UsagePackageModule{} = do
@@ -441,11 +448,11 @@ instance Binary Usage where
put_ bh (usg_mod usg)
put_ bh (usg_mod_hash usg)
- put_ bh usg@UsageHomeModuleInterface{} = do
+ put_ bh usg@UsageHomeModuleBytecode{} = do
putByte bh 4
put_ bh (usg_mod_name usg)
put_ bh (usg_unit_id usg)
- put_ bh (usg_iface_hash usg)
+ put_ bh (usg_bytecode_hash usg)
put_ bh usg@UsageDirectory{} = do
putByte bh 5
@@ -483,7 +490,7 @@ instance Binary Usage where
mod <- get bh
uid <- get bh
hash <- get bh
- return UsageHomeModuleInterface { usg_mod_name = mod, usg_unit_id = uid, usg_iface_hash = hash }
+ return UsageHomeModuleBytecode { usg_mod_name = mod, usg_unit_id = uid, usg_bytecode_hash = hash }
5 -> do
dp <- get bh
hash <- get bh
@@ -695,3 +702,41 @@ data ImportAvails
-- ^ Family instance modules below us in the import tree (and maybe
-- including us for imported modules)
}
+
+data LinkableUsage
+ = FileLinkableUsage
+ { flu_file :: !FilePath
+ , flu_message :: !(Maybe String)
+ , flu_linkable_objs :: !(FlatBag OsPath)
+ }
+ | ByteCodeLinkableUsage
+ { bclu_module :: !Module
+ , bclu_hash :: !Fingerprint
+ , bclu_linkable_objs :: !(FlatBag OsPath)
+ }
+
+instance Outputable LinkableUsage where
+ ppr = \ case
+ FileLinkableUsage fp mmsg _objs ->
+ text "FileLinkableUsage" <+> text fp <> maybe empty (\ msg -> text " " <> text msg) mmsg
+ ByteCodeLinkableUsage modl hash _objs ->
+ text "ByteCodeLinkableUsage" <+> ppr modl <+> ppr hash
+
+instance NFData LinkableUsage where
+ rnf FileLinkableUsage{} = ()
+ rnf ByteCodeLinkableUsage{} = ()
+
+linkableUsageObjectPaths :: LinkableUsage -> [FilePath]
+linkableUsageObjectPaths lnkUsage =
+ map OsPath.unsafeDecodeUtf . Foldable.toList $ linkableUsageObjectOsPaths lnkUsage
+
+linkableUsageObjectOsPaths :: LinkableUsage -> FlatBag OsPath
+linkableUsageObjectOsPaths lnkUsage = case lnkUsage of
+ FileLinkableUsage{flu_linkable_objs} -> flu_linkable_objs
+ ByteCodeLinkableUsage{bclu_linkable_objs} -> bclu_linkable_objs
+
+noLinkableUsage :: [LinkableUsage]
+noLinkableUsage = []
+
+combineLinkableUsage :: [LinkableUsage] -> [LinkableUsage] -> [LinkableUsage]
+combineLinkableUsage a b = a ++ b
=====================================
compiler/GHC/Unit/Module/Status.hs
=====================================
@@ -18,7 +18,7 @@ import GHC.Unit.Home.ModInfo
import GHC.Unit.Module.ModGuts
import GHC.Unit.Module.ModIface
-import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly )
+import GHC.Linker.Types ( Linkable, WholeCoreBindingsLinkable, linkableIsNativeCodeOnly, ModuleByteCode, LinkableWith, linkableBCOs, linkableModuleByteCodes )
import GHC.Utils.Fingerprint
import GHC.Utils.Outputable
@@ -59,7 +59,7 @@ data RecompLinkables = RecompLinkables { recompLinkables_bytecode :: !RecompByte
, recompLinkables_object :: !(Maybe Linkable) }
data RecompBytecodeLinkable
- = NormalLinkable !(Maybe Linkable)
+ = NormalLinkable !(Maybe (LinkableWith ModuleByteCode))
| WholeCoreBindingsLinkable !WholeCoreBindingsLinkable
instance Outputable HscRecompStatus where
@@ -87,7 +87,8 @@ justBytecode :: Either Linkable WholeCoreBindingsLinkable -> RecompLinkables
justBytecode = \case
Left lm ->
assertPpr (not (linkableIsNativeCodeOnly lm)) (ppr lm)
- $ emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just lm) }
+ $ assertPpr (length (linkableBCOs lm) == 1) (text "Expected 1 DotGBC linkable" $$ ppr lm )
+ $ emptyRecompLinkables { recompLinkables_bytecode = NormalLinkable (Just (head (linkableModuleByteCodes lm) <$ lm)) }
Right lm -> emptyRecompLinkables { recompLinkables_bytecode = WholeCoreBindingsLinkable lm }
justObjects :: Linkable -> RecompLinkables
@@ -99,7 +100,8 @@ bytecodeAndObjects :: Either Linkable WholeCoreBindingsLinkable -> Linkable -> R
bytecodeAndObjects either_bc o = case either_bc of
Left bc ->
assertPpr (not (linkableIsNativeCodeOnly bc) && linkableIsNativeCodeOnly o) (ppr bc $$ ppr o)
- $ RecompLinkables (NormalLinkable (Just bc)) (Just o)
+ $ assertPpr (length (linkableBCOs bc) == 1) (text "Expected 1 DotGBC linkable" $$ ppr bc )
+ $ RecompLinkables (NormalLinkable (Just (head (linkableModuleByteCodes bc) <$ bc))) (Just o)
Right bc ->
assertPpr (linkableIsNativeCodeOnly o) (ppr o)
$ RecompLinkables (WholeCoreBindingsLinkable bc) (Just o)
=====================================
compiler/GHC/Utils/Binary.hs
=====================================
@@ -37,6 +37,7 @@ module GHC.Utils.Binary
tellBinWriter,
castBin,
withBinBuffer,
+ withReadBinBuffer,
freezeWriteHandle,
shrinkBinBuffer,
thawReadHandle,
@@ -349,6 +350,12 @@ withBinBuffer (WriteBinMem _ ix_r _ arr_r) action = do
arr <- readIORef arr_r
action $ BS.fromForeignPtr arr 0 ix
+-- | Get access to the underlying buffer.
+withReadBinBuffer :: ReadBinHandle -> (ByteString -> IO a) -> IO a
+withReadBinBuffer (ReadBinMem _ ix_r _ arr) action = do
+ ix <- readFastMutInt ix_r
+ action $ BS.fromForeignPtr arr 0 ix
+
unsafeUnpackBinBuffer :: ByteString -> IO ReadBinHandle
unsafeUnpackBinBuffer (BS.BS arr len) = do
ix_r <- newFastMutInt 0
=====================================
ghc/GHCi/Leak.hs
=====================================
@@ -52,8 +52,11 @@ getLeakIndicators hsc_env =
return $ LeakModIndicators{..}
where
mkWeakLinkables :: HomeModLinkable -> IO [Maybe (Weak Linkable)]
- mkWeakLinkables (HomeModLinkable mbc mo) =
- mapM (\ln -> traverse (flip mkWeakPtr Nothing <=< evaluate) ln) [mbc, mo]
+ mkWeakLinkables hml =
+ mapM (\ln -> traverse (flip mkWeakPtr Nothing <=< evaluate) ln)
+ [ homeModLinkableByteCode hml
+ , homeModLinkableObject hml
+ ]
-- | Look at the LeakIndicators collected by an earlier call to
-- `getLeakIndicators`, and print messasges if any of them are still
=====================================
testsuite/ghc-config/ghc-config
=====================================
Binary files /dev/null and b/testsuite/ghc-config/ghc-config differ
=====================================
testsuite/tests/bytecode/TLinkable/Makefile
=====================================
@@ -0,0 +1,31 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+.PHONY: TLinkable_Prep
+TLinkable_Prep:
+ ./genSplices TLinkable
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -fprefer-byte-code -v0 TLinkable.hs
+
+.PHONY: TLinkable2_Prep
+TLinkable2_Prep:
+ ./genSplices TLinkable2
+ '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) --make -fprefer-byte-code -fwrite-byte-code -v0 TLinkable2.hs
+
+.PHONY: linkable_bytecodelib_Prep linkable_bytecodelib
+PKGCONF01=bytecode.package.conf
+LOCAL_GHC_PKG01='$(GHC_PKG)' --no-user-package-db -f $(PKGCONF01)
+MAIN_MOD=BytecodeUsage
+linkable_bytecodelib_Prep:
+ $(LOCAL_GHC_PKG01) init $(PKGCONF01)
+ mkdir outdir
+ cd outdir && ../genSplices2 $(MAIN_MOD)
+ mv outdir/$(MAIN_MOD).hs $(MAIN_MOD).hs
+ cd outdir && $(TEST_HC) -bytecodelib -hisuf=$(ghciWayExt) $(ghciWayFlags) \
+ -o testpkg-1.2.3.4-XXX.bytecodelib -fbyte-code -fwrite-interface -fwrite-byte-code -this-unit-id=testpkg-1.2.3.4-XXX \
+ *.hs
+ $(LOCAL_GHC_PKG01) register --force outdir/bytecode.pkg
+
+linkable_bytecodelib:
+ $(TEST_HC) $(TEST_HC_OPTS) $(ghcThWayFlags) --make -fprefer-byte-code $(MAIN_MOD) -package testpkg -package-db $(PKGCONF01) +RTS -l -hT -i0.001 -RTS
+
=====================================
testsuite/tests/bytecode/TLinkable/all.T
=====================================
@@ -0,0 +1,33 @@
+# Test ideas
+# Bytecode libraries
+# Depend on that bytecode, look at the bytecode library tests to make sure this ends up in the EPS
+
+def normaliseDynlibNames(str):
+ return re.sub(r'-ghc[0-9.]+\.', '-ghc<VERSION>.', str)
+
+test('TLinkable',
+ [ collect_compiler_stats('bytes allocated',2),
+ pre_cmd('$MAKE -s --no-print-directory TLinkable_Prep'),
+ extra_files(['genSplices']),
+ compile_timeout_multiplier(5),
+ ],
+ compile,
+ ['-fprefer-byte-code -fforce-recomp ' + config.ghc_th_way_flags])
+
+test('TLinkable2',
+ [ collect_compiler_stats('bytes allocated',2),
+ pre_cmd('$MAKE -s --no-print-directory TLinkable2_Prep'),
+ extra_files(['genSplices']),
+ compile_timeout_multiplier(5),
+ ],
+ compile,
+ ['-fprefer-byte-code -fforce-recomp ' + config.ghc_th_way_flags])
+
+test('linkable_bytecodelib',
+ [ extra_files(["genSplices2"])
+ , normalise_errmsg_fun(normaliseDynlibNames)
+ , pre_cmd('$MAKE -s --no-print-directory linkable_bytecodelib_Prep')
+ , copy_files
+ , req_bco ],
+ makefile_test,
+ [])
=====================================
testsuite/tests/bytecode/TLinkable/genSplices
=====================================
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# Generate NMOD Haskell modules, each with NDEF NOINLINE functions
+# Usage: ./genSplices <MODNAME> <NMOD> <NDEF>
+
+MODNAME=${1}
+NMOD=${2:-20} # Default 20 modules
+NDEF=${3:-50} # Default 50 functions per module
+
+# Generate the modules
+for ((i=1; i<=NMOD; i++)); do
+ module_name="Module$(printf "%03d" $i)"
+ file_path="${module_name}.hs"
+
+ cat > "$file_path" << EOF
+module ${module_name} where
+
+EOF
+
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ cat >> "$file_path" << EOF
+{-# NOINLINE ${func_name} #-}
+${func_name} :: Int -> Int
+${func_name} x = x + ${j}
+
+EOF
+ done
+done
+
+# Generate imports section
+imports=""
+for ((i=1; i<=NMOD; i++)); do
+ imports="${imports}import splice Module$(printf "%03d" $i)
+"
+done
+
+# Generate the hard-coded TH expression
+# Build: Module001.func001 1 + Module001.func002 2 + ... + Module{NMOD}.func{NDEF} {NMOD*NDEF}
+expression=""
+count=1
+for ((i=1; i<=NMOD; i++)); do
+ mod_name="Module$(printf "%03d" $i)"
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ if [ $count -gt 1 ]; then
+ expression="${expression} + "
+ fi
+ expression="${expression}${mod_name}.${func_name} ${count}"
+ ((count++))
+ done
+done
+
+# Generate the TH splice file
+cat > "${MODNAME}".hs << EOF
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE NumericUnderscores #-}
+{-# LANGUAGE ExplicitLevelImports #-}
+
+module ${MODNAME} where
+
+import splice Language.Haskell.TH.Syntax (Lift(..))
+import Control.Concurrent (threadDelay)
+import splice Prelude (Num(..), ($), Monad(..), pure)
+
+-- Import all generated modules
+${imports}
+-- Hard-coded splice that references ALL functions from ALL modules
+result :: Int
+result = \$(lift \$ ${expression})
+
+result_test :: IO Int
+result_test = \$( [| threadDelay 1_000_000 >> pure 50 |] )
+
+main :: IO ()
+main = do
+ putStrLn \$ "Result: " ++ show result
+ putStrLn . ("Other result: " ++) . show =<< result_test
+EOF
=====================================
testsuite/tests/bytecode/TLinkable/genSplices2
=====================================
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+MODNAME=${1}
+NMOD=${2:-20} # Default 20 modules
+NDEF=${3:-50} # Default 50 functions per module
+
+# Generate the modules
+for ((i=1; i<=NMOD; i++)); do
+ module_name="Module$(printf "%03d" $i)"
+ file_path="${module_name}.hs"
+
+ cat > "$file_path" << EOF
+module ${module_name} where
+
+EOF
+
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ cat >> "$file_path" << EOF
+{-# NOINLINE ${func_name} #-}
+${func_name} :: Int -> Int
+${func_name} x = x + ${j}
+
+EOF
+ done
+done
+
+# Generate imports section
+imports=""
+for ((i=1; i<=NMOD; i++)); do
+ imports="${imports}import splice Module$(printf "%03d" $i)
+"
+done
+
+# Generate the hard-coded TH expression
+# Build: Module001.func001 1 + Module001.func002 2 + ... + Module{NMOD}.func{NDEF} {NMOD*NDEF}
+expressions=""
+all_mods=""
+for ((i=1; i<=NMOD; i++)); do
+ mod_name="Module$(printf "%03d" $i)"
+ all_mods="${all_mods} ${mod_name}"
+ single_expression=""
+ count=1
+ for ((j=1; j<=NDEF; j++)); do
+ func_name="func$(printf "%03d" $j)"
+ if [ $count -gt 1 ]; then
+ single_expression="${single_expression} + "
+ fi
+ single_expression="${single_expression}${mod_name}.${func_name} ${count}"
+ ((count++))
+ done
+
+ expressions="comp$(printf "%03d" $i) = \$(lift \$ ${single_expression})\\n\\n${expressions}"
+done
+
+# Generate the TH splice file
+cat > bytecode.pkg << EOF
+name: testpkg
+version: 1.2.3.4
+id: testpkg-1.2.3.4-XXX
+key: testpkg-1.2.3.4-XXX
+license: BSD3
+copyright: (c) The Univsersity of Glasgow 2004
+maintainer: glasgow-haskell-users(a)haskell.org
+stability: stable
+homepage: http://www.haskell.org/ghc
+package-url: http://www.haskell.org/ghc
+description: A Test Package
+category: none
+author: simonmar(a)microsoft.com
+exposed: True
+exposed-modules: ${all_mods}
+import-dirs: \${pkgroot}/outdir
+library-dirs: \${pkgroot}/outdir
+include-dirs:
+bytecode-library-dirs: \${pkgroot}/outdir
+hs-libraries: testpkg-1.2.3.4-XXX
+EOF
+
+# Generate the TH splice file
+cat > "${MODNAME}".hs << EOF
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE NumericUnderscores #-}
+{-# LANGUAGE ExplicitLevelImports #-}
+
+module ${MODNAME} where
+
+import splice Language.Haskell.TH.Syntax (Lift(..))
+import Control.Concurrent (threadDelay)
+import splice Prelude (Num(..), ($), Monad(..), pure)
+
+-- Import all generated modules
+${imports}
+
+-- Use from each module
+$(echo -e -n "${expressions}")
+
+EOF
=====================================
testsuite/tests/bytecode/TLinkable/linkable_bytecodelib.stdout
=====================================
@@ -0,0 +1 @@
+[1 of 1] Compiling BytecodeUsage ( BytecodeUsage.hs, BytecodeUsage.o )
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cdc44268af423ea74630d7078d6076…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cdc44268af423ea74630d7078d6076…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26875] 9 commits: Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
by Teo Camarasu (@teo) 18 Feb '26
by Teo Camarasu (@teo) 18 Feb '26
18 Feb '26
Teo Camarasu pushed to branch wip/T26875 at Glasgow Haskell Compiler / GHC
Commits:
14f485ee by ARATA Mizuki at 2026-02-17T09:09:24+09:00
Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
Also, mark AVX-512 ER and PF as deprecated.
AVX-512 instructions can be used for certain 64-bit integer vector operations.
GFNI can be used to implement bitReverse (currently not used by NCG, but LLVM may use it).
Closes #26406
Addresses #26509
- - - - -
016f79d5 by fendor at 2026-02-17T09:16:16-05:00
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
- - - - -
4f2840f2 by Brian J. Cardiff at 2026-02-17T17:04:08-05:00
configure: Accept happy-2.2
In Jan 2026 happy-2.2 was released. The most sensible change is https://github.com/haskell/happy/issues/335 which didn't trigger in a fresh build
- - - - -
10b4d364 by Duncan Coutts at 2026-02-17T17:04:52-05:00
Fix errors in the documentation of the eventlog STOP_THREAD status codes
Fix the code for BlockedOnMsgThrowTo.
Document all the known historical warts.
Fixes issue #26867
- - - - -
c5e15b8b by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: use snippets for all list examples
- generate snippet output for docs
- reduce font size to better fit snippets
- Use only directive to guard html snippets
- Add latex snippets for lists
- - - - -
d388bac1 by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: Place the snippet input and output together
- Put the output seemingly inside the example box
- - - - -
016fa306 by Samuel Thibault at 2026-02-18T05:08:35-05:00
Fix linking against libm by moving the -lm option
For those systems that need -lm for getting math functions, this is
currently added on the link line very early, before the object files being
linked together. Newer toolchains enable --as-needed by default, which means
-lm is ignored at that point because no object requires a math function
yet. With such toolchains, we thus have to add -lm after the objects, so the
linker actually includes libm in the link.
- - - - -
68bd0805 by Teo Camarasu at 2026-02-18T05:09:19-05:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
82000eaa by Teo Camarasu at 2026-02-18T10:56:53+00:00
ghc-internal: avoid depending on GHC.Internal.Control.Monad.Fix
This module contains the definition of MonadFix, since we want an
instance for IO, that instance requires a lot of machinery and we want
to avoid an orphan instance, this will naturally be quite high up in the
dependency graph.
So we want to avoid other modules depending on it as far as possible.
Resolves #26875
- - - - -
120 changed files:
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/SysTools/Cpp.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/phases.rst
- docs/users_guide/using.rst
- libraries/base/changelog.md
- libraries/base/src/Control/Arrow.hs
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/System/IO.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Control/Arrow.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Lazy/Imp.hs
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Identity.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- m4/fptools_happy.m4
- testsuite/driver/cpu_features.py
- testsuite/tests/arrows/should_compile/T21301.stderr
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.hs
- testsuite/tests/deSugar/should_fail/DsStrictFail.stderr
- testsuite/tests/deSugar/should_run/T20024.stderr
- testsuite/tests/deSugar/should_run/dsrun005.stderr
- testsuite/tests/deSugar/should_run/dsrun007.stderr
- testsuite/tests/deSugar/should_run/dsrun008.stderr
- testsuite/tests/deriving/should_run/T9576.stderr
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/ListTuplePunsPpr.stdout
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/ghci/scripts/T4175.stdout
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- testsuite/tests/patsyn/should_run/ghci.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- utils/haddock/doc/.gitignore
- utils/haddock/doc/Makefile
- + utils/haddock/doc/_static/haddock-custom.css
- utils/haddock/doc/conf.py
- utils/haddock/doc/markup.rst
- + utils/haddock/doc/snippets/.gitignore
- + utils/haddock/doc/snippets/Lists.hs
- + utils/haddock/doc/snippets/Makefile
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.html
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
- + utils/haddock/doc/snippets/Snippet-List-Definition.html
- + utils/haddock/doc/snippets/Snippet-List-Definition.tex
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.html
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
- + utils/haddock/doc/snippets/Snippet-List-Indentation.html
- + utils/haddock/doc/snippets/Snippet-List-Indentation.tex
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
- utils/haddock/html-test/ref/A.html
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1033.html
- utils/haddock/html-test/ref/Bug1103.html
- utils/haddock/html-test/ref/Bug548.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/FunArgs.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Instances.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/RedactTypeSynonyms.html
- utils/haddock/html-test/ref/T23616.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b5fa580049dd07d74f958f55491be…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b5fa580049dd07d74f958f55491be…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/linkable-usage] 11 commits: Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
by Hannes Siebenhandl (@fendor) 18 Feb '26
by Hannes Siebenhandl (@fendor) 18 Feb '26
18 Feb '26
Hannes Siebenhandl pushed to branch wip/fendor/linkable-usage at Glasgow Haskell Compiler / GHC
Commits:
14f485ee by ARATA Mizuki at 2026-02-17T09:09:24+09:00
Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
Also, mark AVX-512 ER and PF as deprecated.
AVX-512 instructions can be used for certain 64-bit integer vector operations.
GFNI can be used to implement bitReverse (currently not used by NCG, but LLVM may use it).
Closes #26406
Addresses #26509
- - - - -
016f79d5 by fendor at 2026-02-17T09:16:16-05:00
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
- - - - -
4f2840f2 by Brian J. Cardiff at 2026-02-17T17:04:08-05:00
configure: Accept happy-2.2
In Jan 2026 happy-2.2 was released. The most sensible change is https://github.com/haskell/happy/issues/335 which didn't trigger in a fresh build
- - - - -
10b4d364 by Duncan Coutts at 2026-02-17T17:04:52-05:00
Fix errors in the documentation of the eventlog STOP_THREAD status codes
Fix the code for BlockedOnMsgThrowTo.
Document all the known historical warts.
Fixes issue #26867
- - - - -
c5e15b8b by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: use snippets for all list examples
- generate snippet output for docs
- reduce font size to better fit snippets
- Use only directive to guard html snippets
- Add latex snippets for lists
- - - - -
d388bac1 by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: Place the snippet input and output together
- Put the output seemingly inside the example box
- - - - -
016fa306 by Samuel Thibault at 2026-02-18T05:08:35-05:00
Fix linking against libm by moving the -lm option
For those systems that need -lm for getting math functions, this is
currently added on the link line very early, before the object files being
linked together. Newer toolchains enable --as-needed by default, which means
-lm is ignored at that point because no object requires a math function
yet. With such toolchains, we thus have to add -lm after the objects, so the
linker actually includes libm in the link.
- - - - -
68bd0805 by Teo Camarasu at 2026-02-18T05:09:19-05:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
c45e90e1 by Matthew Pickering at 2026-02-18T11:16:59+01:00
Add support for ghc-debug to ghc executable
- - - - -
bc1c437c by fendor at 2026-02-18T11:16:59+01:00
Add bytecode linkable regression test
- - - - -
cdc44268 by fendor at 2026-02-18T11:16:59+01:00
WIP: LinkableUsage
- - - - -
140 changed files:
- .gitmodules
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Hooks.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Linker/ByteCode.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Unit/Home/ModInfo.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Utils/Binary.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/phases.rst
- docs/users_guide/using.rst
- + ghc-debug
- ghc/GHCi/Leak.hs
- ghc/Main.hs
- ghc/ghc-bin.cabal.in
- hadrian/src/Packages.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- + instructions.md
- libraries/base/changelog.md
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Exts.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- m4/fptools_happy.m4
- testsuite/driver/cpu_features.py
- + testsuite/ghc-config/ghc-config
- testsuite/tests/arrows/should_compile/T21301.stderr
- + testsuite/tests/bytecode/TLinkable/Makefile
- + testsuite/tests/bytecode/TLinkable/all.T
- + testsuite/tests/bytecode/TLinkable/genSplices
- + testsuite/tests/bytecode/TLinkable/genSplices2
- + testsuite/tests/bytecode/TLinkable/linkable_bytecodelib.stdout
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.hs
- testsuite/tests/deSugar/should_fail/DsStrictFail.stderr
- testsuite/tests/deSugar/should_run/T20024.stderr
- testsuite/tests/deSugar/should_run/dsrun005.stderr
- testsuite/tests/deSugar/should_run/dsrun007.stderr
- testsuite/tests/deSugar/should_run/dsrun008.stderr
- testsuite/tests/deriving/should_run/T9576.stderr
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/patsyn/should_run/ghci.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- utils/haddock/doc/.gitignore
- utils/haddock/doc/Makefile
- + utils/haddock/doc/_static/haddock-custom.css
- utils/haddock/doc/conf.py
- utils/haddock/doc/markup.rst
- + utils/haddock/doc/snippets/.gitignore
- + utils/haddock/doc/snippets/Lists.hs
- + utils/haddock/doc/snippets/Makefile
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.html
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
- + utils/haddock/doc/snippets/Snippet-List-Definition.html
- + utils/haddock/doc/snippets/Snippet-List-Definition.tex
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.html
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
- + utils/haddock/doc/snippets/Snippet-List-Indentation.html
- + utils/haddock/doc/snippets/Snippet-List-Indentation.tex
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
- utils/haddock/html-test/ref/A.html
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1033.html
- utils/haddock/html-test/ref/Bug1103.html
- utils/haddock/html-test/ref/Bug548.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/FunArgs.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Instances.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/RedactTypeSynonyms.html
- utils/haddock/html-test/ref/T23616.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47420bcbe490a7a36bbcb04fc329ab…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47420bcbe490a7a36bbcb04fc329ab…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] ghc-internal: Move GHC.Internal.Data.Bool to base
by Marge Bot (@marge-bot) 18 Feb '26
by Marge Bot (@marge-bot) 18 Feb '26
18 Feb '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
68bd0805 by Teo Camarasu at 2026-02-18T05:09:19-05:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
31 changed files:
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Exts.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- utils/haddock/html-test/ref/A.html
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1033.html
- utils/haddock/html-test/ref/Bug1103.html
- utils/haddock/html-test/ref/Bug548.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/FunArgs.html
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Instances.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/RedactTypeSynonyms.html
- utils/haddock/html-test/ref/T23616.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68bd08055594b8cbf6148a72d108786…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68bd08055594b8cbf6148a72d108786…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Fix linking against libm by moving the -lm option
by Marge Bot (@marge-bot) 18 Feb '26
by Marge Bot (@marge-bot) 18 Feb '26
18 Feb '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
016fa306 by Samuel Thibault at 2026-02-18T05:08:35-05:00
Fix linking against libm by moving the -lm option
For those systems that need -lm for getting math functions, this is
currently added on the link line very early, before the object files being
linked together. Newer toolchains enable --as-needed by default, which means
-lm is ignored at that point because no object requires a math function
yet. With such toolchains, we thus have to add -lm after the objects, so the
linker actually includes libm in the link.
- - - - -
1 changed file:
- compiler/GHC/Linker/Dynamic.hs
Changes:
=====================================
compiler/GHC/Linker/Dynamic.hs
=====================================
@@ -227,7 +227,6 @@ linkDynLib logger tmpfs dflags0 unit_env o_files dep_packages
runLink logger tmpfs linker_config (
map Option verbFlags
- ++ libmLinkOpts platform
++ [ Option "-o"
, FileOption "" output_fn
]
@@ -260,6 +259,7 @@ linkDynLib logger tmpfs dflags0 unit_env o_files dep_packages
-- driver is a more pragmatic solution.
++ [ Option "-Wl,--Bsymbolic,--experimental-pic,--unresolved-symbols=import-dynamic" | arch == ArchWasm32 ]
++ extra_ld_inputs
+ ++ libmLinkOpts platform
++ map Option lib_path_opts
++ map Option pkg_lib_path_opts
++ map Option pkg_link_opts
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/016fa306cd8afdaac56ebdebe44a447…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/016fa306cd8afdaac56ebdebe44a447…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: haddock: use snippets for all list examples
by Marge Bot (@marge-bot) 18 Feb '26
by Marge Bot (@marge-bot) 18 Feb '26
18 Feb '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
c5e15b8b by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: use snippets for all list examples
- generate snippet output for docs
- reduce font size to better fit snippets
- Use only directive to guard html snippets
- Add latex snippets for lists
- - - - -
d388bac1 by Phil de Joux at 2026-02-18T05:07:36-05:00
haddock: Place the snippet input and output together
- Put the output seemingly inside the example box
- - - - -
24 changed files:
- utils/haddock/doc/.gitignore
- utils/haddock/doc/Makefile
- + utils/haddock/doc/_static/haddock-custom.css
- utils/haddock/doc/conf.py
- utils/haddock/doc/markup.rst
- + utils/haddock/doc/snippets/.gitignore
- + utils/haddock/doc/snippets/Lists.hs
- + utils/haddock/doc/snippets/Makefile
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.html
- + utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
- + utils/haddock/doc/snippets/Snippet-List-Definition.html
- + utils/haddock/doc/snippets/Snippet-List-Definition.tex
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.html
- + utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
- + utils/haddock/doc/snippets/Snippet-List-Indentation.html
- + utils/haddock/doc/snippets/Snippet-List-Indentation.tex
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
- + utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
- + utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
Changes:
=====================================
utils/haddock/doc/.gitignore
=====================================
@@ -1 +1,3 @@
-.build-html
\ No newline at end of file
+.build-html
+.build-latex
+!_static
=====================================
utils/haddock/doc/Makefile
=====================================
@@ -1,8 +1,13 @@
SPHINX_BUILD ?= sphinx-build
-all : html
+all : html pdf
.PHONY : html
+.PHONY : pdf
html :
$(SPHINX_BUILD) -b html . .build-html
+
+pdf :
+ $(SPHINX_BUILD) -b latex . .build-latex
+ cd .build-latex && make
=====================================
utils/haddock/doc/_static/haddock-custom.css
=====================================
@@ -0,0 +1,19 @@
+.result.admonition {
+ border: solid 3px #eee;
+ border-top: none;
+ background-color: transparent;
+ padding: 1px 0px 10px 10px;
+ margin: 0px 0px -20px 0px;
+ position: relative;
+ top: -18px;
+}
+
+.result.admonition p.admonition-title{
+ position: absolute;
+ visibility: hidden;
+}
+
+/* Use a small font size for code blocks so that they don't overflow. */
+pre {
+ font-size: 0.8em;
+}
=====================================
utils/haddock/doc/conf.py
=====================================
@@ -31,6 +31,12 @@ pygments_style = 'tango'
htmlhelp_basename = 'Haddockdoc'
+html_static_path = ['_static']
+
+html_css_files = [
+ 'haddock-custom.css',
+]
+
# -- Options for LaTeX output ---------------------------------------------
=====================================
utils/haddock/doc/markup.rst
=====================================
@@ -1004,99 +1004,162 @@ Itemized and Enumerated Lists
A bulleted item is represented by preceding a paragraph with either
“``*``” or “``-``”. A sequence of bulleted paragraphs is rendered as an
-itemized list in the generated documentation, e.g.: ::
+itemized list in the generated documentation, e.g.
- -- | This is a bulleted list:
- --
- -- * first item
- --
- -- * second item
+.. literalinclude:: snippets/Lists.hs
+ :lines: 3-7
+
+.. admonition:: Result
+ :class: result
+
+ .. only:: html
+
+ .. raw:: html
+ :file: snippets/Snippet-List-Bulleted.html
+
+ .. only:: latex
+
+ .. raw:: latex
+ :file: snippets/Snippet-List-Bulleted.tex
+
+.. warning::
+
+ Separate lists from any preceding markup with at least one blank line
+ otherwise the list and its items will be rendered with the preceding
+ content.
+
+.. literalinclude:: snippets/Lists.hs
+ :lines: 10-12
+
+.. admonition:: Result
+ :class: result
+
+ .. only:: html
+
+ .. raw:: html
+ :file: snippets/Snippet-List-Not-Separated.html
+
+ .. only:: latex
+
+ .. raw:: latex
+ :file: snippets/Snippet-List-Not-Separated.tex
An enumerated list is similar, except each paragraph must be preceded by
-either “``(n)``” or “``n.``” where n is any integer. e.g. ::
+either “``(n)``” or “``n.``” where n is any integer. e.g.
- -- | This is an enumerated list:
- --
- -- (1) first item
- --
- -- 2. second item
+.. literalinclude:: snippets/Lists.hs
+ :lines: 15-19
-Lists of the same type don't have to be separated by a newline: ::
+.. admonition:: Result
+ :class: result
- -- | This is an enumerated list:
- --
- -- (1) first item
- -- 2. second item
- --
- -- This is a bulleted list:
- --
- -- * first item
- -- * second item
+ .. only:: html
-You can have more than one line of content in a list element: ::
+ .. raw:: html
+ :file: snippets/Snippet-List-Enumerated.html
- -- |
- -- * first item
- -- and more content for the first item
- -- * second item
- -- and more content for the second item
+ .. only:: latex
+
+ .. raw:: latex
+ :file: snippets/Snippet-List-Enumerated.tex
+
+Lists of the same type don't have to be separated by a newline:
+
+.. literalinclude:: snippets/Lists.hs
+ :lines: 22-30
+
+.. admonition:: Result
+ :class: result
+
+ .. only:: html
+
+ .. raw:: html
+ :file: snippets/Snippet-List-Not-Newline.html
+
+ .. only:: latex
+
+ .. raw:: latex
+ :file: snippets/Snippet-List-Not-Newline.tex
+
+You can have more than one line of content in a list element:
+
+.. literalinclude:: snippets/Lists.hs
+ :lines: 33-37
+
+.. admonition:: Result
+ :class: result
+
+ .. only:: html
+
+ .. raw:: html
+ :file: snippets/Snippet-List-Multiline-Item.html
+
+ .. only:: latex
+
+ .. raw:: latex
+ :file: snippets/Snippet-List-Multiline-Item.tex
You can even nest whole paragraphs inside of list elements. The rules
are 4 spaces for each indentation level. You're required to use a
-newline before such nested paragraphs: ::
-
- {-|
- * Beginning of list
- This belongs to the list above!
+newline before such nested paragraphs:
- > nested
- > bird
- > tracks
+.. literalinclude:: snippets/Lists.hs
+ :lines: 40-61
- * Next list
- More of the indented list.
+.. admonition:: Result
+ :class: result
- * Deeper
+ .. only:: html
- @
- even code blocks work
- @
+ .. raw:: html
+ :file: snippets/Snippet-List-Nested-Item.html
- * Deeper
+ .. only:: latex
- 1. Even deeper!
- 2. No newline separation even in indented lists.
- -}
+ .. raw:: latex
+ :file: snippets/Snippet-List-Nested-Item.tex
The indentation of the first list item is honoured. That is, in the
following example the items are on the same level. Before Haddock
2.16.1, the second item would have been nested under the first item
-which was unexpected. ::
+which was unexpected.
- {-|
- * foo
+.. literalinclude:: snippets/Lists.hs
+ :lines: 64-68
- * bar
- -}
+.. admonition:: Result
+ :class: result
+
+ .. only:: html
+
+ .. raw:: html
+ :file: snippets/Snippet-List-Indentation.html
+
+ .. only:: latex
+
+ .. raw:: latex
+ :file: snippets/Snippet-List-Indentation.tex
Definition Lists
~~~~~~~~~~~~~~~~
-Definition lists are written as follows: ::
+Definition lists are written as follows:
- -- | This is a definition list:
- --
- -- [@foo@]: The description of @foo@.
- --
- -- [@bar@]: The description of @bar@.
+.. literalinclude:: snippets/Lists.hs
+ :lines: 71-75
+
+.. admonition:: Result
+ :class: result
+
+ .. only:: html
-To produce output something like this:
+ .. raw:: html
+ :file: snippets/Snippet-List-Definition.html
-``foo``
- The description of ``foo``.
+ .. only:: latex
-``bar``
- The description of ``bar``.
+ .. raw:: latex
+ :file: snippets/Snippet-List-Definition.tex
Each paragraph should be preceded by the “definition term” enclosed in
square brackets and followed by a colon. Other markup operators may be
=====================================
utils/haddock/doc/snippets/.gitignore
=====================================
@@ -0,0 +1,12 @@
+*.html
+*.tex
+haddock-bundle.min.js
+haddock.sty
+linuwial.css
+main.tex
+meta.json
+quick-jump.css
+synopsis.png
+
+!Snippet*.html
+!Snippet*.tex
=====================================
utils/haddock/doc/snippets/Lists.hs
=====================================
@@ -0,0 +1,76 @@
+module Lists where
+
+-- | This is a bulleted list:
+--
+-- * first item
+--
+-- * second item
+data Bulleted
+
+-- | __Missing blank lines__ before a list:
+-- * first item
+-- * second item
+data Before
+
+-- | This is an, (n) n., enumerated list:
+--
+-- (1) first item
+--
+-- 2. second item
+data Enumerated
+
+-- | This is an enumerated list, with items not separated by newlines:
+--
+-- (1) first item
+-- 2. second item
+--
+-- This is a bulleted list, with items not separated by newlines:
+--
+-- * first item
+-- * second item
+data NotNewline
+
+-- |
+-- * first item
+-- and more content for the first item
+-- * second item
+-- and more content for the second item
+data MultilineItem
+
+{-|
+* Beginning of list
+This belongs to the list above!
+
+ > nested
+ > bird
+ > tracks
+
+ * Next list
+ More of the indented list.
+
+ * Deeper
+
+ @
+ even code blocks work
+ @
+
+ * Deeper
+
+ 1. Even deeper!
+ 2. No newline separation even in indented lists.
+-}
+data NestedItem
+
+{-|
+ * foo
+
+ * bar
+-}
+data Indentation
+
+-- | This is a definition list:
+--
+-- [@foo@]: The description of @foo@.
+--
+-- [@bar@]: The description of @bar@.
+data DefinitionList
\ No newline at end of file
=====================================
utils/haddock/doc/snippets/Makefile
=====================================
@@ -0,0 +1,103 @@
+# \newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+HDK_BEGIN := \\\\newcommand{\\haddockbegindoc}{\\hfill\\\\\[1ex]}
+
+# \newcommand{\haddockverb}{\small}
+HDK_VERB := \\\\newcommand{\\haddockverb}{\\small}
+
+# \newcommand{\haddocktt}[1]{{\small \texttt{#1}}}
+HDK_TT := \\\\newcommand{\\haddocktt}[1]{{\\small \\\\texttt{\#1}}}
+
+all: \
+ Snippet-List-Bulleted.html \
+ Snippet-List-Bulleted.tex \
+ Snippet-List-Not-Separated.html \
+ Snippet-List-Not-Separated.tex \
+ Snippet-List-Enumerated.html \
+ Snippet-List-Enumerated.tex \
+ Snippet-List-Not-Newline.html \
+ Snippet-List-Not-Newline.tex \
+ Snippet-List-Multiline-Item.html \
+ Snippet-List-Multiline-Item.tex \
+ Snippet-List-Nested-Item.html \
+ Snippet-List-Nested-Item.tex \
+ Snippet-List-Indentation.html \
+ Snippet-List-Indentation.tex \
+ Snippet-List-Definition.html \
+ Snippet-List-Definition.tex
+
+clean:
+ rm -f Lists*.html
+
+Lists.html: Lists.hs
+ haddock --html $^
+
+Lists.tex: Lists.hs
+ haddock --latex $^
+
+# Using pandoc-3.1.3
+Lists-Pretty.html: Lists.html
+ pandoc $^ -o $@
+
+# Using tex-fmt-0.4.1
+# nix profile install github:wgunderwood/tex-fmt
+Lists-Pretty.tex: Lists.tex
+ cp $^ $@
+ tex-fmt $@
+
+Snippet-List-Bulleted.html: Lists-Pretty.html
+ sed -n '48,52p;53q' $^ > $@
+
+Snippet-List-Bulleted.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ sed -n '18,26p;27q' $^ >> $@
+
+Snippet-List-Not-Separated.html: Lists-Pretty.html
+ sed -n '59,60p;61q' $^ > $@
+
+Snippet-List-Not-Separated.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ sed -n '33,36p;37q' $^ >> $@
+
+Snippet-List-Enumerated.html: Lists-Pretty.html
+ sed -n '68,72p;73q' $^ > $@
+
+Snippet-List-Enumerated.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ sed -n '43,51p;52q' $^ >> $@
+
+Snippet-List-Not-Newline.html: Lists-Pretty.html
+ sed -n '80,89p;90q' $^ > $@
+
+Snippet-List-Not-Newline.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ sed -n '58,74p;75q' $^ >> $@
+
+Snippet-List-Multiline-Item.html: Lists-Pretty.html
+ sed -n '97,100p;101q' $^ > $@
+
+Snippet-List-Multiline-Item.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ sed -n '81,90p;91q' $^ >> $@
+
+Snippet-List-Nested-Item.html: Lists-Pretty.html
+ sed -n '108,127p;128q' $^ > $@
+
+Snippet-List-Nested-Item.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ echo "$(HDK_VERB)" >> $@
+ sed -n '97,141p;142q' $^ >> $@
+
+Snippet-List-Indentation.html: Lists-Pretty.html
+ sed -n '135,138p;139q' $^ > $@
+
+Snippet-List-Indentation.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ sed -n '148,155p;156q' $^ >> $@
+
+Snippet-List-Definition.html: Lists-Pretty.html
+ sed -n '146,156p;157q' $^ > $@
+
+Snippet-List-Definition.tex: Lists-Pretty.tex
+ echo "$(HDK_BEGIN)" > $@
+ echo "$(HDK_TT)" >> $@
+ sed -n '162,170p;171q' $^ >> $@
=====================================
utils/haddock/doc/snippets/Snippet-List-Bulleted.html
=====================================
@@ -0,0 +1,5 @@
+<p>This is a bulleted list:</p>
+<ul>
+<li>first item</li>
+<li>second item</li>
+</ul>
=====================================
utils/haddock/doc/snippets/Snippet-List-Bulleted.tex
=====================================
@@ -0,0 +1,10 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+ {\haddockbegindoc
+ This is a bulleted list:\par
+ \vbox{
+ \begin{itemize}
+ \item
+ first item\par
+ \item
+ second item\par
+ \end{itemize}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Definition.html
=====================================
@@ -0,0 +1,11 @@
+<p>This is a definition list:</p>
+<dl>
+<dt><code>foo</code></dt>
+<dd>
+The description of <code>foo</code>.
+</dd>
+<dt><code>bar</code></dt>
+<dd>
+The description of <code>bar</code>.
+</dd>
+</dl>
=====================================
utils/haddock/doc/snippets/Snippet-List-Definition.tex
=====================================
@@ -0,0 +1,11 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+\newcommand{\haddocktt}[1]{{\small \texttt{#1}}}
+ {\haddockbegindoc
+ This is a definition list:\par
+ \vbox{
+ \begin{description}
+ \item[\haddocktt{foo}]\hfill \par
+ The description of \haddocktt{foo}.
+ \item[\haddocktt{bar}]\hfill \par
+ The description of \haddocktt{bar}.
+ \end{description}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Enumerated.html
=====================================
@@ -0,0 +1,5 @@
+<p>This is an, (n) n., enumerated list:</p>
+<ol>
+<li>first item</li>
+<li>second item</li>
+</ol>
=====================================
utils/haddock/doc/snippets/Snippet-List-Enumerated.tex
=====================================
@@ -0,0 +1,10 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+ {\haddockbegindoc
+ This is an, (n) n., enumerated list:\par
+ \vbox{
+ \begin{enumerate}
+ \item
+ first item\par
+ \item
+ second item\par
+ \end{enumerate}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Indentation.html
=====================================
@@ -0,0 +1,4 @@
+<ul>
+<li>foo</li>
+<li>bar</li>
+</ul>
=====================================
utils/haddock/doc/snippets/Snippet-List-Indentation.tex
=====================================
@@ -0,0 +1,9 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+ {\haddockbegindoc
+ \vbox{
+ \begin{itemize}
+ \item
+ foo\par
+ \item
+ bar\par
+ \end{itemize}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Multiline-Item.html
=====================================
@@ -0,0 +1,4 @@
+<ul>
+<li>first item and more content for the first item</li>
+<li>second item and more content for the second item</li>
+</ul>
=====================================
utils/haddock/doc/snippets/Snippet-List-Multiline-Item.tex
=====================================
@@ -0,0 +1,11 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+ {\haddockbegindoc
+ \vbox{
+ \begin{itemize}
+ \item
+ first item
+ and more content for the first item\par
+ \item
+ second item
+ and more content for the second item\par
+ \end{itemize}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Nested-Item.html
=====================================
@@ -0,0 +1,20 @@
+<ul>
+<li><p>Beginning of list This belongs to the list above!</p>
+<pre><code>nested
+bird
+tracks</code></pre>
+<ul>
+<li><p>Next list More of the indented list.</p>
+<ul>
+<li><p>Deeper</p>
+<pre><code>even code blocks work</code></pre>
+<ul>
+<li><p>Deeper</p>
+<ol>
+<li>Even deeper!</li>
+<li>No newline separation even in indented lists.</li>
+</ol></li>
+</ul></li>
+</ul></li>
+</ul></li>
+</ul>
=====================================
utils/haddock/doc/snippets/Snippet-List-Nested-Item.tex
=====================================
@@ -0,0 +1,47 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+\newcommand{\haddockverb}{\small}
+ {\haddockbegindoc
+ \vbox{
+ \begin{itemize}
+ \item
+ Beginning of list
+ This belongs to the list above!\par
+ \begin{quote}
+ {\haddockverb
+ \begin{verbatim}
+nested
+bird
+tracks
+ \end{verbatim}}
+ \end{quote}
+ \vbox{
+ \begin{itemize}
+ \item
+ Next list
+ More of the indented list.\par
+ \vbox{
+ \begin{itemize}
+ \item
+ Deeper\par
+ \begin{quote}
+ {\haddockverb
+ \begin{verbatim}
+even code blocks work
+ \end{verbatim}}
+ \end{quote}
+ \vbox{
+ \begin{itemize}
+ \item
+ Deeper\par
+ \vbox{
+ \begin{enumerate}
+ \item
+ Even deeper!\par
+ \item
+ No newline separation even in
+ indented lists.\par
+ \end{enumerate}}
+ \end{itemize}}
+ \end{itemize}}
+ \end{itemize}}
+ \end{itemize}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Not-Newline.html
=====================================
@@ -0,0 +1,10 @@
+<p>This is an enumerated list, with items not separated by newlines:</p>
+<ol>
+<li>first item</li>
+<li>second item</li>
+</ol>
+<p>This is a bulleted list, with items not separated by newlines:</p>
+<ul>
+<li>first item</li>
+<li>second item</li>
+</ul>
=====================================
utils/haddock/doc/snippets/Snippet-List-Not-Newline.tex
=====================================
@@ -0,0 +1,18 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+ {\haddockbegindoc
+ This is an enumerated list, with items not separated by newlines:\par
+ \vbox{
+ \begin{enumerate}
+ \item
+ first item\par
+ \item
+ second item\par
+ \end{enumerate}}
+ This is a bulleted list, with items not separated by newlines:\par
+ \vbox{
+ \begin{itemize}
+ \item
+ first item\par
+ \item
+ second item\par
+ \end{itemize}}}
=====================================
utils/haddock/doc/snippets/Snippet-List-Not-Separated.html
=====================================
@@ -0,0 +1,2 @@
+<p><strong>Missing blank lines</strong> before a list: * first item *
+second item</p>
=====================================
utils/haddock/doc/snippets/Snippet-List-Not-Separated.tex
=====================================
@@ -0,0 +1,5 @@
+\newcommand{\haddockbegindoc}{\hfill\\[1ex]}
+ {\haddockbegindoc
+ \textbf{Missing blank lines} before a list:
+ * first item
+ * second item\par}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/10b4d3641f6fe7a7443bd621d62d13…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/10b4d3641f6fe7a7443bd621d62d13…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/ghci-load-all-targets] 42 commits: Remove exprIsCheap from doFloatFromRhs
by Hannes Siebenhandl (@fendor) 18 Feb '26
by Hannes Siebenhandl (@fendor) 18 Feb '26
18 Feb '26
Hannes Siebenhandl pushed to branch wip/fendor/ghci-load-all-targets at Glasgow Haskell Compiler / GHC
Commits:
2b4f463c by Simon Peyton Jones at 2026-02-02T17:32:32+00:00
Remove exprIsCheap from doFloatFromRhs
See #26854 and Note [Float when expandable]
This patch simplifies the code, by removing an extra unnecessary test.
- - - - -
9db7f21f by Brandon Chinn at 2026-02-03T09:15:10-05:00
Refactor: make function patterns exhaustive
Also added missing (==) logic for:
* HsMultilineString
* HsInt{8,16,32}
* HsWord{8,16,32}
- - - - -
aa9c5e2c by Hécate Kleidukos at 2026-02-03T15:58:35-05:00
driver: Hide source paths at verbosity level 1 by default
- - - - -
c64cca1e by mangoiv at 2026-02-03T15:59:29-05:00
ExplicitLevelImports: check staging for types just like for values
Previously, imported types were entirely exempted from staging checks as
the implicit stage persistance assumed to be all imported types to be
well staged. ExplicitLevelImports' change specification, however, does
not do such an exemption. Thus we want to introduce such a check, just
like we have for values.
ExplicitLevelImports does not, however, talk about local names - from
its perspective, we could theoretically keep treating locally introduced
types specially - e.g. an ill-staged used in a quote would only emit a
warning, not an error. To allow for a potential future migration away
from such wrinkles as the staging check in notFound
(see Note [Out of scope might be a staging error]) we consistently do
the strict staging check that we also do for value if ExplicitLevelImports
is on.
Closes #26098
- - - - -
5f0dbeb6 by Simon Hengel at 2026-02-03T16:00:12-05:00
Use Haddock formatting in deprecation message of `initNameCache`
- - - - -
01ecb612 by Andreas Klebinger at 2026-02-04T09:56:25-05:00
testsuite: Explicitly use utf-8 encoding in rts-includes linter.
Not doing so caused failures on windows, as python failed to pick a
reasonable encoding even with locale set.
Fixes #26850
- - - - -
ea0d1317 by Zubin Duggal at 2026-02-04T09:57:06-05:00
Bump transformers submodule to 0.6.3.0
Fixes #26790
- - - - -
cbe4300e by Simon Peyton Jones at 2026-02-05T04:31:04-05:00
Fix subtle bug in GHC.Core.Utils.mkTick
This patch fixes a decade-old bug in `mkTick`, which
could generate type-incorrect code! See the diagnosis
in #26772.
The new code is simpler and easier to understand.
(As #26772 says, I think it could be improved further.)
- - - - -
a193a8da by Simon Peyton Jones at 2026-02-05T04:31:04-05:00
Modify a debug-trace in the Simplifier
...just to show a bit more information.
- - - - -
b579dfdc by Simon Peyton Jones at 2026-02-05T04:31:04-05:00
Fix long-standing interaction between ticks and casts
The code for Note [Eliminate Identity Cases] was simply wrong when
ticks and casts interacted. This patch fixes the interaction.
It was shown up when validating #26772, although it's not the exactly
the bug that's reported by #26772. Nor is it easy to reproduce, hence
no regression test.
- - - - -
fac0de1e by Cheng Shao at 2026-02-05T04:31:49-05:00
libraries: bump Cabal submodule to 3.16.1.0
- - - - -
00589122 by Cheng Shao at 2026-02-05T04:31:49-05:00
libraries: bump deepseq submodule to 1.5.2.0
Also:
- Get rid of usage of deprecated `NFData` function instance in the
compiler
- `T21391` still relies on `NFData` function instance, add
`-Wno-deprecations` for the time being.
- - - - -
84474c71 by Cheng Shao at 2026-02-05T04:31:50-05:00
libraries: bump directory submodule to 1.3.10.1
- - - - -
1a9f4662 by Cheng Shao at 2026-02-05T04:31:50-05:00
libraries: bump exceptions submodule to 0.10.12
- - - - -
2e39a340 by Peng Fan at 2026-02-07T03:42:01-05:00
NCG/LA64: adjust register usage to avoid src-register being clobbered
- - - - -
9faf1b35 by Teo Camarasu at 2026-02-07T03:42:43-05:00
ghc-internal: Delete unnecessary GHC.Internal.Data.Ix
This module merely re-exports GHC.Internal.Ix. It was copied from
`base` when `ghc-internal` was split, but there is no reason to have
this now. So, let's delete it.
Resolves #26848
- - - - -
d112b440 by Sven Tennie at 2026-02-07T10:47:56-05:00
Add cabal.project file to generate-ci
This fixes the HLS setup for our CI code generation script
(generate-ci).
The project file simply makes `generate-ci` of the cabal file
discoverable.
- - - - -
5339f6f0 by Andreas Klebinger at 2026-02-07T10:48:40-05:00
CI: Don't collapse test results.
This puts test output back into the primary test log instead of a
subsection removing the need to expand a section to see test results.
While the intention was good in practice the old behaviour mostly wastes time
by requiring expansion of the section.
Fixes #26882
- - - - -
0e1cd2e0 by Evan Piro at 2026-02-08T10:35:16-08:00
Linker.MacOS reduce dynflags import
- - - - -
1c79a4cd by Michael Alan Dorman at 2026-02-09T08:11:51-05:00
Remove `extra_src_files` variable from `testsuite/driver/testlib.py`
While reading through the test harness code, I noticed this variable
with a TODO attached that referenced #12223. Although that bug is
closed, it strongly implied that this special-case variable that only
affected a single test was expected to be removed at some point.
I also looked at 3415bcaa0b1903b5e12dfaadb5b774718e406eab---where it
was added---whose commit message suggested that it would have been
desirable to remove it, but that there were special circumstances that
meant it had to remain (though it doesn't elucidate what those special
circumstances are).
However, the special circumstances were mentioned as if the test was
in a different location than is currently is, so I decided to try
changing the test to use the standard `extra_files` mechanism, which
works in local testing.
This also seems like a reasonable time to remove the script that was
originally used in the transition, since it doesn't really serve a
purpose anymore.
- - - - -
0020e38a by Matthew Pickering at 2026-02-09T17:29:14-05:00
determinism: Use a stable sort in WithHsDocIdentifiers binary instance
`WithHsDocIdentifiers` is defined as
```
71 data WithHsDocIdentifiers a pass = WithHsDocIdentifiers
72 { hsDocString :: !a
73 , hsDocIdentifiers :: ![Located (IdP pass)]
74 }
```
This list of names is populated from `rnHsDocIdentifiers`, which calls
`lookupGRE`, which calls `lookupOccEnv_AllNameSpaces`, which calls
`nonDetEltsUFM` and returns the results in an order depending on
uniques.
Sorting the list with a stable sort before returning the interface makes
the output deterministic and follows the approach taken by other fields
in `Docs`.
Fixes #26858
- - - - -
89898ce6 by echoumcp1 at 2026-02-09T17:30:01-05:00
Replace putstrln with logMsg in handleSeqHValueStatus
Fixes #26549
- - - - -
7c52c4f9 by John Paul Adrian Glaubitz at 2026-02-10T13:52:43-05:00
rts: Switch prim to use modern atomic compiler builtins
The __sync_*() atomic compiler builtins have been deprecated in GCC
for a while now and also don't provide variants for 64-bit values
such as __sync_fetch_and_add_8().
Thus, replace them with the modern __atomic_*() compiler builtins and
while we're at it, also drop the helper macro CAS_NAND() which is now
no longer needed since we stopped using the __sync_*() compiler builtins
altogether.
Co-authored-by: Ilias Tsitsimpis <iliastsi(a)debian.org>
Fixes #26729
- - - - -
cf60850a by Recursion Ninja at 2026-02-10T13:53:27-05:00
Decoupling L.H.S.Decls from GHC.Types.ForeignCall
- Adding TTG extension point for 'CCallTarget'
- Adding TTG extension point for 'CType'
- Adding TTG extension point for 'Header'
- Moving ForeignCall types that do not need extension
to new L.H.S.Decls.Foreign module
- Replacing 'Bool' parameters with descriptive data-types
to increase clairty and prevent "Boolean Blindness"
- - - - -
11a04cbb by Eric Lee at 2026-02-11T09:20:46-05:00
Derive Semigroup/Monoid for instances believed could be derived in #25871
- - - - -
15d9ce44 by Eric Lee at 2026-02-11T09:20:46-05:00
add Ghc.Data.Pair deriving
- - - - -
c85dc170 by Evan Piro at 2026-02-11T09:21:45-05:00
Linker.MacOS reduce options import
- - - - -
a541dd83 by Chris Wendt at 2026-02-11T16:06:41-05:00
Initialize plugins for `:set +c` in GHCi
Fixes #23110.
- - - - -
0f5a73bc by Cheng Shao at 2026-02-11T16:07:27-05:00
compiler: add Binary Text instance
This patch adds `Binary` instance for strict `Text`, in preparation of
making `Text` usable in certain GHC API use cases (e.g. haddock). This
also introduces `text` as a direct dependency of the `ghc` package.
- - - - -
9e58b8a1 by Cheng Shao at 2026-02-11T16:08:10-05:00
ghc-toolchain: add C11 check
This patch partially reverts commit
b8307eab80c5809df5405d76c822bf86877f5960 that removed C99 check in
autoconf/ghc-toolchain. Now we:
- No longer re-implement `FP_SET_CFLAGS_C11` similar to
`FP_SET_CFLAGS_C99` in the past, since autoconf doesn't provide a
convenient `AC_PROG_CC_C11` function. ghc-toolchain will handle it
anyway.
- The Cmm CPP C99 check is relanded and repurposed for C11.
- The C99 logic in ghc-toolchain is relanded and repurposed for C11.
- The C99 check in Stg.h is corrected to check for C11. The obsolete
_ISOC99_SOURCE trick is dropped.
- Usages of `-std=gnu99` in the testsuite are corrected to use
`-std=gnu11`.
Closes #26908.
- - - - -
4df0adf6 by Simon Peyton Jones at 2026-02-11T21:50:13-05:00
Simplify the treatment of static forms
This MR implements GHC proposal 732: simplify static forms,
https://github.com/ghc-proposals/ghc-proposals/pull/732
thereby addressing #26556.
See `Note [Grand plan for static forms]` in GHC.Iface.Tidy.StaticPtrTable
The main changes are:
* There is a new, simple rule for (static e), namely that the free
term variables of `e` must be bound at top level. The check is
done in the `HsStatic` case of `GHC.Rename.Expr.rnExpr`
* That in turn substantially simplifies the info that the typechecker
carries around in its type environment. Hooray.
* The desugarer emits static bindings to top level directly; see the
`HsStatic` case of `dsExpr`.
* There is no longer any special static-related magic in the FloatOut
pass. And the main Simplifier pipeline no longer needs a special case
to run FloatOut even with -O0. Hooray.
All this forced an unexpected change to the pattern match checker. It
recursively invokes the main Hs desugarer when it wants to take a look
at a term to spot some special cases (notably constructor applications).
We don't want to emit any nested (static e) bindings to top level a
second time! Yikes.
That forced a modest refactor in GHC.HsToCore.Pmc:
* The `dsl_nablas` field of `DsLclEnv` now has a `NoPmc` case, which says
"I'm desugaring just for pattern-match checking purposes".
* When that flag is set we don't emit static binds.
That in turn forces a cascade of refactoring, but the net effect is an
improvement; less risk of duplicated (even exponential?) work.
See Note [Desugaring HsExpr during pattern-match checking].
10% metric decrease, on some architectures, of compile-time max-bytes-used on T15304.
Metric Decrease:
T15304
- - - - -
7922f728 by Teo Camarasu at 2026-02-11T21:50:58-05:00
ghc-internal: avoid depending on GHC.Internal.Exts
This module is mostly just re-exports. It made sense as a user-facing
module, but there's no good reason ghc-internal modules should depend on
it and doing so linearises the module graph
- move considerAccessible to GHC.Internal.Magic
Previously it lived in GHC.Internal.Exts, but it really deserves to live
along with the other magic function, which are already re-exported from .Exts
- move maxTupleSize to GHC.Internal.Tuple
This previously lived in GHC.Internal.Exts but a comment already said it
should be moved to .Tuple
Resolves #26832
- - - - -
b6a4a29b by Eric Lee at 2026-02-11T21:51:55-05:00
Remove unused Semigroup imports to fix GHC 9.14 bootstrapping
- - - - -
99d8c146 by Simon Peyton Jones at 2026-02-12T17:36:59+00:00
Fix subtle bug in cast worker/wrapper
See (CWw4) in Note [Cast worker/wrapper].
The true payload is in the change to the definition of
GHC.Types.Id.Info.hasInlineUnfolding
Everthing else is just documentation.
There is a 2% compile time decrease for T13056;
I'll take the win!
Metric Decrease:
T13056
- - - - -
530e8e58 by Simon Peyton Jones at 2026-02-12T20:17:23-05:00
Add regression tests for four StaticPtr bugs
Tickets #26545, #24464, #24773, #16981 are all solved by the
recently-landed MR
commit 318ee13bcffa6aa8df42ba442ccd92aa0f7e210c
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Oct 20 23:07:20 2025 +0100
Simplify the treatment of static forms
This MR just adds regression tests for them.
- - - - -
4157160f by Cheng Shao at 2026-02-13T06:27:04-05:00
ci: remove unused hlint-ghc-and-base job definition
This patch removes the unused `hlint-ghc-and-base` job definition,
it's never run since !9806. Note that hadrian lint rules still work
locally, so anyone that wishes to run hlint on the codebase can
continue to do so in their local worktree.
- - - - -
039f1977 by Cheng Shao at 2026-02-13T06:27:47-05:00
wasm: use import.meta.main for proper distinction of nodejs main modules
This patch uses `import.meta.main` for proper distinction of nodejs
main modules, especially when the main module might be installed as a
symlink. Fixes #26916.
- - - - -
14f485ee by ARATA Mizuki at 2026-02-17T09:09:24+09:00
Support more x86 extensions: AVX-512 {BW,DQ,VL} and GFNI
Also, mark AVX-512 ER and PF as deprecated.
AVX-512 instructions can be used for certain 64-bit integer vector operations.
GFNI can be used to implement bitReverse (currently not used by NCG, but LLVM may use it).
Closes #26406
Addresses #26509
- - - - -
016f79d5 by fendor at 2026-02-17T09:16:16-05:00
Hide implementation details from base exception stack traces
Ensure we hide the implementation details of the exception throwing mechanisms:
* `undefined`
* `throwSTM`
* `throw`
* `throwIO`
* `error`
The `HasCallStackBacktrace` should always have a length of exactly 1,
not showing internal implementation details in the stack trace, as these
are vastly distracting to end users.
CLC proposal [#387](https://github.com/haskell/core-libraries-committee/issues/387)
- - - - -
4f2840f2 by Brian J. Cardiff at 2026-02-17T17:04:08-05:00
configure: Accept happy-2.2
In Jan 2026 happy-2.2 was released. The most sensible change is https://github.com/haskell/happy/issues/335 which didn't trigger in a fresh build
- - - - -
10b4d364 by Duncan Coutts at 2026-02-17T17:04:52-05:00
Fix errors in the documentation of the eventlog STOP_THREAD status codes
Fix the code for BlockedOnMsgThrowTo.
Document all the known historical warts.
Fixes issue #26867
- - - - -
edb1e67f by fendor at 2026-02-18T10:16:38+01:00
Introduce `-fimport-loaded-targets` GHCi flag
This new flag automatically adds all loaded targets to the GHCi session
by adding an `InteractiveImport` for the loaded targets.
By default, this flag is disabled, as it potentially increases memory-usage.
This interacts with the flag `-fno-load-initial-targets` as follows:
* If no module is loaded, no module is added as an interactive import.
* If a reload loads up to a module, all loaded modules are added as
interactive imports.
* Unloading modules removes them from the interactive context.
Fixes #26866 by rendering the use of a `-ghci-script` to achieve the
same thing redundant.
- - - - -
316 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- + .gitlab/generate-ci/cabal.project
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/CoreToStg/AddImplicitBinds.hs
- compiler/GHC/Data/Pair.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Doc.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Foreign/Call.hs
- compiler/GHC/HsToCore/Foreign/Decl.hs
- compiler/GHC/HsToCore/Foreign/JavaScript.hs
- compiler/GHC/HsToCore/Foreign/Utils.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/GuardedRHSs.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Linker/MacOS.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Splice.hs-boot
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Foreign.hs
- compiler/GHC/StgToJS/FFI.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Foreign.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/BasicTypes.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- − compiler/GHC/Tc/Utils/TcMType.hs-boot
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Unique/DSet.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Ppr/Colour.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- + compiler/Language/Haskell/Syntax/Decls/Foreign.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/eventlog-formats.rst
- docs/users_guide/ghci.rst
- docs/users_guide/phases.rst
- docs/users_guide/using.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Info.hs
- hadrian/src/Settings/Builders/RunTest.hs
- libraries/Cabal
- libraries/base/changelog.md
- libraries/base/src/Data/Ix.hs
- libraries/deepseq
- libraries/directory
- libraries/exceptions
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Ix.hs
- libraries/ghc-internal/src/GHC/Internal/Exception.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Foreign/Callback.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim/Internal/Build.hs
- libraries/ghc-internal/src/GHC/Internal/Magic.hs
- libraries/ghc-internal/src/GHC/Internal/STM.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/Tuple.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Exports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Imports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Types.hs
- + libraries/ghc-internal/tests/backtraces/T15395.hs
- + libraries/ghc-internal/tests/backtraces/T15395.stdout
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- libraries/transformers
- m4/fp_cmm_cpp_cmd_with_args.m4
- m4/fptools_happy.m4
- rts/include/Stg.h
- rts/prim/atomic.c
- testsuite/driver/cpu_features.py
- − testsuite/driver/kill_extra_files.py
- testsuite/driver/testlib.py
- testsuite/mk/test.mk
- testsuite/tests/arrows/should_compile/T21301.stderr
- testsuite/tests/backpack/cabal/bkpcabal08/bkpcabal08.stdout
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-minmax.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-int64-mul.hs
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.asm
- + testsuite/tests/codeGen/should_gen_asm/avx512-word64-minmax.hs
- testsuite/tests/codeGen/should_run/CgStaticPointers.hs
- testsuite/tests/codeGen/should_run/CgStaticPointersNoFullLazyness.hs
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/deSugar/should_fail/DsStrictFail.stderr
- testsuite/tests/deSugar/should_run/T20024.stderr
- testsuite/tests/deSugar/should_run/dsrun005.stderr
- testsuite/tests/deSugar/should_run/dsrun007.stderr
- testsuite/tests/deSugar/should_run/dsrun008.stderr
- testsuite/tests/deriving/should_run/T9576.stderr
- testsuite/tests/driver/T20030/test1/all.T
- testsuite/tests/driver/T20030/test2/all.T
- testsuite/tests/driver/T20030/test3/all.T
- testsuite/tests/driver/T20030/test4/all.T
- testsuite/tests/driver/T20030/test5/all.T
- testsuite/tests/driver/T20030/test6/all.T
- testsuite/tests/driver/T8526/T8526.script
- testsuite/tests/driver/bytecode-object/Makefile
- testsuite/tests/driver/bytecode-object/bytecode_object19.stdout
- testsuite/tests/driver/dynamicToo/dynamicToo001/Makefile
- testsuite/tests/driver/fat-iface/fat014.script
- testsuite/tests/driver/implicit-dyn-too/Makefile
- testsuite/tests/driver/multipleHomeUnits/all.T
- testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits_recomp_th.stdout
- testsuite/tests/ffi/should_run/all.T
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- − testsuite/tests/ghci/linking/T11531.stderr
- testsuite/tests/ghci/prog-mhu005/Makefile
- testsuite/tests/ghci/prog-mhu005/all.T
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005b.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005b.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005c.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005c.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005c.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005d.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005d.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005d.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005e.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005e.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005e.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005f.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005f.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005f.stdout
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005g.script
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005g.stderr
- + testsuite/tests/ghci/prog-mhu005/prog-mhu005g.stdout
- testsuite/tests/ghci/prog018/prog018.script
- testsuite/tests/ghci/prog022/Makefile
- testsuite/tests/ghci/prog022/all.T
- + testsuite/tests/ghci/prog022/ghci.prog022c.script
- + testsuite/tests/ghci/prog022/ghci.prog022c.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022c.stdout
- + testsuite/tests/ghci/prog022/ghci.prog022d.script
- + testsuite/tests/ghci/prog022/ghci.prog022d.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022d.stdout
- + testsuite/tests/ghci/prog022/ghci.prog022e.script
- + testsuite/tests/ghci/prog022/ghci.prog022e.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022e.stdout
- + testsuite/tests/ghci/prog022/ghci.prog022f.script
- + testsuite/tests/ghci/prog022/ghci.prog022f.stderr
- + testsuite/tests/ghci/prog022/ghci.prog022f.stdout
- testsuite/tests/ghci/scripts/Defer02.stderr
- testsuite/tests/ghci/scripts/T13869.script
- testsuite/tests/ghci/scripts/T13997.script
- testsuite/tests/ghci/scripts/T15325.stderr
- testsuite/tests/ghci/scripts/T17669.script
- testsuite/tests/ghci/scripts/T18330.script
- testsuite/tests/ghci/scripts/T18330.stdout
- testsuite/tests/ghci/scripts/T1914.script
- testsuite/tests/ghci/scripts/T20150.stdout
- testsuite/tests/ghci/scripts/T20217.script
- testsuite/tests/ghci/scripts/T6105.script
- testsuite/tests/ghci/scripts/T8042.script
- testsuite/tests/ghci/scripts/T8042recomp.script
- testsuite/tests/ghci/should_run/Makefile
- 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/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/linters/regex-linters/check-rts-includes.py
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/patsyn/should_run/ghci.stderr
- + testsuite/tests/plugins/T23110.hs
- + testsuite/tests/plugins/T23110.script
- + testsuite/tests/plugins/T23110.stdout
- testsuite/tests/plugins/all.T
- testsuite/tests/process/all.T
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/rename/should_fail/RnStaticPointersFail01.stderr
- testsuite/tests/rename/should_fail/RnStaticPointersFail03.stderr
- + testsuite/tests/rename/should_fail/T26545.hs
- + testsuite/tests/rename/should_fail/T26545.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/rts/T13676.script
- testsuite/tests/safeHaskell/safeLanguage/SafeLang15.stderr
- testsuite/tests/showIface/DocsInHiFile1.stdout
- testsuite/tests/showIface/HaddockSpanIssueT24378.stdout
- testsuite/tests/showIface/MagicHashInHaddocks.stdout
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/simplCore/should_compile/T21391.hs
- + testsuite/tests/simplCore/should_compile/T26903.hs
- + testsuite/tests/simplCore/should_compile/T26903.stderr
- testsuite/tests/simplCore/should_compile/T8331.stderr
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/th/T26098A_quote.hs
- + testsuite/tests/th/T26098A_splice.hs
- + testsuite/tests/th/T26098_local.hs
- + testsuite/tests/th/T26098_local.stderr
- + testsuite/tests/th/T26098_quote.hs
- + testsuite/tests/th/T26098_quote.stderr
- + testsuite/tests/th/T26098_splice.hs
- + testsuite/tests/th/T26098_splice.stderr
- testsuite/tests/th/all.T
- testsuite/tests/type-data/should_run/T22332a.stderr
- + testsuite/tests/typecheck/should_compile/T24464.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_run/T10284.stderr
- testsuite/tests/typecheck/should_run/T13838.stderr
- + testsuite/tests/typecheck/should_run/T16981.hs
- + testsuite/tests/typecheck/should_run/T16981.stdout
- + testsuite/tests/typecheck/should_run/T24773.hs
- + testsuite/tests/typecheck/should_run/T24773.stdout
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
- testsuite/tests/typecheck/should_run/all.T
- testsuite/tests/unsatisfiable/T23816.stderr
- testsuite/tests/unsatisfiable/UnsatDefer.stderr
- testsuite/tests/warnings/should_fail/CaretDiagnostics1.stderr
- utils/check-exact/ExactPrint.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
- utils/haddock/haddock-api/src/Haddock/Interface/LexParseRn.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/jsffi/dyld.mjs
- utils/jsffi/post-link.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a349b9ba7a7ccbf3753ecd4cabdcbd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a349b9ba7a7ccbf3753ecd4cabdcbd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0