diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2020-04-30 11:09:24 -0400 |
---|---|---|
committer | Cale Gibbard <cgibbard@gmail.com> | 2020-12-28 12:28:35 -0500 |
commit | 2113a1d600e579bb0f54a0526a03626f105c0365 (patch) | |
tree | 746a62bb019f399f3921fdfb1f1f15ae521f6c90 /compiler/GHC/Unit/Module/ModSummary.hs | |
parent | cbc7c3dda6bdf4acb760ca9eb545faeb98ab0dbe (diff) | |
download | haskell-2113a1d600e579bb0f54a0526a03626f105c0365.tar.gz |
Put hole instantiation typechecking in the module graph and fix driver batch mode backpack edges
Backpack instantiations need to be typechecked to make sure that the
arguments fit the parameters. `tcRnInstantiateSignature` checks
instantiations with concrete modules, while `tcRnCheckUnit` checks
instantiations with free holes (signatures in the current modules).
Before this change, it worked that `tcRnInstantiateSignature` was called
after typechecking the argument module, see `HscMain.hsc_typecheck`,
while `tcRnCheckUnit` was called in `unsweep'` where-bound in
`GhcMake.upsweep`. `tcRnCheckUnit` was called once per each
instantiation once all the argument sigs were processed. This was done
with simple "to do" and "already done" accumulators in the fold.
`parUpsweep` did not implement the change.
With this change, `tcRnCheckUnit` instead is associated with its own
node in the `ModuleGraph`. Nodes are now:
```haskell
data ModuleGraphNode
-- | Instantiation nodes track the instantiation of other units
-- (backpack dependencies) with the holes (signatures) of the current package.
= InstantiationNode InstantiatedUnit
-- | There is a module summary node for each module, signature, and boot module being built.
| ModuleNode ExtendedModSummary
```
instead of just `ModSummary`; the `InstantiationNode` case is the
instantiation of a unit to be checked. The dependencies of such nodes
are the same "free holes" as was checked with the accumulator before.
Both versions of upsweep on such a node call `tcRnCheckUnit`.
There previously was an `implicitRequirements` function which would
crawl through every non-current-unit module dep to look for all free
holes (signatures) to add as dependencies in `GHC.Driver.Make`. But this
is no good: we shouldn't be looking for transitive anything when
building the graph: the graph should only have immediate edges and the
scheduler takes care that all transitive requirements are met.
So `GHC.Driver.Make` stopped using `implicitRequirements`, and instead
uses a new `implicitRequirementsShallow`, which just returns the
outermost instantiation node (or module name if the immediate dependency
is itself a signature). The signature dependencies are just treated like
any other imported module, but the module ones then go in a list stored
in the `ModuleNode` next to the `ModSummary` as the "extra backpack
dependencies". When `downsweep` creates the mod summaries, it adds this
information too.
------
There is one code quality, and possible correctness thing left: In
addition to `implicitRequirements` there is `findExtraSigImports`, which
says something like "if you are an instantiation argument (you are
substituted or a signature), you need to import its things too". This
is a little non-local so I am not quite sure how to get rid of it in
`GHC.Driver.Make`, but we probably should eventually.
First though, let's try to make a test case that observes that we don't
do this, lest it actually be unneeded. Until then, I'm happy to leave it
as is.
------
Beside the ability to use `-j`, the other major user-visibile side
effect of this change is that that the --make progress log now includes
"Instantiating" messages for these new nodes. Those also are numbered
like module nodes and count towards the total.
------
Fixes #17188
Updates hackage submomdule
Metric Increase:
T12425
T13035
Diffstat (limited to 'compiler/GHC/Unit/Module/ModSummary.hs')
-rw-r--r-- | compiler/GHC/Unit/Module/ModSummary.hs | 57 |
1 files changed, 25 insertions, 32 deletions
diff --git a/compiler/GHC/Unit/Module/ModSummary.hs b/compiler/GHC/Unit/Module/ModSummary.hs index a0b42fc2a4..e9106d44eb 100644 --- a/compiler/GHC/Unit/Module/ModSummary.hs +++ b/compiler/GHC/Unit/Module/ModSummary.hs @@ -1,7 +1,11 @@ +{-# LANGUAGE LambdaCase #-} + -- | A ModSummary is a node in the compilation manager's dependency graph -- (ModuleGraph) module GHC.Unit.Module.ModSummary - ( ModSummary (..) + ( ExtendedModSummary (..) + , extendModSummaryNoDeps + , ModSummary (..) , ms_installed_mod , ms_mod_name , ms_imps @@ -13,7 +17,6 @@ module GHC.Unit.Module.ModSummary , msObjFilePath , msDynObjFilePath , isBootSummary - , showModMsg , findTarget ) where @@ -22,9 +25,7 @@ import GHC.Prelude import GHC.Hs -import GHC.Driver.Ppr import GHC.Driver.Session -import GHC.Driver.Backend import GHC.Unit.Types import GHC.Unit.Module @@ -40,9 +41,24 @@ import GHC.Data.StringBuffer ( StringBuffer ) import GHC.Utils.Outputable import Data.Time -import System.FilePath --- | A single node in a 'ModuleGraph'. The nodes of the module graph +-- | Enrichment of 'ModSummary' with backpack dependencies +data ExtendedModSummary = ExtendedModSummary + { emsModSummary :: {-# UNPACK #-} !ModSummary + , emsInstantiatedUnits :: [InstantiatedUnit] + -- ^ Extra backpack deps + -- NB: This is sometimes left empty in situations where the instantiated units + -- would not be used. See call sites of 'extendModSummaryNoDeps'. + } + +instance Outputable ExtendedModSummary where + ppr = \case + ExtendedModSummary ms bds -> ppr ms <+> ppr bds + +extendModSummaryNoDeps :: ModSummary -> ExtendedModSummary +extendModSummaryNoDeps ms = ExtendedModSummary ms [] + +-- | Data for a module node in a 'ModuleGraph'. Module nodes of the module graph -- are one of: -- -- * A regular Haskell source module @@ -53,7 +69,7 @@ data ModSummary ms_mod :: Module, -- ^ Identity of the module ms_hsc_src :: HscSource, - -- ^ The module source either plain Haskell or hs-boot + -- ^ The module source either plain Haskell, hs-boot, or hsig ms_location :: ModLocation, -- ^ Location of the various files belonging to the module ms_hs_date :: UTCTime, @@ -150,31 +166,6 @@ instance Outputable ModSummary where char '}' ] -showModMsg :: DynFlags -> Bool -> ModSummary -> SDoc -showModMsg dflags recomp mod_summary = - if gopt Opt_HideSourcePaths dflags - then text mod_str - else hsep $ - [ text (mod_str ++ replicate (max 0 (16 - length mod_str)) ' ') - , char '(' - , text (op $ msHsFilePath mod_summary) <> char ',' - ] ++ - if gopt Opt_BuildDynamicToo dflags - then [ text obj_file <> char ',' - , text dyn_file - , char ')' - ] - else [ text obj_file, char ')' ] - where - op = normalise - mod = moduleName (ms_mod mod_summary) - mod_str = showPpr dflags mod ++ hscSourceString (ms_hsc_src mod_summary) - dyn_file = op $ msDynObjFilePath mod_summary dflags - obj_file = case backend dflags of - Interpreter | recomp -> "interpreted" - NoBackend -> "nothing" - _ -> (op $ msObjFilePath mod_summary) - findTarget :: ModSummary -> [Target] -> Maybe Target findTarget ms ts = case filter (matches ms) ts of @@ -188,3 +179,5 @@ findTarget ms ts = = f == f' _ `matches` _ = False + + |