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 /ghc/GHCi/UI.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 'ghc/GHCi/UI.hs')
-rw-r--r-- | ghc/GHCi/UI.hs | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs index 152017de38..4a1b91a9fc 100644 --- a/ghc/GHCi/UI.hs +++ b/ghc/GHCi/UI.hs @@ -76,6 +76,7 @@ import qualified GHC.Parser.Lexer as Lexer import GHC.Unit import GHC.Unit.State import GHC.Unit.Finder as Finder +import GHC.Unit.Module.Graph (filterToposortToModules) import GHC.Unit.Module.ModSummary import GHC.Data.StringBuffer @@ -1632,8 +1633,9 @@ chooseEditFile = graph <- GHC.getModuleGraph failed_graph <- - GHC.mkModuleGraph <$> filterM hasFailed (GHC.mgModSummaries graph) - let order g = flattenSCCs $ GHC.topSortModuleGraph True g Nothing + GHC.mkModuleGraph . fmap extendModSummaryNoDeps <$> filterM hasFailed (GHC.mgModSummaries graph) + let order g = flattenSCCs $ filterToposortToModules $ + GHC.topSortModuleGraph True g Nothing pick xs = case xs of x : _ -> GHC.ml_hs_file (GHC.ms_location x) _ -> Nothing @@ -2018,8 +2020,9 @@ setContextAfterLoad keep_ctxt ms = do targets <- GHC.getTargets case [ m | Just m <- map (findTarget ms) targets ] of [] -> - let graph = GHC.mkModuleGraph ms - graph' = flattenSCCs (GHC.topSortModuleGraph True graph Nothing) + let graph = GHC.mkModuleGraph $ extendModSummaryNoDeps <$> ms + graph' = flattenSCCs $ filterToposortToModules $ + GHC.topSortModuleGraph True graph Nothing in load_this (last graph') (m:_) -> load_this m |