summaryrefslogtreecommitdiff
path: root/compiler/GHC/Driver/MakeFile.hs
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2020-04-30 11:09:24 -0400
committerCale Gibbard <cgibbard@gmail.com>2020-12-28 12:28:35 -0500
commit2113a1d600e579bb0f54a0526a03626f105c0365 (patch)
tree746a62bb019f399f3921fdfb1f1f15ae521f6c90 /compiler/GHC/Driver/MakeFile.hs
parentcbc7c3dda6bdf4acb760ca9eb545faeb98ab0dbe (diff)
downloadhaskell-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/Driver/MakeFile.hs')
-rw-r--r--compiler/GHC/Driver/MakeFile.hs23
1 files changed, 17 insertions, 6 deletions
diff --git a/compiler/GHC/Driver/MakeFile.hs b/compiler/GHC/Driver/MakeFile.hs
index 86262c5ab4..b54bbbea3e 100644
--- a/compiler/GHC/Driver/MakeFile.hs
+++ b/compiler/GHC/Driver/MakeFile.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP #-}
+{-# LANGUAGE LambdaCase #-}
-----------------------------------------------------------------------------
--
@@ -186,7 +187,7 @@ processDeps :: DynFlags
-> [ModuleName]
-> FilePath
-> Handle -- Write dependencies to here
- -> SCC ModSummary
+ -> SCC ModuleGraphNode
-> IO ()
-- Write suitable dependencies to handle
-- Always:
@@ -205,9 +206,17 @@ processDeps :: DynFlags
processDeps dflags _ _ _ _ (CyclicSCC nodes)
= -- There shouldn't be any cycles; report them
- throwGhcExceptionIO (ProgramError (showSDoc dflags $ GHC.cyclicModuleErr nodes))
+ throwGhcExceptionIO $ ProgramError $
+ showSDoc dflags $ GHC.cyclicModuleErr nodes
-processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC node)
+processDeps dflags _ _ _ _ (AcyclicSCC (InstantiationNode node))
+ = -- There shouldn't be any backpack instantiations; report them as well
+ throwGhcExceptionIO $ ProgramError $
+ showSDoc dflags $
+ vcat [ text "Unexpected backpack instantiation in dependency graph while constructing Makefile:"
+ , nest 2 $ ppr node ]
+
+processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC (ModuleNode (ExtendedModSummary node _)))
= do { let extra_suffixes = depSuffixes dflags
include_pkg_deps = depIncludePkgDeps dflags
src_file = msHsFilePath node
@@ -371,10 +380,12 @@ dumpModCycles dflags module_graph
| otherwise
= putMsg dflags (hang (text "Module cycles found:") 2 pp_cycles)
where
+ topoSort = filterToposortToModules $
+ GHC.topSortModuleGraph True module_graph Nothing
cycles :: [[ModSummary]]
cycles =
- [ c | CyclicSCC c <- GHC.topSortModuleGraph True module_graph Nothing ]
+ [ c | CyclicSCC c <- topoSort ]
pp_cycles = vcat [ (text "---------- Cycle" <+> int n <+> ptext (sLit "----------"))
$$ pprCycle c $$ blankLine
@@ -402,8 +413,8 @@ pprCycle summaries = pp_group (CyclicSCC summaries)
loop_breaker = head boot_only
all_others = tail boot_only ++ others
- groups =
- GHC.topSortModuleGraph True (mkModuleGraph all_others) Nothing
+ groups = filterToposortToModules $
+ GHC.topSortModuleGraph True (mkModuleGraph $ extendModSummaryNoDeps <$> all_others) Nothing
pp_ms summary = text mod_str <> text (take (20 - length mod_str) (repeat ' '))
<+> (pp_imps empty (map snd (ms_imps summary)) $$