Commit c56de4b8 authored by John Ericson's avatar John Ericson
Browse files

WIP: Put hole instantiation typechecking in the module graph

Backpack instantiations need to be typechecked to make sure that the
arguments fit the parameters. `tcRnInstantiateSignature` checks
instantiations with concrete modules, while `tcRnCheckUnitId` 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 `tcRnCheckUnitId` was called in `unsweep'` where-bound in
`GhcMake.upsweep`. `tcRnCheckUnitId` 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, `tcRnCheckUnitId` instead is associated with its own
node in the `ModuleGraph`. Nodes are now:
```haskell
data WorkGraphNode
  = InstantiationNode IndefUnitId
  | ModuleNode ModSummary
```
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
upsweeps on such a node call `tcRnCheckUnitId`.

The instantiation nodes are not depended on by other nodes; `tcRnCheckUnitId` is
just being called for errors. I do take this as evidence for the argument that
perhaps my patch is over-engineered; one could also just leave the graph as-is
and post upsweep `tcRnCheckUnitId` all unit-ids unconditionally. Now, if there
is extra `-j` sooner one can get the errors quicker than that with mine, but
without the dependencies into the merged node (mimicking the eagerness of the
fold of the sequential upsweep) this isn't guaranteed to happen.

I admit I went with the current approach before I realized that nothing
else depended on the effects for `tcRnCheckUnitId`, but I still think
it is the right one with future changes in mind. For this, I refer to
"Note [Identity versus semantic module]". The current reasoning appeals
to the compilation pipeline invariants, but if we get multi package
support [proposal 23], we could have all three of the original
signature, argument, and instiation in home packages. I think having
separate dependency nodes for each of those 3 might yield more
incrementality and/or parallelism, especially if nodes became per
pipeline stage.

Fixes #17188

Things yet to do:

* [ ]  There are extra numbered steps that don't print out, probably should have some `[m of n] checking instantiation ...`

* [ ]  Errors are rendered slightly differently for some reason

[proposal 23]: https://github.com/ghc-proposals/ghc-proposals/pull/263
parent 5e6a0c7d
Pipeline #11406 passed with stages
in 417 minutes and 49 seconds
......@@ -663,7 +663,8 @@ hsunitModuleGraph dflags unit = do
else fmap Just $ summariseRequirement pn mod_name
-- 3. Return the kaboodle
return $ mkModuleGraph $ nodes ++ req_nodes
return $ mkModuleGraph' $
(ModuleNode <$> (nodes ++ req_nodes)) ++ instantiationNodes dflags
summariseRequirement :: PackageName -> ModuleName -> BkpM ModSummary
summariseRequirement pn mod_name = do
......
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
-----------------------------------------------------------------------------
--
......@@ -23,7 +24,7 @@ import Util
import HscTypes
import qualified SysTools
import Module
import Digraph ( SCC(..) )
import Digraph ( SCC(..))
import Finder
import Outputable
import Panic
......@@ -80,7 +81,8 @@ doMkDependHS srcs = do
-- Sort into dependency order
-- There should be no cycles
let sorted = GHC.topSortModuleGraph False module_graph Nothing
let sorted = filterToposortToModules $
GHC.topSortModuleGraph False module_graph Nothing
-- Print out the dependencies if wanted
liftIO $ debugTraceMsg dflags 2 (text "Module dependencies" $$ ppr sorted)
......@@ -196,7 +198,8 @@ 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 $ fmap ModuleNode nodes
processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC node)
= do { let extra_suffixes = depSuffixes dflags
......@@ -350,10 +353,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
......@@ -381,8 +386,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 $ all_others) Nothing
pp_ms summary = text mod_str <> text (take (20 - length mod_str) (repeat ' '))
<+> (pp_imps empty (map snd (ms_imps summary)) $$
......
This diff is collapsed.
......@@ -4,8 +4,10 @@
\section[HscTypes]{Types for the per-module compiler}
-}
{-# LANGUAGE CPP, ScopedTypeVariables #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | Types for the per-module compiler
module HscTypes (
......@@ -17,8 +19,11 @@ module HscTypes (
IServ(..),
-- * ModuleGraph
ModuleGraph, emptyMG, mkModuleGraph, extendMG, mapMG,
mgModSummaries, mgElemModule, mgLookupModule,
ModuleGraph, WorkGraphNode(..), emptyMG, mapMG,
mkModuleGraph, mkModuleGraph', extendMG, extendMGInst, extendMG',
filterToposortToModules,
mgModSummaries, mgModSummaries',
mgElemModule, mgLookupModule,
needsTemplateHaskellOrQQ, mgBootModules,
-- * Hsc monad
......@@ -173,6 +178,7 @@ import TyCon
import CoAxiom
import ConLike
import DataCon
import Digraph ( SCC, mapMaybeSCC )
import PatSyn
import PrelNames ( gHC_PRIM, ioTyConName, printName, mkInteractiveModule
, eqTyConName )
......@@ -1003,7 +1009,7 @@ mi_free_holes iface =
-- holes are just C.
renameFreeHoles :: UniqDSet ModuleName -> [(ModuleName, Module)] -> UniqDSet ModuleName
renameFreeHoles fhs insts =
unionManyUniqDSets (map lookup_impl (uniqDSetToList fhs))
unionManyUniqDSets $ map lookup_impl $ uniqDSetToList fhs
where
hmap = listToUFM insts
lookup_impl mod_name
......@@ -2654,14 +2660,49 @@ soExt platform
************************************************************************
-}
-- | A ModuleGraph contains all the nodes from the home package (only).
-- There will be a node for each source module, plus a node for each hi-boot
-- module.
-- | A '@WorkGraphNode@' is a node in the '@ModuleGraph@'.
data WorkGraphNode
-- | Instantiation nodes track the instantiation of other units with the
-- holes (signatures) of the current package.
--
-- Longer term, I (@Ericson2314) hope to track more work this way. We could
-- also track the instantiation of other units with already-built (EPS not
-- HPT) modules. If we support recursive backpack linking (even if just
-- limited cyclic unit instantiations which resolve to acyclic module\/sig
-- instantiations). we could track those instantiations too. At some point, we
-- may even wish to deduplicate the implementation for hs-boot and backpack
-- some more, and track the "instantation" of hs-boot with real modules a
-- similar way.
--
-- See Note [Identity versus semantic module]. I don't yet know the specifics,
-- but I suspect that the invariants discussed there interplay with this plan
-- for more explicit instantiations.
= InstantiationNode IndefUnitId
-- | There is a module summary node for each module, signature, and boot module being built.
| ModuleNode ModSummary
-- TODO what do we want here?
instance Outputable WorkGraphNode where
ppr = \case
InstantiationNode iuid -> ppr iuid
ModuleNode ms -> ppr ms
-- TODO deprecate and remove this.
type ModuleGraph = WorkGraph
-- | A '@WorkGraph@' contains all the nodes from the home package (only). See
-- '@WorkGraphNode@' for information about the nodes.
--
-- Modules need to be compiled. hs-boots need to be typechecked before
-- the associated "real" module so modules with {-# SOURCE #-} imports can be
-- built. Instantiations also need to be typechecked to ensure that the module
-- fits the signature. Substantiation typechecking is roughly comparable to the
-- check that the module and its hs-boot agree.
--
-- The graph is not necessarily stored in topologically-sorted order. Use
-- 'GHC.topSortModuleGraph' and 'Digraph.flattenSCC' to achieve this.
data ModuleGraph = ModuleGraph
{ mg_mss :: [ModSummary]
data WorkGraph = ModuleGraph
{ mg_mss :: [WorkGraphNode]
, mg_non_boot :: ModuleEnv ModSummary
-- a map of all non-boot ModSummaries keyed by Modules
, mg_boot :: ModuleSet
......@@ -2684,7 +2725,9 @@ needsTemplateHaskellOrQQ mg = mg_needs_th_or_qq mg
-- To preserve invariants 'f' can't change the isBoot status.
mapMG :: (ModSummary -> ModSummary) -> ModuleGraph -> ModuleGraph
mapMG f mg@ModuleGraph{..} = mg
{ mg_mss = map f mg_mss
{ mg_mss = flip fmap mg_mss $ \case
InstantiationNode iuid -> InstantiationNode iuid
ModuleNode ms -> ModuleNode $ f ms
, mg_non_boot = mapModuleEnv f mg_non_boot
}
......@@ -2692,7 +2735,10 @@ mgBootModules :: ModuleGraph -> ModuleSet
mgBootModules ModuleGraph{..} = mg_boot
mgModSummaries :: ModuleGraph -> [ModSummary]
mgModSummaries = mg_mss
mgModSummaries mg = [ m | ModuleNode m <- mgModSummaries' mg ]
mgModSummaries' :: ModuleGraph -> [WorkGraphNode]
mgModSummaries' = mg_mss
mgElemModule :: ModuleGraph -> Module -> Bool
mgElemModule ModuleGraph{..} m = elemModuleEnv m mg_non_boot
......@@ -2714,7 +2760,7 @@ isTemplateHaskellOrQQNonBoot ms =
-- not an element of the ModuleGraph.
extendMG :: ModuleGraph -> ModSummary -> ModuleGraph
extendMG ModuleGraph{..} ms = ModuleGraph
{ mg_mss = ms:mg_mss
{ mg_mss = ModuleNode ms : mg_mss
, mg_non_boot = if isBootSummary ms
then mg_non_boot
else extendModuleEnv mg_non_boot (ms_mod ms) ms
......@@ -2724,9 +2770,35 @@ extendMG ModuleGraph{..} ms = ModuleGraph
, mg_needs_th_or_qq = mg_needs_th_or_qq || isTemplateHaskellOrQQNonBoot ms
}
extendMGInst :: ModuleGraph -> IndefUnitId -> ModuleGraph
extendMGInst mg depUnitId = mg
{ mg_mss = InstantiationNode depUnitId : mg_mss mg
}
extendMG' :: ModuleGraph -> WorkGraphNode -> ModuleGraph
extendMG' mg = \case
InstantiationNode depUnitId -> extendMGInst mg depUnitId
ModuleNode ms -> extendMG mg ms
mkModuleGraph :: [ModSummary] -> ModuleGraph
mkModuleGraph = foldr (flip extendMG) emptyMG
mkModuleGraph' :: [WorkGraphNode] -> ModuleGraph
mkModuleGraph' = foldr (flip extendMG') emptyMG
-- | This function filters out all the instantiation nodes from a "step" of a
-- topological sort. It's use is somewhat dubious: when '@WorkGraphNode@' was
-- created, replacing '@ModSummary@' as the node type, it was easy to get some
-- uses of the work graph outside of '@GhcMake@' to typecheck again by just
-- filtering out the new nodes. But going forward, as '@InstantiationNodes@'
-- hopefully become more useful, those use sites should be reevaluated as to
-- whether ignoring non-module nodes is really the correct things to do.
filterToposortToModules
:: [SCC WorkGraphNode] -> [SCC ModSummary]
filterToposortToModules = mapMaybe $ mapMaybeSCC $ \case
InstantiationNode _ -> Nothing
ModuleNode node -> Just node
-- | A single node in a 'ModuleGraph'. The nodes of the module graph
-- are one of:
--
......@@ -2738,7 +2810,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,
......
......@@ -240,12 +240,12 @@ requirementMerges dflags mod_name =
-- is something like this:
--
-- unit p where
-- signature A
-- signature B
-- import A
-- signature X
-- signature Y
-- import Y
--
-- unit q where
-- dependency p[A=<A>,B=<B>]
-- dependency p[X=<A>,Y=<B>]
-- signature A
-- signature B
--
......@@ -288,7 +288,7 @@ implicitRequirements hsc_env normal_imports
-- Given a list of 'import M' statements in a module, figure out
-- any extra implicit requirement imports they may have. For
-- example, if they 'import M' and M resolves to p[A=<B>], then
-- example, if they 'import M' and M resolves to p[A=<B>,C=D], then
-- they actually also import the local requirement B.
implicitRequirements' :: HscEnv
-> [(Maybe FastString, Located ModuleName)]
......
-- (c) The University of Glasgow 2006
{-# LANGUAGE CPP, ScopedTypeVariables, ViewPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
module Digraph(
Graph, graphFromEdgedVerticesOrd, graphFromEdgedVerticesUniq,
......@@ -12,6 +15,7 @@ module Digraph(
reachableG, reachablesG, transposeG,
emptyG,
mapMaybeSCC,
findCycle,
-- For backwards compatibility with the simpler version of Digraph
......@@ -195,6 +199,15 @@ reduceNodesIntoVerticesUniq = reduceNodesIntoVertices listToUFM (flip lookupUFM)
************************************************************************
-}
-- TODO upstream to witherable package
mapMaybeSCC :: (a -> Maybe b) -> SCC a -> Maybe (SCC b)
mapMaybeSCC f = \case
AcyclicSCC a -> AcyclicSCC <$> f a
CyclicSCC as -> case mapMaybe f as of
[] -> Nothing
[a] -> Just $ AcyclicSCC a
as -> Just $ CyclicSCC as
type WorkItem key payload
= (Node key payload, -- Tip of the path
[payload]) -- Rest of the path;
......
......@@ -53,7 +53,8 @@ import GHC ( LoadHowMuch(..), Target(..), TargetId(..), InteractiveImport(..),
import HsImpExp
import HsSyn
import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, hsc_IC,
setInteractivePrintName, hsc_dflags, msObjFilePath )
setInteractivePrintName, hsc_dflags, msObjFilePath,
filterToposortToModules )
import Module
import Name
import Packages ( trusted, getPackageDetails, getInstalledPackageDetails,
......@@ -1485,7 +1486,8 @@ chooseEditFile =
graph <- GHC.getModuleGraph
failed_graph <-
GHC.mkModuleGraph <$> filterM hasFailed (GHC.mgModSummaries graph)
let order g = flattenSCCs $ GHC.topSortModuleGraph True g Nothing
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
......@@ -1830,7 +1832,8 @@ setContextAfterLoad keep_ctxt ms = do
case [ m | Just m <- map (findTarget ms) targets ] of
[] ->
let graph = GHC.mkModuleGraph ms
graph' = flattenSCCs (GHC.topSortModuleGraph True graph Nothing)
graph' = flattenSCCs $ filterToposortToModules $
GHC.topSortModuleGraph True graph Nothing
in load_this (last graph')
(m:_) ->
load_this m
......
[1 of 2] Processing h
[1 of 1] Compiling H[sig] ( h/H.hsig, nothing )
[2 of 2] Processing p
[1 of 3] Compiling B ( p/B.hs, nothing )
[2 of 3] Compiling H[sig] ( p/H.hsig, nothing )
[3 of 3] Compiling A ( p/A.hs, nothing )
[1 of 4] Compiling B ( p/B.hs, nothing )
[2 of 4] Compiling H[sig] ( p/H.hsig, nothing )
[3 of 4] Compiling A ( p/A.hs, nothing )
......@@ -5,9 +5,9 @@
Instantiating timpl
[1 of 1] Compiling TImpl ( timpl/TImpl.hs, nothing )
[3 of 5] Processing q
[1 of 3] Compiling T[sig] ( q/T.hsig, nothing )
[2 of 3] Compiling H[sig] ( q/H.hsig, nothing )
[3 of 3] Compiling A ( q/A.hs, nothing )
[1 of 4] Compiling T[sig] ( q/T.hsig, nothing )
[2 of 4] Compiling H[sig] ( q/H.hsig, nothing )
[3 of 4] Compiling A ( q/A.hs, nothing )
[4 of 5] Processing r-impl
Instantiating r-impl
[1 of 1] Including timpl
......@@ -22,6 +22,6 @@
Instantiating p[H=r-impl:H,T=r-impl:T]
[1 of 2] Compiling T[sig] ( p/T.hsig, nothing )
[2 of 2] Compiling H[sig] ( p/H.hsig, nothing )
[1 of 3] Compiling T[sig] ( q/T.hsig, nothing )
[2 of 3] Compiling H[sig] ( q/H.hsig, nothing )
[3 of 3] Compiling A ( q/A.hs, nothing )
[1 of 4] Compiling T[sig] ( q/T.hsig, nothing )
[2 of 4] Compiling H[sig] ( q/H.hsig, nothing )
[3 of 4] Compiling A ( q/A.hs, nothing )
......@@ -4,5 +4,5 @@
[2 of 3] Processing q
[1 of 1] Compiling A2[sig] ( q/A2.hsig, nothing )
[3 of 3] Processing r
[1 of 2] Compiling A1[sig] ( r/A1.hsig, nothing )
[2 of 2] Compiling A2[sig] ( r/A2.hsig, nothing )
[1 of 4] Compiling A1[sig] ( r/A1.hsig, nothing )
[2 of 4] Compiling A2[sig] ( r/A2.hsig, nothing )
......@@ -4,5 +4,5 @@
[2 of 3] Processing p2
[1 of 1] Compiling A[sig] ( p2/A.hsig, nothing )
[3 of 3] Processing p
[1 of 2] Compiling A[sig] ( p/A.hsig, nothing )
[2 of 2] Compiling M ( p/M.hs, nothing )
[1 of 3] Compiling A[sig] ( p/A.hsig, nothing )
[2 of 3] Compiling M ( p/M.hs, nothing )
[1 of 2] Processing p
[1 of 1] Compiling A[sig] ( p/A.hsig, nothing )
[2 of 2] Processing q
[1 of 2] Compiling A[sig] ( q/A.hsig, nothing )
[2 of 2] Compiling M ( q/M.hs, nothing )
[1 of 3] Compiling A[sig] ( q/A.hsig, nothing )
[2 of 3] Compiling M ( q/M.hs, nothing )
[1 of 2] Processing p
[1 of 1] Compiling A[sig] ( p/A.hsig, nothing )
[2 of 2] Processing q
[1 of 2] Compiling A[sig] ( q/A.hsig, nothing )
[2 of 2] Compiling M ( q/M.hs, nothing )
[1 of 3] Compiling A[sig] ( q/A.hsig, nothing )
[2 of 3] Compiling M ( q/M.hs, nothing )
......@@ -24,5 +24,5 @@
[1 of 2] Compiling A[sig] ( p2/A.hsig, nothing )
[2 of 2] Compiling M ( p2/M.hs, nothing )
[7 of 7] Processing p3
[1 of 2] Compiling A[sig] ( p3/A.hsig, nothing )
[2 of 2] Compiling M2 ( p3/M2.hs, nothing )
[1 of 4] Compiling A[sig] ( p3/A.hsig, nothing )
[2 of 4] Compiling M2 ( p3/M2.hs, nothing )
......@@ -7,12 +7,12 @@
[1 of 2] Compiling A ( q/A.hs, T13214.out/q/A.o )
[2 of 2] Compiling A2 ( q/A2.hs, T13214.out/q/A2.o )
[3 of 5] Processing r1
[1 of 2] Compiling H[sig] ( r1/H.hsig, nothing )
[2 of 2] Compiling C ( r1/C.hs, nothing )
[1 of 3] Compiling H[sig] ( r1/H.hsig, nothing )
[2 of 3] Compiling C ( r1/C.hs, nothing )
[4 of 5] Processing r2
[1 of 2] Compiling H[sig] ( r2/H.hsig, nothing )
[2 of 2] Compiling C ( r2/C.hs, nothing )
[1 of 3] Compiling H[sig] ( r2/H.hsig, nothing )
[2 of 3] Compiling C ( r2/C.hs, nothing )
[5 of 5] Processing r3
[1 of 3] Compiling X[sig] ( r3/X.hsig, nothing )
[2 of 3] Compiling H[sig] ( r3/H.hsig, nothing )
[3 of 3] Compiling D ( r3/D.hs, nothing )
[1 of 4] Compiling X[sig] ( r3/X.hsig, nothing )
[2 of 4] Compiling H[sig] ( r3/H.hsig, nothing )
[3 of 4] Compiling D ( r3/D.hs, nothing )
......@@ -10,4 +10,4 @@
Instantiating p[A=q:A]
[1 of 2] Compiling A[sig] ( p/A.hsig, T13323.out/p/p-HVmFlcYSefiK5n1aDP1v7x/A.o )
[2 of 2] Compiling P ( p/P.hs, T13323.out/p/p-HVmFlcYSefiK5n1aDP1v7x/P.o )
[1 of 1] Compiling R ( r/R.hs, T13323.out/r/R.o )
[1 of 2] Compiling R ( r/R.hs, T13323.out/r/R.o )
......@@ -2,7 +2,7 @@
[1 of 2] Compiling H[sig] ( p/H.hsig, nothing )
[2 of 2] Compiling A ( p/A.hs, nothing )
[2 of 4] Processing q
[1 of 1] Compiling H[sig] ( q/H.hsig, nothing )
[1 of 2] Compiling H[sig] ( q/H.hsig, nothing )
[3 of 4] Processing h
Instantiating h
[1 of 1] Compiling H ( h/H.hs, bkp01.out/h/H.o )
......@@ -15,4 +15,4 @@
Instantiating p[H=h:H]
[1 of 2] Compiling H[sig] ( p/H.hsig, bkp01.out/p/p-6KeuBvYi0jvLWqVbkSAZMq/H.o )
[2 of 2] Compiling A ( p/A.hs, bkp01.out/p/p-6KeuBvYi0jvLWqVbkSAZMq/A.o )
[1 of 1] Compiling H[sig] ( q/H.hsig, bkp01.out/q/q-6KeuBvYi0jvLWqVbkSAZMq/H.o )
[1 of 2] Compiling H[sig] ( q/H.hsig, bkp01.out/q/q-6KeuBvYi0jvLWqVbkSAZMq/H.o )
......@@ -11,4 +11,4 @@
Instantiating p[H=q:H]
[1 of 2] Compiling H[sig] ( p/H.hsig, bkp02.out/p/p-D5Mg3foBSCrDbQDKH4WGSG/H.o )
[2 of 2] Compiling A ( p/A.hs, bkp02.out/p/p-D5Mg3foBSCrDbQDKH4WGSG/A.o )
[1 of 1] Compiling R ( r/R.hs, bkp02.out/r/R.o )
[1 of 2] Compiling R ( r/R.hs, bkp02.out/r/R.o )
[1 of 2] Processing p
[1 of 1] Compiling A[sig] ( p/A.hsig, nothing )
[2 of 2] Processing q
[1 of 2] Compiling A[sig] ( q/A.hsig, nothing )
[2 of 2] Compiling B ( q/B.hs, nothing )
[1 of 3] Compiling A[sig] ( q/A.hsig, nothing )
[2 of 3] Compiling B ( q/B.hs, nothing )
......@@ -9,4 +9,4 @@
[2 of 2] Including r[H=q:H]
Instantiating r[H=q:H]
[1 of 1] Compiling H[sig] ( r/H.hsig, bkp08.out/r/r-D5Mg3foBSCrDbQDKH4WGSG/H.o )
[1 of 1] Compiling M ( p/M.hs, bkp08.out/p/M.o )
[1 of 2] Compiling M ( p/M.hs, bkp08.out/p/M.o )
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment