Safe Haskell | None |
---|---|
Language | GHC2021 |
The HomePackageTable
(HPT) contains information about all modules that are part
of a home package. At its core, the information for each module is a
HomeModInfo
.
During upsweep, the HPT is a monotonically increasing data structure: it
only ever gets extended by inserting modules which are loaded and for which
we discover the information required to construct a ModInfo
.
There should only ever exist one single HPT for any given home unit. It's crucial we don't accidentally leak HPTs (e.g. by filtering it, which used to happen -- #25511), so the HPT is mutable and only its reference should be shared. This is alright because the modules don't change throughout compilation.
:::WARNING:::
If you intend to change this interface, consider carefully whether you are
exposing memory-leak footguns which may end up being misused in the compiler
eventually. For instance, if you really, really, end up needing a way to take
a snapshot of the IORef (think: do you really need to?), at least make
obvious in the name like snapshotCopyHpt
.
Or, do you really need a function to traverse all modules in the HPT? It is
often better to keep the computation internal to this module, such as in
hptCollectObjects
...
Synopsis
- newtype HomePackageTable = HPT {}
- emptyHomePackageTable :: IO HomePackageTable
- lookupHpt :: HomePackageTable -> ModuleName -> IO (Maybe HomeModInfo)
- lookupHptByModule :: HomePackageTable -> Module -> IO (Maybe HomeModInfo)
- addHomeModInfoToHpt :: HomeModInfo -> HomePackageTable -> IO ()
- addHomeModInfosToHpt :: HomePackageTable -> [HomeModInfo] -> IO ()
- restrictHpt :: HomePackageTable -> [HomeModInfo] -> IO ()
- hptCompleteSigs :: HomePackageTable -> IO CompleteMatches
- hptAllInstances :: HomePackageTable -> IO (InstEnv, [FamInst])
- hptAllFamInstances :: HomePackageTable -> IO (ModuleEnv FamInstEnv)
- hptAllAnnotations :: HomePackageTable -> IO AnnEnv
- hptCollectDependencies :: HomePackageTable -> IO (Set UnitId)
- hptCollectObjects :: HomePackageTable -> IO [Linkable]
- hptCollectModules :: HomePackageTable -> IO [Module]
- concatHpt :: (HomeModInfo -> [a]) -> HomePackageTable -> IO [a]
- pprHPT :: HomePackageTable -> IO SDoc
- hptInternalTableRef :: HomePackageTable -> IORef (DModuleNameEnv HomeModInfo)
- hptInternalTableFromRef :: IORef (DModuleNameEnv HomeModInfo) -> IO HomePackageTable
- addToHpt :: HomePackageTable -> ModuleName -> HomeModInfo -> IO ()
- addListToHpt :: HomePackageTable -> [(ModuleName, HomeModInfo)] -> IO ()
Documentation
newtype HomePackageTable Source #
Helps us find information about modules in the home package
HPT | |
|
emptyHomePackageTable :: IO HomePackageTable Source #
Create a new HomePackageTable
.
Be careful not to share it across e.g. different units, since it uses a mutable variable under the hood to keep the monotonically increasing list of loaded modules.
Lookups in the HPT
lookupHpt :: HomePackageTable -> ModuleName -> IO (Maybe HomeModInfo) Source #
Lookup the HomeModInfo
of a module in the HPT, given its name.
lookupHptByModule :: HomePackageTable -> Module -> IO (Maybe HomeModInfo) Source #
Lookup the HomeModInfo
of a Module
in the HPT.
Extending the HPT
addHomeModInfoToHpt :: HomeModInfo -> HomePackageTable -> IO () Source #
Add a new module to the HPT.
An HPT is a monotonically increasing data structure, holding information about loaded modules in a package. This is the main function by which the HPT is extended or updated.
When the module of the inserted HomeModInfo
does not exist, a new entry in
the HPT is created for that module name.
When the module already has an entry, inserting a new one entry in the HPT
will always overwrite the existing entry for that module.
addHomeModInfosToHpt :: HomePackageTable -> [HomeModInfo] -> IO () Source #
addHomeModInfoToHpt
for multiple module infos.
Restrict the HPT
restrictHpt :: HomePackageTable -> [HomeModInfo] -> IO () Source #
Thin each HPT variable to only contain keys from the given dependencies. This is used at the end of upsweep to make sure that only completely successfully loaded modules are visible for subsequent operations.
This is an exception to the invariant of the HPT -- that it grows monotonically, never removing entries -- which is safe as long as it is only called at barrier points, such as the end of upsweep, when all threads are done and we want to clean up failed entries.
Queries about home modules
hptCompleteSigs :: HomePackageTable -> IO CompleteMatches Source #
Get all CompleteMatches
(arising from COMPLETE pragmas) present in all
modules from this unit's HPT.
hptAllInstances :: HomePackageTable -> IO (InstEnv, [FamInst]) Source #
Find all the instance declarations (of classes and families) from this Home Package Table
hptAllFamInstances :: HomePackageTable -> IO (ModuleEnv FamInstEnv) Source #
Find all the family instance declarations from the HPT
hptAllAnnotations :: HomePackageTable -> IO AnnEnv Source #
All annotations from the HPT
More Traversal-based queries
hptCollectDependencies :: HomePackageTable -> IO (Set UnitId) Source #
Collect the immediate dependencies of all modules in the HPT into a Set.
The immediate dependencies are given by the iface as
.dep_direct_pkgs
. mi_deps
Note: This should be a query on the ModuleGraph
, since we don't really
ever want to collect *all* dependencies. The current caller of this function
currently takes all dependencies only to then filter them with an ad-hoc transitive closure check.
See #25639
hptCollectObjects :: HomePackageTable -> IO [Linkable] Source #
hptCollectModules :: HomePackageTable -> IO [Module] Source #
Memory dangerous queries
concatHpt :: (HomeModInfo -> [a]) -> HomePackageTable -> IO [a] Source #
Like concatMap f .
, but filters out all eltsHpt
HomeModInfo
for which
f
returns the empty list before doing the sort inherent to eltsUDFM
.
If this function is ever exposed from the HPT module, make sure the argument function doesn't introduce leaks.
Utilities
pprHPT :: HomePackageTable -> IO SDoc Source #
Pretty print a HomePackageTable
.
Make sure you really do need to print the whole HPT before infusing too much code with IO.
For instance, in the HUG, it suffices to print the unit-keys present in the unit map in failed lookups.
Internals
These provide access to the internals of the HomePackageTable to facilitate existing workflows that used the previous API. For instance, if you were listing out all elements or merging, you can keep doing so by reading the internal IO ref and then using the moduleenv contents directly.
In GHC itself these should be avoided, and other uses should justify why it is not sufficient to go through the intended insert-only API.
hptInternalTableRef :: HomePackageTable -> IORef (DModuleNameEnv HomeModInfo) Source #
Gets the internal IORef
which holds the HomeModInfo
s of this HPT.
Use with care.
hptInternalTableFromRef :: IORef (DModuleNameEnv HomeModInfo) -> IO HomePackageTable Source #
Construct a HomePackageTable from the IORef. Use with care, only if you can really justify going around the intended insert-only API.
Legacy API
This API is deprecated and meant to be removed.
addToHpt :: HomePackageTable -> ModuleName -> HomeModInfo -> IO () Source #
Deprecated: Deprecated in favour of addHomeModInfoToHpt
, as the module at which a HomeModInfo
is inserted should always be derived from the HomeModInfo
itself.
addListToHpt :: HomePackageTable -> [(ModuleName, HomeModInfo)] -> IO () Source #
Deprecated: Deprecated in favour of addHomeModInfosToHpt
, as the module at which a HomeModInfo
is inserted should always be derived from the HomeModInfo
itself.