{-# LANGUAGE BangPatterns, CPP, NondecreasingIndentation, ScopedTypeVariables #-}
{-# LANGUAGE RecordWildCards, NamedFieldPuns #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module GHC.Driver.Make (
depanal, depanalE, depanalPartial,
load, load', LoadHowMuch(..),
downsweep,
topSortModuleGraph,
ms_home_srcimps, ms_home_imps,
summariseModule,
hscSourceToIsBoot,
findExtraSigImports,
implicitRequirements,
noModError, cyclicModuleErr,
moduleGraphNodes, SummaryNode,
IsBootInterface(..)
) where
#include "HsVersions.h"
import GHC.Prelude
import qualified GHC.Runtime.Linker as Linker
import GHC.Driver.Phases
import GHC.Driver.Pipeline
import GHC.Driver.Session
import GHC.Utils.Error
import GHC.Driver.Finder
import GHC.Driver.Monad
import GHC.Parser.Header
import GHC.Driver.Types
import GHC.Unit.Module
import GHC.IfaceToCore ( typecheckIface )
import GHC.Tc.Utils.Monad ( initIfaceCheck )
import GHC.Driver.Main
import GHC.Data.Bag ( unitBag, listToBag, unionManyBags, isEmptyBag )
import GHC.Types.Basic
import GHC.Data.Graph.Directed
import GHC.Utils.Exception ( tryIO )
import GHC.Data.FastString
import GHC.Data.Maybe ( expectJust )
import GHC.Types.Name
import GHC.Utils.Monad ( allM )
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Types.SrcLoc
import GHC.Data.StringBuffer
import GHC.Types.Unique.FM
import GHC.Types.Unique.DSet
import GHC.Tc.Utils.Backpack
import GHC.Unit.State
import GHC.Types.Unique.Set
import GHC.Utils.Misc
import qualified GHC.LanguageExtensions as LangExt
import GHC.Types.Name.Env
import GHC.SysTools.FileCleanup
import Data.Either ( rights, partitionEithers )
import qualified Data.Map as Map
import Data.Map (Map)
import qualified Data.Set as Set
import qualified GHC.Data.FiniteMap as Map ( insertListWith )
import Control.Concurrent ( forkIOWithUnmask, killThread )
import qualified GHC.Conc as CC
import Control.Concurrent.MVar
import Control.Concurrent.QSem
import Control.Exception
import Control.Monad
import Control.Monad.Trans.Except ( ExceptT(..), runExceptT, throwE )
import qualified Control.Monad.Catch as MC
import Data.IORef
import Data.List
import qualified Data.List as List
import Data.Foldable (toList)
import Data.Maybe
import Data.Ord ( comparing )
import Data.Time
import System.Directory
import System.FilePath
import System.IO ( fixIO )
import System.IO.Error ( isDoesNotExistError )
import GHC.Conc ( getNumProcessors, getNumCapabilities, setNumCapabilities )
label_self :: String -> IO ()
label_self :: FilePath -> IO ()
label_self FilePath
thread_name = do
ThreadId
self_tid <- IO ThreadId
CC.myThreadId
ThreadId -> FilePath -> IO ()
CC.labelThread ThreadId
self_tid FilePath
thread_name
depanal :: GhcMonad m =>
[ModuleName]
-> Bool
-> m ModuleGraph
depanal :: forall (m :: * -> *).
GhcMonad m =>
[ModuleName] -> Bool -> m ModuleGraph
depanal [ModuleName]
excluded_mods Bool
allow_dup_roots = do
(ErrorMessages
errs, ModuleGraph
mod_graph) <- [ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
forall (m :: * -> *).
GhcMonad m =>
[ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
depanalE [ModuleName]
excluded_mods Bool
allow_dup_roots
if ErrorMessages -> Bool
forall a. Bag a -> Bool
isEmptyBag ErrorMessages
errs
then ModuleGraph -> m ModuleGraph
forall (f :: * -> *) a. Applicative f => a -> f a
pure ModuleGraph
mod_graph
else ErrorMessages -> m ModuleGraph
forall (io :: * -> *) a. MonadIO io => ErrorMessages -> io a
throwErrors ErrorMessages
errs
depanalE :: GhcMonad m =>
[ModuleName]
-> Bool
-> m (ErrorMessages, ModuleGraph)
depanalE :: forall (m :: * -> *).
GhcMonad m =>
[ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
depanalE [ModuleName]
excluded_mods Bool
allow_dup_roots = do
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
(ErrorMessages
errs, ModuleGraph
mod_graph) <- [ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
forall (m :: * -> *).
GhcMonad m =>
[ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
depanalPartial [ModuleName]
excluded_mods Bool
allow_dup_roots
if ErrorMessages -> Bool
forall a. Bag a -> Bool
isEmptyBag ErrorMessages
errs
then do
let unused_home_mod_err :: [ErrMsg]
unused_home_mod_err = HscEnv -> ModuleGraph -> [ErrMsg]
warnMissingHomeModules HscEnv
hsc_env ModuleGraph
mod_graph
unused_pkg_err :: [ErrMsg]
unused_pkg_err = HscEnv -> ModuleGraph -> [ErrMsg]
warnUnusedPackages HscEnv
hsc_env ModuleGraph
mod_graph
warns :: [ErrMsg]
warns = [ErrMsg]
unused_home_mod_err [ErrMsg] -> [ErrMsg] -> [ErrMsg]
forall a. [a] -> [a] -> [a]
++ [ErrMsg]
unused_pkg_err
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [ErrMsg] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ErrMsg]
warns) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
ErrorMessages -> m ()
forall (m :: * -> *). GhcMonad m => ErrorMessages -> m ()
logWarnings ([ErrMsg] -> ErrorMessages
forall a. [a] -> Bag a
listToBag [ErrMsg]
warns)
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env { hsc_mod_graph :: ModuleGraph
hsc_mod_graph = ModuleGraph
mod_graph }
(ErrorMessages, ModuleGraph) -> m (ErrorMessages, ModuleGraph)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ErrorMessages
errs, ModuleGraph
mod_graph)
else do
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env { hsc_mod_graph :: ModuleGraph
hsc_mod_graph = ModuleGraph
emptyMG }
(ErrorMessages, ModuleGraph) -> m (ErrorMessages, ModuleGraph)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ErrorMessages
errs, ModuleGraph
emptyMG)
depanalPartial
:: GhcMonad m
=> [ModuleName]
-> Bool
-> m (ErrorMessages, ModuleGraph)
depanalPartial :: forall (m :: * -> *).
GhcMonad m =>
[ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
depanalPartial [ModuleName]
excluded_mods Bool
allow_dup_roots = do
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
let
dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
targets :: [Target]
targets = HscEnv -> [Target]
hsc_targets HscEnv
hsc_env
old_graph :: ModuleGraph
old_graph = HscEnv -> ModuleGraph
hsc_mod_graph HscEnv
hsc_env
DynFlags
-> SDoc
-> ((ErrorMessages, ModuleGraph) -> ())
-> m (ErrorMessages, ModuleGraph)
-> m (ErrorMessages, ModuleGraph)
forall (m :: * -> *) a.
MonadIO m =>
DynFlags -> SDoc -> (a -> ()) -> m a -> m a
withTiming DynFlags
dflags (FilePath -> SDoc
text FilePath
"Chasing dependencies") (() -> (ErrorMessages, ModuleGraph) -> ()
forall a b. a -> b -> a
const ()) (m (ErrorMessages, ModuleGraph) -> m (ErrorMessages, ModuleGraph))
-> m (ErrorMessages, ModuleGraph) -> m (ErrorMessages, ModuleGraph)
forall a b. (a -> b) -> a -> b
$ do
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2 ([SDoc] -> SDoc
hcat [
FilePath -> SDoc
text FilePath
"Chasing modules from: ",
[SDoc] -> SDoc
hcat (SDoc -> [SDoc] -> [SDoc]
punctuate SDoc
comma ((Target -> SDoc) -> [Target] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Target -> SDoc
pprTarget [Target]
targets))])
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ HscEnv -> IO ()
flushFinderCaches HscEnv
hsc_env
[Either ErrorMessages ModSummary]
mod_summariesE <- IO [Either ErrorMessages ModSummary]
-> m [Either ErrorMessages ModSummary]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Either ErrorMessages ModSummary]
-> m [Either ErrorMessages ModSummary])
-> IO [Either ErrorMessages ModSummary]
-> m [Either ErrorMessages ModSummary]
forall a b. (a -> b) -> a -> b
$ HscEnv
-> [ModSummary]
-> [ModuleName]
-> Bool
-> IO [Either ErrorMessages ModSummary]
downsweep HscEnv
hsc_env (ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
old_graph)
[ModuleName]
excluded_mods Bool
allow_dup_roots
let
([ErrorMessages]
errs, [ModSummary]
mod_summaries) = [Either ErrorMessages ModSummary]
-> ([ErrorMessages], [ModSummary])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either ErrorMessages ModSummary]
mod_summariesE
mod_graph :: ModuleGraph
mod_graph = [ModSummary] -> ModuleGraph
mkModuleGraph [ModSummary]
mod_summaries
(ErrorMessages, ModuleGraph) -> m (ErrorMessages, ModuleGraph)
forall (m :: * -> *) a. Monad m => a -> m a
return ([ErrorMessages] -> ErrorMessages
forall a. [Bag a] -> Bag a
unionManyBags [ErrorMessages]
errs, ModuleGraph
mod_graph)
warnMissingHomeModules :: HscEnv -> ModuleGraph -> [ErrMsg]
warnMissingHomeModules :: HscEnv -> ModuleGraph -> [ErrMsg]
warnMissingHomeModules HscEnv
hsc_env ModuleGraph
mod_graph =
if (WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnMissingHomeModules DynFlags
dflags Bool -> Bool -> Bool
&& Bool -> Bool
not ([ModuleName] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ModuleName]
missing))
then [ErrMsg
warn]
else []
where
dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
targets :: [TargetId]
targets = (Target -> TargetId) -> [Target] -> [TargetId]
forall a b. (a -> b) -> [a] -> [b]
map Target -> TargetId
targetId (HscEnv -> [Target]
hsc_targets HscEnv
hsc_env)
is_known_module :: ModSummary -> Bool
is_known_module ModSummary
mod = (TargetId -> Bool) -> [TargetId] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (ModSummary -> TargetId -> Bool
is_my_target ModSummary
mod) [TargetId]
targets
is_my_target :: ModSummary -> TargetId -> Bool
is_my_target ModSummary
mod (TargetModule ModuleName
name)
= Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (ModSummary -> Module
ms_mod ModSummary
mod) ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
name
is_my_target ModSummary
mod (TargetFile FilePath
target_file Maybe Phase
_)
| Just FilePath
mod_file <- ModLocation -> Maybe FilePath
ml_hs_file (ModSummary -> ModLocation
ms_location ModSummary
mod)
= FilePath
target_file FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
mod_file Bool -> Bool -> Bool
||
FilePath -> FilePath
addBootSuffix FilePath
target_file FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
mod_file Bool -> Bool -> Bool
||
FilePath -> ModuleName
mkModuleName ((FilePath, FilePath) -> FilePath
forall a b. (a, b) -> a
fst ((FilePath, FilePath) -> FilePath)
-> (FilePath, FilePath) -> FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> (FilePath, FilePath)
splitExtension FilePath
target_file)
ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (ModSummary -> Module
ms_mod ModSummary
mod)
is_my_target ModSummary
_ TargetId
_ = Bool
False
missing :: [ModuleName]
missing = (ModSummary -> ModuleName) -> [ModSummary] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (Module -> ModuleName)
-> (ModSummary -> Module) -> ModSummary -> ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModSummary -> Module
ms_mod) ([ModSummary] -> [ModuleName]) -> [ModSummary] -> [ModuleName]
forall a b. (a -> b) -> a -> b
$
(ModSummary -> Bool) -> [ModSummary] -> [ModSummary]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (ModSummary -> Bool) -> ModSummary -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModSummary -> Bool
is_known_module) (ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
mod_graph)
msg :: SDoc
msg
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_BuildingCabalPackage DynFlags
dflags
= SDoc -> Int -> SDoc -> SDoc
hang
(FilePath -> SDoc
text FilePath
"These modules are needed for compilation but not listed in your .cabal file's other-modules: ")
Int
4
([SDoc] -> SDoc
sep ((ModuleName -> SDoc) -> [ModuleName] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ModuleName]
missing))
| Bool
otherwise
=
SDoc -> Int -> SDoc -> SDoc
hang
(FilePath -> SDoc
text FilePath
"Modules are not listed in command line but needed for compilation: ")
Int
4
([SDoc] -> SDoc
sep ((ModuleName -> SDoc) -> [ModuleName] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ModuleName]
missing))
warn :: ErrMsg
warn = WarnReason -> ErrMsg -> ErrMsg
makeIntoWarning
(WarningFlag -> WarnReason
Reason WarningFlag
Opt_WarnMissingHomeModules)
(DynFlags -> SrcSpan -> SDoc -> ErrMsg
mkPlainErrMsg DynFlags
dflags SrcSpan
noSrcSpan SDoc
msg)
data LoadHowMuch
= LoadAllTargets
| LoadUpTo ModuleName
| LoadDependenciesOf ModuleName
load :: GhcMonad m => LoadHowMuch -> m SuccessFlag
load :: forall (m :: * -> *). GhcMonad m => LoadHowMuch -> m SuccessFlag
load LoadHowMuch
how_much = do
(ErrorMessages
errs, ModuleGraph
mod_graph) <- [ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
forall (m :: * -> *).
GhcMonad m =>
[ModuleName] -> Bool -> m (ErrorMessages, ModuleGraph)
depanalE [] Bool
False
SuccessFlag
success <- LoadHowMuch -> Maybe Messager -> ModuleGraph -> m SuccessFlag
forall (m :: * -> *).
GhcMonad m =>
LoadHowMuch -> Maybe Messager -> ModuleGraph -> m SuccessFlag
load' LoadHowMuch
how_much (Messager -> Maybe Messager
forall a. a -> Maybe a
Just Messager
batchMsg) ModuleGraph
mod_graph
if ErrorMessages -> Bool
forall a. Bag a -> Bool
isEmptyBag ErrorMessages
errs
then SuccessFlag -> m SuccessFlag
forall (f :: * -> *) a. Applicative f => a -> f a
pure SuccessFlag
success
else ErrorMessages -> m SuccessFlag
forall (io :: * -> *) a. MonadIO io => ErrorMessages -> io a
throwErrors ErrorMessages
errs
warnUnusedPackages :: HscEnv -> ModuleGraph -> [ErrMsg]
warnUnusedPackages :: HscEnv -> ModuleGraph -> [ErrMsg]
warnUnusedPackages HscEnv
hsc_env ModuleGraph
mod_graph =
let dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
state :: UnitState
state = DynFlags -> UnitState
unitState DynFlags
dflags
loadedPackages :: [UnitInfo]
loadedPackages = [[UnitInfo]] -> [UnitInfo]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[UnitInfo]] -> [UnitInfo]) -> [[UnitInfo]] -> [UnitInfo]
forall a b. (a -> b) -> a -> b
$
((Maybe FastString, GenLocated SrcSpan ModuleName)
-> Maybe [UnitInfo])
-> [(Maybe FastString, GenLocated SrcSpan ModuleName)]
-> [[UnitInfo]]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\(Maybe FastString
fs, GenLocated SrcSpan ModuleName
mn) -> UnitState -> ModuleName -> Maybe FastString -> Maybe [UnitInfo]
lookupModulePackage UnitState
state (GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc GenLocated SrcSpan ModuleName
mn) Maybe FastString
fs)
([(Maybe FastString, GenLocated SrcSpan ModuleName)]
-> [[UnitInfo]])
-> [(Maybe FastString, GenLocated SrcSpan ModuleName)]
-> [[UnitInfo]]
forall a b. (a -> b) -> a -> b
$ (ModSummary -> [(Maybe FastString, GenLocated SrcSpan ModuleName)])
-> [ModSummary]
-> [(Maybe FastString, GenLocated SrcSpan ModuleName)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ModSummary -> [(Maybe FastString, GenLocated SrcSpan ModuleName)]
ms_imps (ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
mod_graph)
requestedArgs :: [PackageArg]
requestedArgs = (PackageFlag -> Maybe PackageArg) -> [PackageFlag] -> [PackageArg]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe PackageFlag -> Maybe PackageArg
packageArg (DynFlags -> [PackageFlag]
packageFlags DynFlags
dflags)
unusedArgs :: [PackageArg]
unusedArgs
= (PackageArg -> Bool) -> [PackageArg] -> [PackageArg]
forall a. (a -> Bool) -> [a] -> [a]
filter (\PackageArg
arg -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (UnitInfo -> Bool) -> [UnitInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (UnitState -> PackageArg -> UnitInfo -> Bool
matching UnitState
state PackageArg
arg) [UnitInfo]
loadedPackages)
[PackageArg]
requestedArgs
warn :: ErrMsg
warn = WarnReason -> ErrMsg -> ErrMsg
makeIntoWarning
(WarningFlag -> WarnReason
Reason WarningFlag
Opt_WarnUnusedPackages)
(DynFlags -> SrcSpan -> SDoc -> ErrMsg
mkPlainErrMsg DynFlags
dflags SrcSpan
noSrcSpan SDoc
msg)
msg :: SDoc
msg = [SDoc] -> SDoc
vcat [ FilePath -> SDoc
text FilePath
"The following packages were specified" SDoc -> SDoc -> SDoc
<+>
FilePath -> SDoc
text FilePath
"via -package or -package-id flags,"
, FilePath -> SDoc
text FilePath
"but were not needed for compilation:"
, Int -> SDoc -> SDoc
nest Int
2 ([SDoc] -> SDoc
vcat ((PackageArg -> SDoc) -> [PackageArg] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (SDoc -> SDoc
withDash (SDoc -> SDoc) -> (PackageArg -> SDoc) -> PackageArg -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageArg -> SDoc
pprUnusedArg) [PackageArg]
unusedArgs)) ]
in if Bool -> Bool
not ([PackageArg] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PackageArg]
unusedArgs) Bool -> Bool -> Bool
&& WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnUnusedPackages DynFlags
dflags
then [ErrMsg
warn]
else []
where
packageArg :: PackageFlag -> Maybe PackageArg
packageArg (ExposePackage FilePath
_ PackageArg
arg ModRenaming
_) = PackageArg -> Maybe PackageArg
forall a. a -> Maybe a
Just PackageArg
arg
packageArg PackageFlag
_ = Maybe PackageArg
forall a. Maybe a
Nothing
pprUnusedArg :: PackageArg -> SDoc
pprUnusedArg (PackageArg FilePath
str) = FilePath -> SDoc
text FilePath
str
pprUnusedArg (UnitIdArg GenUnit UnitId
uid) = GenUnit UnitId -> SDoc
forall a. Outputable a => a -> SDoc
ppr GenUnit UnitId
uid
withDash :: SDoc -> SDoc
withDash = SDoc -> SDoc -> SDoc
(<+>) (FilePath -> SDoc
text FilePath
"-")
matchingStr :: String -> UnitInfo -> Bool
matchingStr :: FilePath -> UnitInfo -> Bool
matchingStr FilePath
str UnitInfo
p
= FilePath
str FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== UnitInfo -> FilePath
forall u. GenUnitInfo u -> FilePath
unitPackageIdString UnitInfo
p
Bool -> Bool -> Bool
|| FilePath
str FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== UnitInfo -> FilePath
forall u. GenUnitInfo u -> FilePath
unitPackageNameString UnitInfo
p
matching :: UnitState -> PackageArg -> UnitInfo -> Bool
matching :: UnitState -> PackageArg -> UnitInfo -> Bool
matching UnitState
_ (PackageArg FilePath
str) UnitInfo
p = FilePath -> UnitInfo -> Bool
matchingStr FilePath
str UnitInfo
p
matching UnitState
state (UnitIdArg GenUnit UnitId
uid) UnitInfo
p = GenUnit UnitId
uid GenUnit UnitId -> GenUnit UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitState -> UnitInfo -> GenUnit UnitId
realUnit UnitState
state UnitInfo
p
realUnit :: UnitState -> UnitInfo -> Unit
realUnit :: UnitState -> UnitInfo -> GenUnit UnitId
realUnit UnitState
state
= UnitState -> GenUnit UnitId -> GenUnit UnitId
unwireUnit UnitState
state
(GenUnit UnitId -> GenUnit UnitId)
-> (UnitInfo -> GenUnit UnitId) -> UnitInfo -> GenUnit UnitId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Definite UnitId -> GenUnit UnitId
forall uid. Definite uid -> GenUnit uid
RealUnit
(Definite UnitId -> GenUnit UnitId)
-> (UnitInfo -> Definite UnitId) -> UnitInfo -> GenUnit UnitId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitId -> Definite UnitId
forall unit. unit -> Definite unit
Definite
(UnitId -> Definite UnitId)
-> (UnitInfo -> UnitId) -> UnitInfo -> Definite UnitId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitInfo -> UnitId
forall compid srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo compid srcpkgid srcpkgname uid modulename mod
-> uid
unitId
load' :: GhcMonad m => LoadHowMuch -> Maybe Messager -> ModuleGraph -> m SuccessFlag
load' :: forall (m :: * -> *).
GhcMonad m =>
LoadHowMuch -> Maybe Messager -> ModuleGraph -> m SuccessFlag
load' LoadHowMuch
how_much Maybe Messager
mHscMessage ModuleGraph
mod_graph = do
(HscEnv -> HscEnv) -> m ()
forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
modifySession ((HscEnv -> HscEnv) -> m ()) -> (HscEnv -> HscEnv) -> m ()
forall a b. (a -> b) -> a -> b
$ \HscEnv
hsc_env -> HscEnv
hsc_env { hsc_mod_graph :: ModuleGraph
hsc_mod_graph = ModuleGraph
mod_graph }
m ()
forall (m :: * -> *). GhcMonad m => m ()
guessOutputFile
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
let hpt1 :: HomePackageTable
hpt1 = HscEnv -> HomePackageTable
hsc_HPT HscEnv
hsc_env
let dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
let all_home_mods :: UniqSet ModuleName
all_home_mods =
[ModuleName] -> UniqSet ModuleName
forall a. Uniquable a => [a] -> UniqSet a
mkUniqSet [ ModSummary -> ModuleName
ms_mod_name ModSummary
s
| ModSummary
s <- ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
mod_graph, ModSummary -> IsBootInterface
isBootSummary ModSummary
s IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
NotBoot]
let checkHowMuch :: LoadHowMuch -> m SuccessFlag -> m SuccessFlag
checkHowMuch (LoadUpTo ModuleName
m) = ModuleName -> m SuccessFlag -> m SuccessFlag
forall {m :: * -> *}.
MonadIO m =>
ModuleName -> m SuccessFlag -> m SuccessFlag
checkMod ModuleName
m
checkHowMuch (LoadDependenciesOf ModuleName
m) = ModuleName -> m SuccessFlag -> m SuccessFlag
forall {m :: * -> *}.
MonadIO m =>
ModuleName -> m SuccessFlag -> m SuccessFlag
checkMod ModuleName
m
checkHowMuch LoadHowMuch
_ = m SuccessFlag -> m SuccessFlag
forall a. a -> a
id
checkMod :: ModuleName -> m SuccessFlag -> m SuccessFlag
checkMod ModuleName
m m SuccessFlag
and_then
| ModuleName
m ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
all_home_mods = m SuccessFlag
and_then
| Bool
otherwise = do
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> IO ()
errorMsg DynFlags
dflags (FilePath -> SDoc
text FilePath
"no such module:" SDoc -> SDoc -> SDoc
<+>
SDoc -> SDoc
quotes (ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
m))
SuccessFlag -> m SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
Failed
LoadHowMuch -> m SuccessFlag -> m SuccessFlag
forall {m :: * -> *}.
MonadIO m =>
LoadHowMuch -> m SuccessFlag -> m SuccessFlag
checkHowMuch LoadHowMuch
how_much (m SuccessFlag -> m SuccessFlag) -> m SuccessFlag -> m SuccessFlag
forall a b. (a -> b) -> a -> b
$ do
let mg2_with_srcimps :: [SCC ModSummary]
mg2_with_srcimps :: [SCC ModSummary]
mg2_with_srcimps = Bool -> ModuleGraph -> Maybe ModuleName -> [SCC ModSummary]
topSortModuleGraph Bool
True ModuleGraph
mod_graph Maybe ModuleName
forall a. Maybe a
Nothing
[SCC ModSummary] -> m ()
forall (m :: * -> *). GhcMonad m => [SCC ModSummary] -> m ()
warnUnnecessarySourceImports [SCC ModSummary]
mg2_with_srcimps
let
stable_mods :: (UniqSet ModuleName, UniqSet ModuleName)
stable_mods@(UniqSet ModuleName
stable_obj,UniqSet ModuleName
stable_bco)
= HomePackageTable
-> [SCC ModSummary]
-> UniqSet ModuleName
-> (UniqSet ModuleName, UniqSet ModuleName)
checkStability HomePackageTable
hpt1 [SCC ModSummary]
mg2_with_srcimps UniqSet ModuleName
all_home_mods
pruned_hpt :: HomePackageTable
pruned_hpt = HomePackageTable
-> [ModSummary]
-> (UniqSet ModuleName, UniqSet ModuleName)
-> HomePackageTable
pruneHomePackageTable HomePackageTable
hpt1
([SCC ModSummary] -> [ModSummary]
forall a. [SCC a] -> [a]
flattenSCCs [SCC ModSummary]
mg2_with_srcimps)
(UniqSet ModuleName, UniqSet ModuleName)
stable_mods
HomePackageTable
_ <- IO HomePackageTable -> m HomePackageTable
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO HomePackageTable -> m HomePackageTable)
-> IO HomePackageTable -> m HomePackageTable
forall a b. (a -> b) -> a -> b
$ HomePackageTable -> IO HomePackageTable
forall a. a -> IO a
evaluate HomePackageTable
pruned_hpt
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession (HscEnv -> m ()) -> HscEnv -> m ()
forall a b. (a -> b) -> a -> b
$ HscEnv -> HscEnv
discardIC (HscEnv -> HscEnv) -> HscEnv -> HscEnv
forall a b. (a -> b) -> a -> b
$ HscEnv
hsc_env { hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable
pruned_hpt }
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2 (FilePath -> SDoc
text FilePath
"Stable obj:" SDoc -> SDoc -> SDoc
<+> UniqSet ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr UniqSet ModuleName
stable_obj SDoc -> SDoc -> SDoc
$$
FilePath -> SDoc
text FilePath
"Stable BCO:" SDoc -> SDoc -> SDoc
<+> UniqSet ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr UniqSet ModuleName
stable_bco)
let stable_linkables :: [Linkable]
stable_linkables = [ Linkable
linkable
| ModuleName
m <- UniqSet ModuleName -> [ModuleName]
forall elt. UniqSet elt -> [elt]
nonDetEltsUniqSet UniqSet ModuleName
stable_obj [ModuleName] -> [ModuleName] -> [ModuleName]
forall a. [a] -> [a] -> [a]
++
UniqSet ModuleName -> [ModuleName]
forall elt. UniqSet elt -> [elt]
nonDetEltsUniqSet UniqSet ModuleName
stable_bco,
Just HomeModInfo
hmi <- [HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
pruned_hpt ModuleName
m],
Just Linkable
linkable <- [HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi] ]
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ HscEnv -> [Linkable] -> IO ()
unload HscEnv
hsc_env [Linkable]
stable_linkables
let full_mg :: [SCC ModSummary]
full_mg :: [SCC ModSummary]
full_mg = Bool -> ModuleGraph -> Maybe ModuleName -> [SCC ModSummary]
topSortModuleGraph Bool
False ModuleGraph
mod_graph Maybe ModuleName
forall a. Maybe a
Nothing
maybe_top_mod :: Maybe ModuleName
maybe_top_mod = case LoadHowMuch
how_much of
LoadUpTo ModuleName
m -> ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
m
LoadDependenciesOf ModuleName
m -> ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
m
LoadHowMuch
_ -> Maybe ModuleName
forall a. Maybe a
Nothing
partial_mg0 :: [SCC ModSummary]
partial_mg0 :: [SCC ModSummary]
partial_mg0 = Bool -> ModuleGraph -> Maybe ModuleName -> [SCC ModSummary]
topSortModuleGraph Bool
False ModuleGraph
mod_graph Maybe ModuleName
maybe_top_mod
partial_mg :: [SCC ModSummary]
partial_mg
| LoadDependenciesOf ModuleName
_mod <- LoadHowMuch
how_much
= ASSERT( case last partial_mg0 of
AcyclicSCC ms -> ms_mod_name ms == _mod; _ -> False )
[SCC ModSummary] -> [SCC ModSummary]
forall a. [a] -> [a]
List.init [SCC ModSummary]
partial_mg0
| Bool
otherwise
= [SCC ModSummary]
partial_mg0
stable_mg :: [SCC ModSummary]
stable_mg =
[ ModSummary -> SCC ModSummary
forall vertex. vertex -> SCC vertex
AcyclicSCC ModSummary
ms
| AcyclicSCC ModSummary
ms <- [SCC ModSummary]
full_mg,
ModSummary -> Bool
stable_mod_summary ModSummary
ms ]
stable_mod_summary :: ModSummary -> Bool
stable_mod_summary ModSummary
ms =
ModSummary -> ModuleName
ms_mod_name ModSummary
ms ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_obj Bool -> Bool -> Bool
||
ModSummary -> ModuleName
ms_mod_name ModSummary
ms ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_bco
unstable_mg :: [SCC ModSummary]
unstable_mg = (SCC ModSummary -> Bool) -> [SCC ModSummary] -> [SCC ModSummary]
forall a. (a -> Bool) -> [a] -> [a]
filter SCC ModSummary -> Bool
not_stable [SCC ModSummary]
partial_mg
where not_stable :: SCC ModSummary -> Bool
not_stable (CyclicSCC [ModSummary]
_) = Bool
True
not_stable (AcyclicSCC ModSummary
ms)
= Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ModSummary -> Bool
stable_mod_summary ModSummary
ms
mg :: [SCC ModSummary]
mg = [SCC ModSummary]
stable_mg [SCC ModSummary] -> [SCC ModSummary] -> [SCC ModSummary]
forall a. [a] -> [a] -> [a]
++ [SCC ModSummary]
unstable_mg
let cleanup :: HscEnv -> IO ()
cleanup = DynFlags -> IO ()
cleanCurrentModuleTempFiles (DynFlags -> IO ()) -> (HscEnv -> DynFlags) -> HscEnv -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HscEnv -> DynFlags
hsc_dflags
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2 (SDoc -> Int -> SDoc -> SDoc
hang (FilePath -> SDoc
text FilePath
"Ready for upsweep")
Int
2 ([SCC ModSummary] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [SCC ModSummary]
mg))
Int
n_jobs <- case DynFlags -> Maybe Int
parMakeCount DynFlags
dflags of
Maybe Int
Nothing -> IO Int -> m Int
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Int
getNumProcessors
Just Int
n -> Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n
let upsweep_fn :: Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
upsweep_fn | Int
n_jobs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 = Int
-> Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
forall (m :: * -> *).
GhcMonad m =>
Int
-> Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
parUpsweep Int
n_jobs
| Bool
otherwise = Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
forall (m :: * -> *).
GhcMonad m =>
Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
upsweep
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env{ hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable
emptyHomePackageTable }
(SuccessFlag
upsweep_ok, [ModSummary]
modsUpswept) <- m (SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall (m :: * -> *) a. GhcMonad m => m a -> m a
withDeferredDiagnostics (m (SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary]))
-> m (SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall a b. (a -> b) -> a -> b
$
Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
upsweep_fn Maybe Messager
mHscMessage HomePackageTable
pruned_hpt (UniqSet ModuleName, UniqSet ModuleName)
stable_mods HscEnv -> IO ()
cleanup [SCC ModSummary]
mg
let modsDone :: [ModSummary]
modsDone = [ModSummary] -> [ModSummary]
forall a. [a] -> [a]
reverse [ModSummary]
modsUpswept
if SuccessFlag -> Bool
succeeded SuccessFlag
upsweep_ok
then
do IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2 (FilePath -> SDoc
text FilePath
"Upsweep completely successful.")
HscEnv
hsc_env1 <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> IO ()
cleanCurrentModuleTempFiles DynFlags
dflags
let ofile :: Maybe FilePath
ofile = DynFlags -> Maybe FilePath
outputFile DynFlags
dflags
let no_hs_main :: Bool
no_hs_main = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_NoHsMain DynFlags
dflags
let
main_mod :: Module
main_mod = DynFlags -> Module
mainModIs DynFlags
dflags
a_root_is_Main :: Bool
a_root_is_Main = ModuleGraph -> Module -> Bool
mgElemModule ModuleGraph
mod_graph Module
main_mod
do_linking :: Bool
do_linking = Bool
a_root_is_Main Bool -> Bool -> Bool
|| Bool
no_hs_main Bool -> Bool -> Bool
|| DynFlags -> GhcLink
ghcLink DynFlags
dflags GhcLink -> GhcLink -> Bool
forall a. Eq a => a -> a -> Bool
== GhcLink
LinkDynLib Bool -> Bool -> Bool
|| DynFlags -> GhcLink
ghcLink DynFlags
dflags GhcLink -> GhcLink -> Bool
forall a. Eq a => a -> a -> Bool
== GhcLink
LinkStaticLib
SuccessFlag
linkresult <- IO SuccessFlag -> m SuccessFlag
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO SuccessFlag -> m SuccessFlag)
-> IO SuccessFlag -> m SuccessFlag
forall a b. (a -> b) -> a -> b
$ GhcLink -> DynFlags -> Bool -> HomePackageTable -> IO SuccessFlag
link (DynFlags -> GhcLink
ghcLink DynFlags
dflags) DynFlags
dflags Bool
do_linking (HscEnv -> HomePackageTable
hsc_HPT HscEnv
hsc_env1)
if DynFlags -> GhcLink
ghcLink DynFlags
dflags GhcLink -> GhcLink -> Bool
forall a. Eq a => a -> a -> Bool
== GhcLink
LinkBinary Bool -> Bool -> Bool
&& Maybe FilePath -> Bool
forall a. Maybe a -> Bool
isJust Maybe FilePath
ofile Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
do_linking
then do
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> IO ()
errorMsg DynFlags
dflags (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> SDoc
text
(FilePath
"output was redirected with -o, " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++
FilePath
"but no output will be generated\n" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++
FilePath
"because there is no " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++
ModuleName -> FilePath
moduleNameString (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
main_mod) FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
" module.")
SuccessFlag -> SuccessFlag -> m SuccessFlag
forall (m :: * -> *).
GhcMonad m =>
SuccessFlag -> SuccessFlag -> m SuccessFlag
loadFinish SuccessFlag
Failed SuccessFlag
linkresult
else
SuccessFlag -> SuccessFlag -> m SuccessFlag
forall (m :: * -> *).
GhcMonad m =>
SuccessFlag -> SuccessFlag -> m SuccessFlag
loadFinish SuccessFlag
Succeeded SuccessFlag
linkresult
else
do IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2 (FilePath -> SDoc
text FilePath
"Upsweep partially successful.")
let modsDone_names :: [Module]
modsDone_names
= (ModSummary -> Module) -> [ModSummary] -> [Module]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> Module
ms_mod [ModSummary]
modsDone
let mods_to_zap_names :: Set Module
mods_to_zap_names
= [Module] -> [SCC ModSummary] -> Set Module
findPartiallyCompletedCycles [Module]
modsDone_names
[SCC ModSummary]
mg2_with_srcimps
let ([ModSummary]
mods_to_clean, [ModSummary]
mods_to_keep) =
(ModSummary -> Bool)
-> [ModSummary] -> ([ModSummary], [ModSummary])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition ((Module -> Set Module -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Module
mods_to_zap_names)(Module -> Bool) -> (ModSummary -> Module) -> ModSummary -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.ModSummary -> Module
ms_mod) [ModSummary]
modsDone
HscEnv
hsc_env1 <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
let hpt4 :: HomePackageTable
hpt4 = HscEnv -> HomePackageTable
hsc_HPT HscEnv
hsc_env1
unneeded_temps :: [FilePath]
unneeded_temps = [[FilePath]] -> [FilePath]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[FilePath
ms_hspp_file FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: [FilePath]
object_files
| ModSummary{Module
ms_mod :: Module
ms_mod :: ModSummary -> Module
ms_mod, FilePath
ms_hspp_file :: ModSummary -> FilePath
ms_hspp_file :: FilePath
ms_hspp_file} <- [ModSummary]
mods_to_clean
, let object_files :: [FilePath]
object_files = [FilePath]
-> (Linkable -> [FilePath]) -> Maybe Linkable -> [FilePath]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Linkable -> [FilePath]
linkableObjs (Maybe Linkable -> [FilePath]) -> Maybe Linkable -> [FilePath]
forall a b. (a -> b) -> a -> b
$
HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
hpt4 (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
ms_mod)
Maybe HomeModInfo
-> (HomeModInfo -> Maybe Linkable) -> Maybe Linkable
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HomeModInfo -> Maybe Linkable
hm_linkable
]
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
DynFlags -> TempFileLifetime -> [FilePath] -> IO ()
changeTempFilesLifetime DynFlags
dflags TempFileLifetime
TFL_CurrentModule [FilePath]
unneeded_temps
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> IO ()
cleanCurrentModuleTempFiles DynFlags
dflags
let hpt5 :: HomePackageTable
hpt5 = [ModuleName] -> HomePackageTable -> HomePackageTable
retainInTopLevelEnvs ((ModSummary -> ModuleName) -> [ModSummary] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> ModuleName
ms_mod_name [ModSummary]
mods_to_keep)
HomePackageTable
hpt4
let just_linkables :: Bool
just_linkables =
GhcLink -> Bool
isNoLink (DynFlags -> GhcLink
ghcLink DynFlags
dflags)
Bool -> Bool -> Bool
|| (HomeModInfo -> Bool) -> HomePackageTable -> Bool
allHpt (Maybe Linkable -> Bool
forall a. Maybe a -> Bool
isJust(Maybe Linkable -> Bool)
-> (HomeModInfo -> Maybe Linkable) -> HomeModInfo -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.HomeModInfo -> Maybe Linkable
hm_linkable)
((HomeModInfo -> Bool) -> HomePackageTable -> HomePackageTable
filterHpt ((HscSource -> HscSource -> Bool
forall a. Eq a => a -> a -> Bool
== HscSource
HsSrcFile)(HscSource -> Bool)
-> (HomeModInfo -> HscSource) -> HomeModInfo -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.ModIface_ 'ModIfaceFinal -> HscSource
forall (phase :: ModIfacePhase). ModIface_ phase -> HscSource
mi_hsc_src(ModIface_ 'ModIfaceFinal -> HscSource)
-> (HomeModInfo -> ModIface_ 'ModIfaceFinal)
-> HomeModInfo
-> HscSource
forall b c a. (b -> c) -> (a -> b) -> a -> c
.HomeModInfo -> ModIface_ 'ModIfaceFinal
hm_iface)
HomePackageTable
hpt5)
ASSERT( just_linkables ) do
linkresult <- liftIO $ link (ghcLink dflags) dflags False hpt5
modifySession $ \hsc_env -> hsc_env{ hsc_HPT = hpt5 }
loadFinish Failed linkresult
loadFinish :: GhcMonad m => SuccessFlag -> SuccessFlag -> m SuccessFlag
loadFinish :: forall (m :: * -> *).
GhcMonad m =>
SuccessFlag -> SuccessFlag -> m SuccessFlag
loadFinish SuccessFlag
_all_ok SuccessFlag
Failed
= do HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ HscEnv -> [Linkable] -> IO ()
unload HscEnv
hsc_env []
(HscEnv -> HscEnv) -> m ()
forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
modifySession HscEnv -> HscEnv
discardProg
SuccessFlag -> m SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
Failed
loadFinish SuccessFlag
all_ok SuccessFlag
Succeeded
= do (HscEnv -> HscEnv) -> m ()
forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
modifySession HscEnv -> HscEnv
discardIC
SuccessFlag -> m SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
all_ok
discardProg :: HscEnv -> HscEnv
discardProg :: HscEnv -> HscEnv
discardProg HscEnv
hsc_env
= HscEnv -> HscEnv
discardIC (HscEnv -> HscEnv) -> HscEnv -> HscEnv
forall a b. (a -> b) -> a -> b
$ HscEnv
hsc_env { hsc_mod_graph :: ModuleGraph
hsc_mod_graph = ModuleGraph
emptyMG
, hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable
emptyHomePackageTable }
discardIC :: HscEnv -> HscEnv
discardIC :: HscEnv -> HscEnv
discardIC HscEnv
hsc_env
= HscEnv
hsc_env { hsc_IC :: InteractiveContext
hsc_IC = InteractiveContext
empty_ic { ic_int_print :: Name
ic_int_print = Name
new_ic_int_print
, ic_monad :: Name
ic_monad = Name
new_ic_monad } }
where
!new_ic_int_print :: Name
new_ic_int_print = (InteractiveContext -> Name) -> Name
keep_external_name InteractiveContext -> Name
ic_int_print
!new_ic_monad :: Name
new_ic_monad = (InteractiveContext -> Name) -> Name
keep_external_name InteractiveContext -> Name
ic_monad
dflags :: DynFlags
dflags = InteractiveContext -> DynFlags
ic_dflags InteractiveContext
old_ic
old_ic :: InteractiveContext
old_ic = HscEnv -> InteractiveContext
hsc_IC HscEnv
hsc_env
empty_ic :: InteractiveContext
empty_ic = DynFlags -> InteractiveContext
emptyInteractiveContext DynFlags
dflags
keep_external_name :: (InteractiveContext -> Name) -> Name
keep_external_name InteractiveContext -> Name
ic_name
| GenUnit UnitId -> Name -> Bool
nameIsFromExternalPackage GenUnit UnitId
this_pkg Name
old_name = Name
old_name
| Bool
otherwise = InteractiveContext -> Name
ic_name InteractiveContext
empty_ic
where
this_pkg :: GenUnit UnitId
this_pkg = DynFlags -> GenUnit UnitId
homeUnit DynFlags
dflags
old_name :: Name
old_name = InteractiveContext -> Name
ic_name InteractiveContext
old_ic
guessOutputFile :: GhcMonad m => m ()
guessOutputFile :: forall (m :: * -> *). GhcMonad m => m ()
guessOutputFile = (HscEnv -> HscEnv) -> m ()
forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
modifySession ((HscEnv -> HscEnv) -> m ()) -> (HscEnv -> HscEnv) -> m ()
forall a b. (a -> b) -> a -> b
$ \HscEnv
env ->
let dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
env
!mod_graph :: ModuleGraph
mod_graph = HscEnv -> ModuleGraph
hsc_mod_graph HscEnv
env
mainModuleSrcPath :: Maybe String
mainModuleSrcPath :: Maybe FilePath
mainModuleSrcPath = do
ModSummary
ms <- ModuleGraph -> Module -> Maybe ModSummary
mgLookupModule ModuleGraph
mod_graph (DynFlags -> Module
mainModIs DynFlags
dflags)
ModLocation -> Maybe FilePath
ml_hs_file (ModSummary -> ModLocation
ms_location ModSummary
ms)
name :: Maybe FilePath
name = (FilePath -> FilePath) -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FilePath -> FilePath
dropExtension Maybe FilePath
mainModuleSrcPath
name_exe :: Maybe FilePath
name_exe = do
#if defined(mingw32_HOST_OS)
name' <- fmap (<.> "exe") name
#else
FilePath
name' <- Maybe FilePath
name
#endif
FilePath
mainModuleSrcPath' <- Maybe FilePath
mainModuleSrcPath
if FilePath
name' FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
mainModuleSrcPath'
then GhcException -> Maybe FilePath
forall a. GhcException -> a
throwGhcException (GhcException -> Maybe FilePath)
-> (FilePath -> GhcException) -> FilePath -> Maybe FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> GhcException
UsageError (FilePath -> Maybe FilePath) -> FilePath -> Maybe FilePath
forall a b. (a -> b) -> a -> b
$
FilePath
"default output name would overwrite the input file; " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++
FilePath
"must specify -o explicitly"
else FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
name'
in
case DynFlags -> Maybe FilePath
outputFile DynFlags
dflags of
Just FilePath
_ -> HscEnv
env
Maybe FilePath
Nothing -> HscEnv
env { hsc_dflags :: DynFlags
hsc_dflags = DynFlags
dflags { outputFile :: Maybe FilePath
outputFile = Maybe FilePath
name_exe } }
pruneHomePackageTable :: HomePackageTable
-> [ModSummary]
-> StableModules
-> HomePackageTable
pruneHomePackageTable :: HomePackageTable
-> [ModSummary]
-> (UniqSet ModuleName, UniqSet ModuleName)
-> HomePackageTable
pruneHomePackageTable HomePackageTable
hpt [ModSummary]
summ (UniqSet ModuleName
stable_obj, UniqSet ModuleName
stable_bco)
= (HomeModInfo -> HomeModInfo)
-> HomePackageTable -> HomePackageTable
mapHpt HomeModInfo -> HomeModInfo
prune HomePackageTable
hpt
where prune :: HomeModInfo -> HomeModInfo
prune HomeModInfo
hmi
| ModuleName -> Bool
is_stable ModuleName
modl = HomeModInfo
hmi'
| Bool
otherwise = HomeModInfo
hmi'{ hm_details :: ModDetails
hm_details = ModDetails
emptyModDetails }
where
modl :: ModuleName
modl = Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (ModIface_ 'ModIfaceFinal -> Module
forall (phase :: ModIfacePhase). ModIface_ phase -> Module
mi_module (HomeModInfo -> ModIface_ 'ModIfaceFinal
hm_iface HomeModInfo
hmi))
hmi' :: HomeModInfo
hmi' | Just Linkable
l <- HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi, Linkable -> UTCTime
linkableTime Linkable
l UTCTime -> UTCTime -> Bool
forall a. Ord a => a -> a -> Bool
< ModSummary -> UTCTime
ms_hs_date ModSummary
ms
= HomeModInfo
hmi{ hm_linkable :: Maybe Linkable
hm_linkable = Maybe Linkable
forall a. Maybe a
Nothing }
| Bool
otherwise
= HomeModInfo
hmi
where ms :: ModSummary
ms = FilePath -> Maybe ModSummary -> ModSummary
forall a. HasCallStack => FilePath -> Maybe a -> a
expectJust FilePath
"prune" (UniqFM ModuleName ModSummary -> ModuleName -> Maybe ModSummary
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM UniqFM ModuleName ModSummary
ms_map ModuleName
modl)
ms_map :: UniqFM ModuleName ModSummary
ms_map = [(ModuleName, ModSummary)] -> UniqFM ModuleName ModSummary
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM [(ModSummary -> ModuleName
ms_mod_name ModSummary
ms, ModSummary
ms) | ModSummary
ms <- [ModSummary]
summ]
is_stable :: ModuleName -> Bool
is_stable ModuleName
m =
ModuleName
m ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_obj Bool -> Bool -> Bool
||
ModuleName
m ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_bco
findPartiallyCompletedCycles :: [Module] -> [SCC ModSummary] -> Set.Set Module
findPartiallyCompletedCycles :: [Module] -> [SCC ModSummary] -> Set Module
findPartiallyCompletedCycles [Module]
modsDone [SCC ModSummary]
theGraph
= [Set Module] -> Set Module
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions
[Set Module
mods_in_this_cycle
| CyclicSCC [ModSummary]
vs <- [SCC ModSummary]
theGraph
, let names_in_this_cycle :: Set Module
names_in_this_cycle = [Module] -> Set Module
forall a. Ord a => [a] -> Set a
Set.fromList ((ModSummary -> Module) -> [ModSummary] -> [Module]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> Module
ms_mod [ModSummary]
vs)
mods_in_this_cycle :: Set Module
mods_in_this_cycle =
Set Module -> Set Module -> Set Module
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection ([Module] -> Set Module
forall a. Ord a => [a] -> Set a
Set.fromList [Module]
modsDone) Set Module
names_in_this_cycle
, Set Module -> Int
forall a. Set a -> Int
Set.size Set Module
mods_in_this_cycle Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Set Module -> Int
forall a. Set a -> Int
Set.size Set Module
names_in_this_cycle]
unload :: HscEnv -> [Linkable] -> IO ()
unload :: HscEnv -> [Linkable] -> IO ()
unload HscEnv
hsc_env [Linkable]
stable_linkables
= case DynFlags -> GhcLink
ghcLink (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) of
GhcLink
LinkInMemory -> HscEnv -> [Linkable] -> IO ()
Linker.unload HscEnv
hsc_env [Linkable]
stable_linkables
GhcLink
_other -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
type StableModules =
( UniqSet ModuleName
, UniqSet ModuleName
)
checkStability
:: HomePackageTable
-> [SCC ModSummary]
-> UniqSet ModuleName
-> StableModules
checkStability :: HomePackageTable
-> [SCC ModSummary]
-> UniqSet ModuleName
-> (UniqSet ModuleName, UniqSet ModuleName)
checkStability HomePackageTable
hpt [SCC ModSummary]
sccs UniqSet ModuleName
all_home_mods =
((UniqSet ModuleName, UniqSet ModuleName)
-> SCC ModSummary -> (UniqSet ModuleName, UniqSet ModuleName))
-> (UniqSet ModuleName, UniqSet ModuleName)
-> [SCC ModSummary]
-> (UniqSet ModuleName, UniqSet ModuleName)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (UniqSet ModuleName, UniqSet ModuleName)
-> SCC ModSummary -> (UniqSet ModuleName, UniqSet ModuleName)
checkSCC (UniqSet ModuleName
forall a. UniqSet a
emptyUniqSet, UniqSet ModuleName
forall a. UniqSet a
emptyUniqSet) [SCC ModSummary]
sccs
where
checkSCC :: StableModules -> SCC ModSummary -> StableModules
checkSCC :: (UniqSet ModuleName, UniqSet ModuleName)
-> SCC ModSummary -> (UniqSet ModuleName, UniqSet ModuleName)
checkSCC (UniqSet ModuleName
stable_obj, UniqSet ModuleName
stable_bco) SCC ModSummary
scc0
| Bool
stableObjects = (UniqSet ModuleName -> [ModuleName] -> UniqSet ModuleName
forall a. Uniquable a => UniqSet a -> [a] -> UniqSet a
addListToUniqSet UniqSet ModuleName
stable_obj [ModuleName]
scc_mods, UniqSet ModuleName
stable_bco)
| Bool
stableBCOs = (UniqSet ModuleName
stable_obj, UniqSet ModuleName -> [ModuleName] -> UniqSet ModuleName
forall a. Uniquable a => UniqSet a -> [a] -> UniqSet a
addListToUniqSet UniqSet ModuleName
stable_bco [ModuleName]
scc_mods)
| Bool
otherwise = (UniqSet ModuleName
stable_obj, UniqSet ModuleName
stable_bco)
where
scc :: [ModSummary]
scc = SCC ModSummary -> [ModSummary]
forall vertex. SCC vertex -> [vertex]
flattenSCC SCC ModSummary
scc0
scc_mods :: [ModuleName]
scc_mods = (ModSummary -> ModuleName) -> [ModSummary] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> ModuleName
ms_mod_name [ModSummary]
scc
home_module :: ModuleName -> Bool
home_module ModuleName
m =
ModuleName
m ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
all_home_mods Bool -> Bool -> Bool
&& ModuleName
m ModuleName -> [ModuleName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [ModuleName]
scc_mods
scc_allimps :: [ModuleName]
scc_allimps = [ModuleName] -> [ModuleName]
forall a. Eq a => [a] -> [a]
nub ((ModuleName -> Bool) -> [ModuleName] -> [ModuleName]
forall a. (a -> Bool) -> [a] -> [a]
filter ModuleName -> Bool
home_module ((ModSummary -> [ModuleName]) -> [ModSummary] -> [ModuleName]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ModSummary -> [ModuleName]
ms_home_allimps [ModSummary]
scc))
stable_obj_imps :: [Bool]
stable_obj_imps = (ModuleName -> Bool) -> [ModuleName] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_obj) [ModuleName]
scc_allimps
stable_bco_imps :: [Bool]
stable_bco_imps = (ModuleName -> Bool) -> [ModuleName] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_bco) [ModuleName]
scc_allimps
stableObjects :: Bool
stableObjects =
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [Bool]
stable_obj_imps
Bool -> Bool -> Bool
&& (ModSummary -> Bool) -> [ModSummary] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ModSummary -> Bool
object_ok [ModSummary]
scc
stableBCOs :: Bool
stableBCOs =
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ((Bool -> Bool -> Bool) -> [Bool] -> [Bool] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Bool -> Bool -> Bool
(||) [Bool]
stable_obj_imps [Bool]
stable_bco_imps)
Bool -> Bool -> Bool
&& (ModSummary -> Bool) -> [ModSummary] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ModSummary -> Bool
bco_ok [ModSummary]
scc
object_ok :: ModSummary -> Bool
object_ok ModSummary
ms
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_ForceRecomp (ModSummary -> DynFlags
ms_hspp_opts ModSummary
ms) = Bool
False
| Just UTCTime
t <- ModSummary -> Maybe UTCTime
ms_obj_date ModSummary
ms = UTCTime
t UTCTime -> UTCTime -> Bool
forall a. Ord a => a -> a -> Bool
>= ModSummary -> UTCTime
ms_hs_date ModSummary
ms
Bool -> Bool -> Bool
&& UTCTime -> Bool
same_as_prev UTCTime
t
| Bool
otherwise = Bool
False
where
same_as_prev :: UTCTime -> Bool
same_as_prev UTCTime
t = case HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
hpt (ModSummary -> ModuleName
ms_mod_name ModSummary
ms) of
Just HomeModInfo
hmi | Just Linkable
l <- HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi
-> Linkable -> Bool
isObjectLinkable Linkable
l Bool -> Bool -> Bool
&& UTCTime
t UTCTime -> UTCTime -> Bool
forall a. Eq a => a -> a -> Bool
== Linkable -> UTCTime
linkableTime Linkable
l
Maybe HomeModInfo
_other -> Bool
True
bco_ok :: ModSummary -> Bool
bco_ok ModSummary
ms
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_ForceRecomp (ModSummary -> DynFlags
ms_hspp_opts ModSummary
ms) = Bool
False
| Bool
otherwise = case HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
hpt (ModSummary -> ModuleName
ms_mod_name ModSummary
ms) of
Just HomeModInfo
hmi | Just Linkable
l <- HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi ->
Bool -> Bool
not (Linkable -> Bool
isObjectLinkable Linkable
l) Bool -> Bool -> Bool
&&
Linkable -> UTCTime
linkableTime Linkable
l UTCTime -> UTCTime -> Bool
forall a. Ord a => a -> a -> Bool
>= ModSummary -> UTCTime
ms_hs_date ModSummary
ms
Maybe HomeModInfo
_other -> Bool
False
data LogQueue = LogQueue !(IORef [Maybe (WarnReason, Severity, SrcSpan, MsgDoc)])
!(MVar ())
type CompilationGraph = [(ModSummary, MVar SuccessFlag, LogQueue)]
buildCompGraph :: [SCC ModSummary] -> IO (CompilationGraph, Maybe [ModSummary])
buildCompGraph :: [SCC ModSummary] -> IO (CompilationGraph, Maybe [ModSummary])
buildCompGraph [] = (CompilationGraph, Maybe [ModSummary])
-> IO (CompilationGraph, Maybe [ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return ([], Maybe [ModSummary]
forall a. Maybe a
Nothing)
buildCompGraph (SCC ModSummary
scc:[SCC ModSummary]
sccs) = case SCC ModSummary
scc of
AcyclicSCC ModSummary
ms -> do
MVar SuccessFlag
mvar <- IO (MVar SuccessFlag)
forall a. IO (MVar a)
newEmptyMVar
LogQueue
log_queue <- do
IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
ref <- [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> IO (IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)])
forall a. a -> IO (IORef a)
newIORef []
MVar ()
sem <- IO (MVar ())
forall a. IO (MVar a)
newEmptyMVar
LogQueue -> IO LogQueue
forall (m :: * -> *) a. Monad m => a -> m a
return (IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> MVar () -> LogQueue
LogQueue IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
ref MVar ()
sem)
(CompilationGraph
rest,Maybe [ModSummary]
cycle) <- [SCC ModSummary] -> IO (CompilationGraph, Maybe [ModSummary])
buildCompGraph [SCC ModSummary]
sccs
(CompilationGraph, Maybe [ModSummary])
-> IO (CompilationGraph, Maybe [ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return ((ModSummary
ms,MVar SuccessFlag
mvar,LogQueue
log_queue)(ModSummary, MVar SuccessFlag, LogQueue)
-> CompilationGraph -> CompilationGraph
forall a. a -> [a] -> [a]
:CompilationGraph
rest, Maybe [ModSummary]
cycle)
CyclicSCC [ModSummary]
mss -> (CompilationGraph, Maybe [ModSummary])
-> IO (CompilationGraph, Maybe [ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [ModSummary] -> Maybe [ModSummary]
forall a. a -> Maybe a
Just [ModSummary]
mss)
type BuildModule = ModuleWithIsBoot
hscSourceToIsBoot :: HscSource -> IsBootInterface
hscSourceToIsBoot :: HscSource -> IsBootInterface
hscSourceToIsBoot HscSource
HsBootFile = IsBootInterface
IsBoot
hscSourceToIsBoot HscSource
_ = IsBootInterface
NotBoot
mkBuildModule :: ModSummary -> BuildModule
mkBuildModule :: ModSummary -> BuildModule
mkBuildModule ModSummary
ms = GWIB :: forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB
{ gwib_mod :: Module
gwib_mod = ModSummary -> Module
ms_mod ModSummary
ms
, gwib_isBoot :: IsBootInterface
gwib_isBoot = ModSummary -> IsBootInterface
isBootSummary ModSummary
ms
}
mkHomeBuildModule :: ModSummary -> ModuleNameWithIsBoot
mkHomeBuildModule :: ModSummary -> NodeKey
mkHomeBuildModule ModSummary
ms = GWIB :: forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB
{ gwib_mod :: ModuleName
gwib_mod = Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (Module -> ModuleName) -> Module -> ModuleName
forall a b. (a -> b) -> a -> b
$ ModSummary -> Module
ms_mod ModSummary
ms
, gwib_isBoot :: IsBootInterface
gwib_isBoot = ModSummary -> IsBootInterface
isBootSummary ModSummary
ms
}
parUpsweep
:: GhcMonad m
=> Int
-> Maybe Messager
-> HomePackageTable
-> StableModules
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag,
[ModSummary])
parUpsweep :: forall (m :: * -> *).
GhcMonad m =>
Int
-> Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
parUpsweep Int
n_jobs Maybe Messager
mHscMessage HomePackageTable
old_hpt (UniqSet ModuleName, UniqSet ModuleName)
stable_mods HscEnv -> IO ()
cleanup [SCC ModSummary]
sccs = do
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
let dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not ([GenUnit UnitId] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DynFlags -> [GenUnit UnitId]
instantiatedUnitsToCheck DynFlags
dflags))) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
GhcException -> m ()
forall a. GhcException -> a
throwGhcException (FilePath -> GhcException
ProgramError FilePath
"Backpack typechecking not supported with -j")
MVar HscEnv
hsc_env_var <- IO (MVar HscEnv) -> m (MVar HscEnv)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MVar HscEnv) -> m (MVar HscEnv))
-> IO (MVar HscEnv) -> m (MVar HscEnv)
forall a b. (a -> b) -> a -> b
$ HscEnv -> IO (MVar HscEnv)
forall a. a -> IO (MVar a)
newMVar HscEnv
hsc_env
IORef HomePackageTable
old_hpt_var <- IO (IORef HomePackageTable) -> m (IORef HomePackageTable)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef HomePackageTable) -> m (IORef HomePackageTable))
-> IO (IORef HomePackageTable) -> m (IORef HomePackageTable)
forall a b. (a -> b) -> a -> b
$ HomePackageTable -> IO (IORef HomePackageTable)
forall a. a -> IO (IORef a)
newIORef HomePackageTable
old_hpt
QSem
par_sem <- IO QSem -> m QSem
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO QSem -> m QSem) -> IO QSem -> m QSem
forall a b. (a -> b) -> a -> b
$ Int -> IO QSem
newQSem Int
n_jobs
let updNumCapabilities :: m Int
updNumCapabilities = IO Int -> m Int
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Int -> m Int) -> IO Int -> m Int
forall a b. (a -> b) -> a -> b
$ do
Int
n_capabilities <- IO Int
getNumCapabilities
Int
n_cpus <- IO Int
getNumProcessors
let n_caps :: Int
n_caps = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n_jobs Int
n_cpus
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
n_capabilities Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
1) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> IO ()
setNumCapabilities Int
n_caps
Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n_capabilities
let resetNumCapabilities :: Int -> m ()
resetNumCapabilities Int
orig_n = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> IO ()
setNumCapabilities Int
orig_n
m Int
-> (Int -> m ())
-> (Int -> m (SuccessFlag, [ModSummary]))
-> m (SuccessFlag, [ModSummary])
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
MC.bracket m Int
updNumCapabilities Int -> m ()
forall {m :: * -> *}. MonadIO m => Int -> m ()
resetNumCapabilities ((Int -> m (SuccessFlag, [ModSummary]))
-> m (SuccessFlag, [ModSummary]))
-> (Int -> m (SuccessFlag, [ModSummary]))
-> m (SuccessFlag, [ModSummary])
forall a b. (a -> b) -> a -> b
$ \Int
_ -> do
let finallySyncSession :: m a -> m a
finallySyncSession m a
io = m a
io m a -> m () -> m a
forall (m :: * -> *) a b. MonadMask m => m a -> m b -> m a
`MC.finally` do
HscEnv
hsc_env <- IO HscEnv -> m HscEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO HscEnv -> m HscEnv) -> IO HscEnv -> m HscEnv
forall a b. (a -> b) -> a -> b
$ MVar HscEnv -> IO HscEnv
forall a. MVar a -> IO a
readMVar MVar HscEnv
hsc_env_var
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env
m (SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall (m :: * -> *) a. GhcMonad m => m a -> m a
finallySyncSession (m (SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary]))
-> m (SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall a b. (a -> b) -> a -> b
$ do
(CompilationGraph
comp_graph,Maybe [ModSummary]
cycle) <- IO (CompilationGraph, Maybe [ModSummary])
-> m (CompilationGraph, Maybe [ModSummary])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (CompilationGraph, Maybe [ModSummary])
-> m (CompilationGraph, Maybe [ModSummary]))
-> IO (CompilationGraph, Maybe [ModSummary])
-> m (CompilationGraph, Maybe [ModSummary])
forall a b. (a -> b) -> a -> b
$ [SCC ModSummary] -> IO (CompilationGraph, Maybe [ModSummary])
buildCompGraph [SCC ModSummary]
sccs
let comp_graph_w_idx :: [((ModSummary, MVar SuccessFlag, LogQueue), Int)]
comp_graph_w_idx = CompilationGraph
-> [Int] -> [((ModSummary, MVar SuccessFlag, LogQueue), Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip CompilationGraph
comp_graph [Int
1..]
let graph :: [ModSummary]
graph = ((ModSummary, MVar SuccessFlag, LogQueue) -> ModSummary)
-> CompilationGraph -> [ModSummary]
forall a b. (a -> b) -> [a] -> [b]
map (ModSummary, MVar SuccessFlag, LogQueue) -> ModSummary
forall a b c. (a, b, c) -> a
fstOf3 (CompilationGraph -> CompilationGraph
forall a. [a] -> [a]
reverse CompilationGraph
comp_graph)
boot_modules :: ModuleSet
boot_modules = [Module] -> ModuleSet
mkModuleSet [ModSummary -> Module
ms_mod ModSummary
ms | ModSummary
ms <- [ModSummary]
graph, ModSummary -> IsBootInterface
isBootSummary ModSummary
ms IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
IsBoot]
comp_graph_loops :: [[BuildModule]]
comp_graph_loops = [ModSummary] -> ModuleSet -> [[BuildModule]]
go [ModSummary]
graph ModuleSet
boot_modules
where
remove :: ModSummary -> ModuleSet -> ModuleSet
remove ModSummary
ms ModuleSet
bm = case ModSummary -> IsBootInterface
isBootSummary ModSummary
ms of
IsBootInterface
IsBoot -> ModuleSet -> Module -> ModuleSet
delModuleSet ModuleSet
bm (ModSummary -> Module
ms_mod ModSummary
ms)
IsBootInterface
NotBoot -> ModuleSet
bm
go :: [ModSummary] -> ModuleSet -> [[BuildModule]]
go [] ModuleSet
_ = []
go mg :: [ModSummary]
mg@(ModSummary
ms:[ModSummary]
mss) ModuleSet
boot_modules
| Just [ModSummary]
loop <- ModSummary
-> [ModSummary] -> (Module -> Bool) -> Maybe [ModSummary]
getModLoop ModSummary
ms [ModSummary]
mg (Module -> ModuleSet -> Bool
`elemModuleSet` ModuleSet
boot_modules)
= (ModSummary -> BuildModule) -> [ModSummary] -> [BuildModule]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> BuildModule
mkBuildModule (ModSummary
msModSummary -> [ModSummary] -> [ModSummary]
forall a. a -> [a] -> [a]
:[ModSummary]
loop) [BuildModule] -> [[BuildModule]] -> [[BuildModule]]
forall a. a -> [a] -> [a]
: [ModSummary] -> ModuleSet -> [[BuildModule]]
go [ModSummary]
mss (ModSummary -> ModuleSet -> ModuleSet
remove ModSummary
ms ModuleSet
boot_modules)
| Bool
otherwise
= [ModSummary] -> ModuleSet -> [[BuildModule]]
go [ModSummary]
mss (ModSummary -> ModuleSet -> ModuleSet
remove ModSummary
ms ModuleSet
boot_modules)
let home_mod_map :: Map BuildModule (MVar SuccessFlag, Int)
home_mod_map :: Map BuildModule (MVar SuccessFlag, Int)
home_mod_map =
[(BuildModule, (MVar SuccessFlag, Int))]
-> Map BuildModule (MVar SuccessFlag, Int)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (ModSummary -> BuildModule
mkBuildModule ModSummary
ms, (MVar SuccessFlag
mvar, Int
idx))
| ((ModSummary
ms,MVar SuccessFlag
mvar,LogQueue
_),Int
idx) <- [((ModSummary, MVar SuccessFlag, LogQueue), Int)]
comp_graph_w_idx ]
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ()
label_self FilePath
"main --make thread"
let { spawnWorkers :: IO [ThreadId]
spawnWorkers = [((ModSummary, MVar SuccessFlag, LogQueue), Int)]
-> (((ModSummary, MVar SuccessFlag, LogQueue), Int) -> IO ThreadId)
-> IO [ThreadId]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [((ModSummary, MVar SuccessFlag, LogQueue), Int)]
comp_graph_w_idx ((((ModSummary, MVar SuccessFlag, LogQueue), Int) -> IO ThreadId)
-> IO [ThreadId])
-> (((ModSummary, MVar SuccessFlag, LogQueue), Int) -> IO ThreadId)
-> IO [ThreadId]
forall a b. (a -> b) -> a -> b
$ \((ModSummary
mod,!MVar SuccessFlag
mvar,!LogQueue
log_queue),!Int
mod_idx) ->
((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId
forkIOWithUnmask (((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId)
-> ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
unmask -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ()
label_self (FilePath -> IO ()) -> FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ [FilePath] -> FilePath
unwords
[ FilePath
"worker --make thread"
, FilePath
"for module"
, FilePath -> FilePath
forall a. Show a => a -> FilePath
show (ModuleName -> FilePath
moduleNameString (ModSummary -> ModuleName
ms_mod_name ModSummary
mod))
, FilePath
"number"
, Int -> FilePath
forall a. Show a => a -> FilePath
show Int
mod_idx
]
IORef FilesToClean
lcl_files_to_clean <- FilesToClean -> IO (IORef FilesToClean)
forall a. a -> IO (IORef a)
newIORef FilesToClean
emptyFilesToClean
let lcl_dflags :: DynFlags
lcl_dflags = DynFlags
dflags { log_action :: LogAction
log_action = LogQueue -> LogAction
parLogAction LogQueue
log_queue
, filesToClean :: IORef FilesToClean
filesToClean = IORef FilesToClean
lcl_files_to_clean }
Either SomeException SuccessFlag
m_res <- IO SuccessFlag -> IO (Either SomeException SuccessFlag)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
MC.try (IO SuccessFlag -> IO (Either SomeException SuccessFlag))
-> IO SuccessFlag -> IO (Either SomeException SuccessFlag)
forall a b. (a -> b) -> a -> b
$ IO SuccessFlag -> IO SuccessFlag
forall a. IO a -> IO a
unmask (IO SuccessFlag -> IO SuccessFlag)
-> IO SuccessFlag -> IO SuccessFlag
forall a b. (a -> b) -> a -> b
$ DynFlags -> IO SuccessFlag -> IO SuccessFlag
forall (m :: * -> *) a. ExceptionMonad m => DynFlags -> m a -> m a
prettyPrintGhcErrors DynFlags
lcl_dflags (IO SuccessFlag -> IO SuccessFlag)
-> IO SuccessFlag -> IO SuccessFlag
forall a b. (a -> b) -> a -> b
$
ModSummary
-> Map BuildModule (MVar SuccessFlag, Int)
-> [[BuildModule]]
-> DynFlags
-> Maybe Messager
-> (HscEnv -> IO ())
-> QSem
-> MVar HscEnv
-> IORef HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> Int
-> Int
-> IO SuccessFlag
parUpsweep_one ModSummary
mod Map BuildModule (MVar SuccessFlag, Int)
home_mod_map [[BuildModule]]
comp_graph_loops
DynFlags
lcl_dflags Maybe Messager
mHscMessage HscEnv -> IO ()
cleanup
QSem
par_sem MVar HscEnv
hsc_env_var IORef HomePackageTable
old_hpt_var
(UniqSet ModuleName, UniqSet ModuleName)
stable_mods Int
mod_idx ([SCC ModSummary] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SCC ModSummary]
sccs)
SuccessFlag
res <- case Either SomeException SuccessFlag
m_res of
Right SuccessFlag
flag -> SuccessFlag -> IO SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
flag
Left SomeException
exc -> do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (SomeException -> Maybe AsyncException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
exc Maybe AsyncException -> Maybe AsyncException -> Bool
forall a. Eq a => a -> a -> Bool
/= AsyncException -> Maybe AsyncException
forall a. a -> Maybe a
Just AsyncException
ThreadKilled)
(DynFlags -> SDoc -> IO ()
errorMsg DynFlags
lcl_dflags (FilePath -> SDoc
text (SomeException -> FilePath
forall a. Show a => a -> FilePath
show SomeException
exc)))
SuccessFlag -> IO SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
Failed
MVar SuccessFlag -> SuccessFlag -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar SuccessFlag
mvar SuccessFlag
res
LogQueue -> Maybe (WarnReason, Severity, SrcSpan, SDoc) -> IO ()
writeLogQueue LogQueue
log_queue Maybe (WarnReason, Severity, SrcSpan, SDoc)
forall a. Maybe a
Nothing
FilesToClean
{ ftcCurrentModule :: FilesToClean -> Set FilePath
ftcCurrentModule = Set FilePath
cm_files
, ftcGhcSession :: FilesToClean -> Set FilePath
ftcGhcSession = Set FilePath
gs_files
} <- IORef FilesToClean -> IO FilesToClean
forall a. IORef a -> IO a
readIORef (DynFlags -> IORef FilesToClean
filesToClean DynFlags
lcl_dflags)
DynFlags -> TempFileLifetime -> [FilePath] -> IO ()
addFilesToClean DynFlags
dflags TempFileLifetime
TFL_CurrentModule ([FilePath] -> IO ()) -> [FilePath] -> IO ()
forall a b. (a -> b) -> a -> b
$ Set FilePath -> [FilePath]
forall a. Set a -> [a]
Set.toList Set FilePath
cm_files
DynFlags -> TempFileLifetime -> [FilePath] -> IO ()
addFilesToClean DynFlags
dflags TempFileLifetime
TFL_GhcSession ([FilePath] -> IO ()) -> [FilePath] -> IO ()
forall a b. (a -> b) -> a -> b
$ Set FilePath -> [FilePath]
forall a. Set a -> [a]
Set.toList Set FilePath
gs_files
; killWorkers :: [ThreadId] -> IO ()
killWorkers = IO () -> IO ()
forall (m :: * -> *) a. MonadMask m => m a -> m a
MC.uninterruptibleMask_ (IO () -> IO ()) -> ([ThreadId] -> IO ()) -> [ThreadId] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ThreadId -> IO ()) -> [ThreadId] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ThreadId -> IO ()
killThread }
[Maybe ModSummary]
results <- IO [Maybe ModSummary] -> m [Maybe ModSummary]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Maybe ModSummary] -> m [Maybe ModSummary])
-> IO [Maybe ModSummary] -> m [Maybe ModSummary]
forall a b. (a -> b) -> a -> b
$ IO [ThreadId]
-> ([ThreadId] -> IO ())
-> ([ThreadId] -> IO [Maybe ModSummary])
-> IO [Maybe ModSummary]
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
MC.bracket IO [ThreadId]
spawnWorkers [ThreadId] -> IO ()
killWorkers (([ThreadId] -> IO [Maybe ModSummary]) -> IO [Maybe ModSummary])
-> ([ThreadId] -> IO [Maybe ModSummary]) -> IO [Maybe ModSummary]
forall a b. (a -> b) -> a -> b
$ \[ThreadId]
_ ->
CompilationGraph
-> ((ModSummary, MVar SuccessFlag, LogQueue)
-> IO (Maybe ModSummary))
-> IO [Maybe ModSummary]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM CompilationGraph
comp_graph (((ModSummary, MVar SuccessFlag, LogQueue)
-> IO (Maybe ModSummary))
-> IO [Maybe ModSummary])
-> ((ModSummary, MVar SuccessFlag, LogQueue)
-> IO (Maybe ModSummary))
-> IO [Maybe ModSummary]
forall a b. (a -> b) -> a -> b
$ \(ModSummary
mod,MVar SuccessFlag
mvar,LogQueue
log_queue) -> do
DynFlags -> LogQueue -> IO ()
printLogs DynFlags
dflags LogQueue
log_queue
SuccessFlag
result <- MVar SuccessFlag -> IO SuccessFlag
forall a. MVar a -> IO a
readMVar MVar SuccessFlag
mvar
if SuccessFlag -> Bool
succeeded SuccessFlag
result then Maybe ModSummary -> IO (Maybe ModSummary)
forall (m :: * -> *) a. Monad m => a -> m a
return (ModSummary -> Maybe ModSummary
forall a. a -> Maybe a
Just ModSummary
mod) else Maybe ModSummary -> IO (Maybe ModSummary)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ModSummary
forall a. Maybe a
Nothing
let ok_results :: [ModSummary]
ok_results = [ModSummary] -> [ModSummary]
forall a. [a] -> [a]
reverse ([Maybe ModSummary] -> [ModSummary]
forall a. [Maybe a] -> [a]
catMaybes [Maybe ModSummary]
results)
case Maybe [ModSummary]
cycle of
Just [ModSummary]
mss -> do
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> IO ()
fatalErrorMsg DynFlags
dflags ([ModSummary] -> SDoc
cyclicModuleErr [ModSummary]
mss)
(SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
Failed,[ModSummary]
ok_results)
Maybe [ModSummary]
Nothing -> do
let success_flag :: SuccessFlag
success_flag = Bool -> SuccessFlag
successIf ((Maybe ModSummary -> Bool) -> [Maybe ModSummary] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Maybe ModSummary -> Bool
forall a. Maybe a -> Bool
isJust [Maybe ModSummary]
results)
(SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
success_flag,[ModSummary]
ok_results)
where
writeLogQueue :: LogQueue -> Maybe (WarnReason,Severity,SrcSpan,MsgDoc) -> IO ()
writeLogQueue :: LogQueue -> Maybe (WarnReason, Severity, SrcSpan, SDoc) -> IO ()
writeLogQueue (LogQueue IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
ref MVar ()
sem) Maybe (WarnReason, Severity, SrcSpan, SDoc)
msg = do
IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)], ()))
-> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
ref (([Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)], ()))
-> IO ())
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)], ()))
-> IO ()
forall a b. (a -> b) -> a -> b
$ \[Maybe (WarnReason, Severity, SrcSpan, SDoc)]
msgs -> (Maybe (WarnReason, Severity, SrcSpan, SDoc)
msgMaybe (WarnReason, Severity, SrcSpan, SDoc)
-> [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
forall a. a -> [a] -> [a]
:[Maybe (WarnReason, Severity, SrcSpan, SDoc)]
msgs,())
Bool
_ <- MVar () -> () -> IO Bool
forall a. MVar a -> a -> IO Bool
tryPutMVar MVar ()
sem ()
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
parLogAction :: LogQueue -> LogAction
parLogAction :: LogQueue -> LogAction
parLogAction LogQueue
log_queue DynFlags
_dflags !WarnReason
reason !Severity
severity !SrcSpan
srcSpan !SDoc
msg = do
LogQueue -> Maybe (WarnReason, Severity, SrcSpan, SDoc) -> IO ()
writeLogQueue LogQueue
log_queue ((WarnReason, Severity, SrcSpan, SDoc)
-> Maybe (WarnReason, Severity, SrcSpan, SDoc)
forall a. a -> Maybe a
Just (WarnReason
reason,Severity
severity,SrcSpan
srcSpan,SDoc
msg))
printLogs :: DynFlags -> LogQueue -> IO ()
printLogs :: DynFlags -> LogQueue -> IO ()
printLogs !DynFlags
dflags (LogQueue IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
ref MVar ()
sem) = IO ()
read_msgs
where read_msgs :: IO ()
read_msgs = do
MVar () -> IO ()
forall a. MVar a -> IO a
takeMVar MVar ()
sem
[Maybe (WarnReason, Severity, SrcSpan, SDoc)]
msgs <- IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)],
[Maybe (WarnReason, Severity, SrcSpan, SDoc)]))
-> IO [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
ref (([Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)],
[Maybe (WarnReason, Severity, SrcSpan, SDoc)]))
-> IO [Maybe (WarnReason, Severity, SrcSpan, SDoc)])
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> ([Maybe (WarnReason, Severity, SrcSpan, SDoc)],
[Maybe (WarnReason, Severity, SrcSpan, SDoc)]))
-> IO [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
forall a b. (a -> b) -> a -> b
$ \[Maybe (WarnReason, Severity, SrcSpan, SDoc)]
xs -> ([], [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
-> [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
forall a. [a] -> [a]
reverse [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
xs)
[Maybe (WarnReason, Severity, SrcSpan, SDoc)] -> IO ()
print_loop [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
msgs
print_loop :: [Maybe (WarnReason, Severity, SrcSpan, SDoc)] -> IO ()
print_loop [] = IO ()
read_msgs
print_loop (Maybe (WarnReason, Severity, SrcSpan, SDoc)
x:[Maybe (WarnReason, Severity, SrcSpan, SDoc)]
xs) = case Maybe (WarnReason, Severity, SrcSpan, SDoc)
x of
Just (WarnReason
reason,Severity
severity,SrcSpan
srcSpan,SDoc
msg) -> do
LogAction
putLogMsg DynFlags
dflags WarnReason
reason Severity
severity SrcSpan
srcSpan SDoc
msg
[Maybe (WarnReason, Severity, SrcSpan, SDoc)] -> IO ()
print_loop [Maybe (WarnReason, Severity, SrcSpan, SDoc)]
xs
Maybe (WarnReason, Severity, SrcSpan, SDoc)
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
parUpsweep_one
:: ModSummary
-> Map BuildModule (MVar SuccessFlag, Int)
-> [[BuildModule]]
-> DynFlags
-> Maybe Messager
-> (HscEnv -> IO ())
-> QSem
-> MVar HscEnv
-> IORef HomePackageTable
-> StableModules
-> Int
-> Int
-> IO SuccessFlag
parUpsweep_one :: ModSummary
-> Map BuildModule (MVar SuccessFlag, Int)
-> [[BuildModule]]
-> DynFlags
-> Maybe Messager
-> (HscEnv -> IO ())
-> QSem
-> MVar HscEnv
-> IORef HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> Int
-> Int
-> IO SuccessFlag
parUpsweep_one ModSummary
mod Map BuildModule (MVar SuccessFlag, Int)
home_mod_map [[BuildModule]]
comp_graph_loops DynFlags
lcl_dflags Maybe Messager
mHscMessage HscEnv -> IO ()
cleanup QSem
par_sem
MVar HscEnv
hsc_env_var IORef HomePackageTable
old_hpt_var (UniqSet ModuleName, UniqSet ModuleName)
stable_mods Int
mod_index Int
num_mods = do
let this_build_mod :: BuildModule
this_build_mod = ModSummary -> BuildModule
mkBuildModule ModSummary
mod
let home_imps :: [ModuleName]
home_imps = (GenLocated SrcSpan ModuleName -> ModuleName)
-> [GenLocated SrcSpan ModuleName] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc ([GenLocated SrcSpan ModuleName] -> [ModuleName])
-> [GenLocated SrcSpan ModuleName] -> [ModuleName]
forall a b. (a -> b) -> a -> b
$ ModSummary -> [GenLocated SrcSpan ModuleName]
ms_home_imps ModSummary
mod
let home_src_imps :: [ModuleName]
home_src_imps = (GenLocated SrcSpan ModuleName -> ModuleName)
-> [GenLocated SrcSpan ModuleName] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc ([GenLocated SrcSpan ModuleName] -> [ModuleName])
-> [GenLocated SrcSpan ModuleName] -> [ModuleName]
forall a b. (a -> b) -> a -> b
$ ModSummary -> [GenLocated SrcSpan ModuleName]
ms_home_srcimps ModSummary
mod
let textual_deps :: Set BuildModule
textual_deps = [BuildModule] -> Set BuildModule
forall a. Ord a => [a] -> Set a
Set.fromList ([BuildModule] -> Set BuildModule)
-> [BuildModule] -> Set BuildModule
forall a b. (a -> b) -> a -> b
$
(ModuleName -> IsBootInterface -> BuildModule)
-> [ModuleName] -> [IsBootInterface] -> [BuildModule]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ModuleName -> IsBootInterface -> BuildModule
f [ModuleName]
home_imps (IsBootInterface -> [IsBootInterface]
forall a. a -> [a]
repeat IsBootInterface
NotBoot) [BuildModule] -> [BuildModule] -> [BuildModule]
forall a. [a] -> [a] -> [a]
++
(ModuleName -> IsBootInterface -> BuildModule)
-> [ModuleName] -> [IsBootInterface] -> [BuildModule]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ModuleName -> IsBootInterface -> BuildModule
f [ModuleName]
home_src_imps (IsBootInterface -> [IsBootInterface]
forall a. a -> [a]
repeat IsBootInterface
IsBoot)
where f :: ModuleName -> IsBootInterface -> BuildModule
f ModuleName
mn IsBootInterface
isBoot = GWIB :: forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB
{ gwib_mod :: Module
gwib_mod = DynFlags -> ModuleName -> Module
mkHomeModule DynFlags
lcl_dflags ModuleName
mn
, gwib_isBoot :: IsBootInterface
gwib_isBoot = IsBootInterface
isBoot
}
let finish_loop :: Maybe [BuildModule]
finish_loop = [[BuildModule]] -> Maybe [BuildModule]
forall a. [a] -> Maybe a
listToMaybe
[ [BuildModule] -> [BuildModule]
forall a. [a] -> [a]
tail [BuildModule]
loop | [BuildModule]
loop <- [[BuildModule]]
comp_graph_loops
, [BuildModule] -> BuildModule
forall a. [a] -> a
head [BuildModule]
loop BuildModule -> BuildModule -> Bool
forall a. Eq a => a -> a -> Bool
== BuildModule
this_build_mod ]
let int_loop_deps :: Set BuildModule
int_loop_deps = [BuildModule] -> Set BuildModule
forall a. Ord a => [a] -> Set a
Set.fromList ([BuildModule] -> Set BuildModule)
-> [BuildModule] -> Set BuildModule
forall a b. (a -> b) -> a -> b
$
case Maybe [BuildModule]
finish_loop of
Maybe [BuildModule]
Nothing -> []
Just [BuildModule]
loop -> (BuildModule -> Bool) -> [BuildModule] -> [BuildModule]
forall a. (a -> Bool) -> [a] -> [a]
filter (BuildModule -> BuildModule -> Bool
forall a. Eq a => a -> a -> Bool
/= BuildModule
this_build_mod) [BuildModule]
loop
let ext_loop_deps :: Set BuildModule
ext_loop_deps = [BuildModule] -> Set BuildModule
forall a. Ord a => [a] -> Set a
Set.fromList
[ [BuildModule] -> BuildModule
forall a. [a] -> a
head [BuildModule]
loop | [BuildModule]
loop <- [[BuildModule]]
comp_graph_loops
, (BuildModule -> Bool) -> [BuildModule] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (BuildModule -> Set BuildModule -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set BuildModule
textual_deps) [BuildModule]
loop
, BuildModule
this_build_mod BuildModule -> [BuildModule] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [BuildModule]
loop ]
let all_deps :: Set BuildModule
all_deps = (Set BuildModule -> Set BuildModule -> Set BuildModule)
-> [Set BuildModule] -> Set BuildModule
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Set BuildModule -> Set BuildModule -> Set BuildModule
forall a. Ord a => Set a -> Set a -> Set a
Set.union [Set BuildModule
textual_deps, Set BuildModule
int_loop_deps, Set BuildModule
ext_loop_deps]
let home_deps_with_idx :: [(MVar SuccessFlag, Int)]
home_deps_with_idx =
[ (MVar SuccessFlag, Int)
home_dep | BuildModule
dep <- Set BuildModule -> [BuildModule]
forall a. Set a -> [a]
Set.toList Set BuildModule
all_deps
, Just (MVar SuccessFlag, Int)
home_dep <- [BuildModule
-> Map BuildModule (MVar SuccessFlag, Int)
-> Maybe (MVar SuccessFlag, Int)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup BuildModule
dep Map BuildModule (MVar SuccessFlag, Int)
home_mod_map] ]
let home_deps :: [MVar SuccessFlag]
home_deps = ((MVar SuccessFlag, Int) -> MVar SuccessFlag)
-> [(MVar SuccessFlag, Int)] -> [MVar SuccessFlag]
forall a b. (a -> b) -> [a] -> [b]
map (MVar SuccessFlag, Int) -> MVar SuccessFlag
forall a b. (a, b) -> a
fst ([(MVar SuccessFlag, Int)] -> [MVar SuccessFlag])
-> [(MVar SuccessFlag, Int)] -> [MVar SuccessFlag]
forall a b. (a -> b) -> a -> b
$ ((MVar SuccessFlag, Int) -> (MVar SuccessFlag, Int) -> Ordering)
-> [(MVar SuccessFlag, Int)] -> [(MVar SuccessFlag, Int)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((MVar SuccessFlag, Int) -> (MVar SuccessFlag, Int) -> Ordering)
-> (MVar SuccessFlag, Int) -> (MVar SuccessFlag, Int) -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((MVar SuccessFlag, Int) -> Int)
-> (MVar SuccessFlag, Int) -> (MVar SuccessFlag, Int) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (MVar SuccessFlag, Int) -> Int
forall a b. (a, b) -> b
snd)) [(MVar SuccessFlag, Int)]
home_deps_with_idx
Bool
deps_ok <- (MVar SuccessFlag -> IO Bool) -> [MVar SuccessFlag] -> IO Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
allM ((SuccessFlag -> Bool) -> IO SuccessFlag -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SuccessFlag -> Bool
succeeded (IO SuccessFlag -> IO Bool)
-> (MVar SuccessFlag -> IO SuccessFlag)
-> MVar SuccessFlag
-> IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar SuccessFlag -> IO SuccessFlag
forall a. MVar a -> IO a
readMVar) [MVar SuccessFlag]
home_deps
if Bool -> Bool
not Bool
deps_ok
then SuccessFlag -> IO SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
Failed
else do
HscEnv
hsc_env <- MVar HscEnv -> IO HscEnv
forall a. MVar a -> IO a
readMVar MVar HscEnv
hsc_env_var
HomePackageTable
old_hpt <- IORef HomePackageTable -> IO HomePackageTable
forall a. IORef a -> IO a
readIORef IORef HomePackageTable
old_hpt_var
let logger :: SourceError -> IO ()
logger SourceError
err = DynFlags -> ErrorMessages -> IO ()
printBagOfErrors DynFlags
lcl_dflags (SourceError -> ErrorMessages
srcErrorMessages SourceError
err)
let withSem :: QSem -> IO b -> IO b
withSem QSem
sem = IO () -> IO () -> IO b -> IO b
forall (m :: * -> *) a c b. MonadMask m => m a -> m c -> m b -> m b
MC.bracket_ (QSem -> IO ()
waitQSem QSem
sem) (QSem -> IO ()
signalQSem QSem
sem)
Maybe HomeModInfo
mb_mod_info <- QSem -> IO (Maybe HomeModInfo) -> IO (Maybe HomeModInfo)
forall {b}. QSem -> IO b -> IO b
withSem QSem
par_sem (IO (Maybe HomeModInfo) -> IO (Maybe HomeModInfo))
-> IO (Maybe HomeModInfo) -> IO (Maybe HomeModInfo)
forall a b. (a -> b) -> a -> b
$
(SourceError -> IO (Maybe HomeModInfo))
-> IO (Maybe HomeModInfo) -> IO (Maybe HomeModInfo)
forall (m :: * -> *) a.
MonadCatch m =>
(SourceError -> m a) -> m a -> m a
handleSourceError (\SourceError
err -> do SourceError -> IO ()
logger SourceError
err; Maybe HomeModInfo -> IO (Maybe HomeModInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe HomeModInfo
forall a. Maybe a
Nothing) (IO (Maybe HomeModInfo) -> IO (Maybe HomeModInfo))
-> IO (Maybe HomeModInfo) -> IO (Maybe HomeModInfo)
forall a b. (a -> b) -> a -> b
$ do
let lcl_mod :: ModSummary
lcl_mod = ModSummary -> ModSummary
localize_mod ModSummary
mod
let lcl_hsc_env :: HscEnv
lcl_hsc_env = HscEnv -> HscEnv
localize_hsc_env HscEnv
hsc_env
IORef (NameEnv TyThing)
type_env_var <- IO (IORef (NameEnv TyThing)) -> IO (IORef (NameEnv TyThing))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (NameEnv TyThing)) -> IO (IORef (NameEnv TyThing)))
-> IO (IORef (NameEnv TyThing)) -> IO (IORef (NameEnv TyThing))
forall a b. (a -> b) -> a -> b
$ NameEnv TyThing -> IO (IORef (NameEnv TyThing))
forall a. a -> IO (IORef a)
newIORef NameEnv TyThing
forall a. NameEnv a
emptyNameEnv
let lcl_hsc_env' :: HscEnv
lcl_hsc_env' = HscEnv
lcl_hsc_env { hsc_type_env_var :: Maybe (Module, IORef (NameEnv TyThing))
hsc_type_env_var =
(Module, IORef (NameEnv TyThing))
-> Maybe (Module, IORef (NameEnv TyThing))
forall a. a -> Maybe a
Just (ModSummary -> Module
ms_mod ModSummary
lcl_mod, IORef (NameEnv TyThing)
type_env_var) }
HscEnv
lcl_hsc_env'' <- case Maybe [BuildModule]
finish_loop of
Maybe [BuildModule]
Nothing -> HscEnv -> IO HscEnv
forall (m :: * -> *) a. Monad m => a -> m a
return HscEnv
lcl_hsc_env'
Just [BuildModule]
loop -> DynFlags -> HscEnv -> [ModuleName] -> IO HscEnv
typecheckLoop DynFlags
lcl_dflags HscEnv
lcl_hsc_env' ([ModuleName] -> IO HscEnv) -> [ModuleName] -> IO HscEnv
forall a b. (a -> b) -> a -> b
$
(ModuleName -> Bool) -> [ModuleName] -> [ModuleName]
forall a. (a -> Bool) -> [a] -> [a]
filter (ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
/= Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (BuildModule -> Module
forall mod. GenWithIsBoot mod -> mod
gwib_mod BuildModule
this_build_mod)) ([ModuleName] -> [ModuleName]) -> [ModuleName] -> [ModuleName]
forall a b. (a -> b) -> a -> b
$
(BuildModule -> ModuleName) -> [BuildModule] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (Module -> ModuleName)
-> (BuildModule -> Module) -> BuildModule -> ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildModule -> Module
forall mod. GenWithIsBoot mod -> mod
gwib_mod) [BuildModule]
loop
HomeModInfo
mod_info <- HscEnv
-> Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> ModSummary
-> Int
-> Int
-> IO HomeModInfo
upsweep_mod HscEnv
lcl_hsc_env'' Maybe Messager
mHscMessage HomePackageTable
old_hpt (UniqSet ModuleName, UniqSet ModuleName)
stable_mods
ModSummary
lcl_mod Int
mod_index Int
num_mods
Maybe HomeModInfo -> IO (Maybe HomeModInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return (HomeModInfo -> Maybe HomeModInfo
forall a. a -> Maybe a
Just HomeModInfo
mod_info)
case Maybe HomeModInfo
mb_mod_info of
Maybe HomeModInfo
Nothing -> SuccessFlag -> IO SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
Failed
Just HomeModInfo
mod_info -> do
let this_mod :: ModuleName
this_mod = ModSummary -> ModuleName
ms_mod_name ModSummary
mod
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ModSummary -> IsBootInterface
isBootSummary ModSummary
mod IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
IsBoot) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
IORef HomePackageTable
-> (HomePackageTable -> (HomePackageTable, ())) -> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef HomePackageTable
old_hpt_var ((HomePackageTable -> (HomePackageTable, ())) -> IO ())
-> (HomePackageTable -> (HomePackageTable, ())) -> IO ()
forall a b. (a -> b) -> a -> b
$ \HomePackageTable
old_hpt ->
(HomePackageTable -> ModuleName -> HomePackageTable
delFromHpt HomePackageTable
old_hpt ModuleName
this_mod, ())
HscEnv
lcl_hsc_env' <- MVar HscEnv -> (HscEnv -> IO (HscEnv, HscEnv)) -> IO HscEnv
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar MVar HscEnv
hsc_env_var ((HscEnv -> IO (HscEnv, HscEnv)) -> IO HscEnv)
-> (HscEnv -> IO (HscEnv, HscEnv)) -> IO HscEnv
forall a b. (a -> b) -> a -> b
$ \HscEnv
hsc_env -> do
let hsc_env' :: HscEnv
hsc_env' = HscEnv
hsc_env
{ hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable -> ModuleName -> HomeModInfo -> HomePackageTable
addToHpt (HscEnv -> HomePackageTable
hsc_HPT HscEnv
hsc_env)
ModuleName
this_mod HomeModInfo
mod_info }
HscEnv
hsc_env'' <- case Maybe [BuildModule]
finish_loop of
Maybe [BuildModule]
Nothing -> HscEnv -> IO HscEnv
forall (m :: * -> *) a. Monad m => a -> m a
return HscEnv
hsc_env'
Just [BuildModule]
loop -> DynFlags -> HscEnv -> [ModuleName] -> IO HscEnv
typecheckLoop DynFlags
lcl_dflags HscEnv
hsc_env' ([ModuleName] -> IO HscEnv) -> [ModuleName] -> IO HscEnv
forall a b. (a -> b) -> a -> b
$
(BuildModule -> ModuleName) -> [BuildModule] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (Module -> ModuleName)
-> (BuildModule -> Module) -> BuildModule -> ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuildModule -> Module
forall mod. GenWithIsBoot mod -> mod
gwib_mod) [BuildModule]
loop
(HscEnv, HscEnv) -> IO (HscEnv, HscEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (HscEnv
hsc_env'', HscEnv -> HscEnv
localize_hsc_env HscEnv
hsc_env'')
HscEnv -> IO ()
cleanup HscEnv
lcl_hsc_env'
SuccessFlag -> IO SuccessFlag
forall (m :: * -> *) a. Monad m => a -> m a
return SuccessFlag
Succeeded
where
localize_mod :: ModSummary -> ModSummary
localize_mod ModSummary
mod
= ModSummary
mod { ms_hspp_opts :: DynFlags
ms_hspp_opts = (ModSummary -> DynFlags
ms_hspp_opts ModSummary
mod)
{ log_action :: LogAction
log_action = DynFlags -> LogAction
log_action DynFlags
lcl_dflags
, filesToClean :: IORef FilesToClean
filesToClean = DynFlags -> IORef FilesToClean
filesToClean DynFlags
lcl_dflags } }
localize_hsc_env :: HscEnv -> HscEnv
localize_hsc_env HscEnv
hsc_env
= HscEnv
hsc_env { hsc_dflags :: DynFlags
hsc_dflags = (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env)
{ log_action :: LogAction
log_action = DynFlags -> LogAction
log_action DynFlags
lcl_dflags
, filesToClean :: IORef FilesToClean
filesToClean = DynFlags -> IORef FilesToClean
filesToClean DynFlags
lcl_dflags } }
upsweep
:: GhcMonad m
=> Maybe Messager
-> HomePackageTable
-> StableModules
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag,
[ModSummary])
upsweep :: forall (m :: * -> *).
GhcMonad m =>
Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> (HscEnv -> IO ())
-> [SCC ModSummary]
-> m (SuccessFlag, [ModSummary])
upsweep Maybe Messager
mHscMessage HomePackageTable
old_hpt (UniqSet ModuleName, UniqSet ModuleName)
stable_mods HscEnv -> IO ()
cleanup [SCC ModSummary]
sccs = do
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
getSessionDynFlags
(SuccessFlag
res, ModuleGraph
done) <- HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *).
GhcMonad m =>
HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
upsweep' HomePackageTable
old_hpt ModuleGraph
emptyMG [SCC ModSummary]
sccs Int
1 ([SCC ModSummary] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SCC ModSummary]
sccs)
(DynFlags -> [GenUnit UnitId]
instantiatedUnitsToCheck DynFlags
dflags) UniqSet ModuleName
forall a. UniqSet a
done_holes
(SuccessFlag, [ModSummary]) -> m (SuccessFlag, [ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
res, [ModSummary] -> [ModSummary]
forall a. [a] -> [a]
reverse ([ModSummary] -> [ModSummary]) -> [ModSummary] -> [ModSummary]
forall a b. (a -> b) -> a -> b
$ ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
done)
where
done_holes :: UniqSet a
done_holes = UniqSet a
forall a. UniqSet a
emptyUniqSet
keep_going :: [NodeKey]
-> HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
keep_going [NodeKey]
this_mods HomePackageTable
old_hpt ModuleGraph
done [SCC ModSummary]
mods Int
mod_index Int
nmods [GenUnit UnitId]
uids_to_check UniqSet ModuleName
done_holes = do
let sum_deps :: [NodeKey] -> SCC ModSummary -> [NodeKey]
sum_deps [NodeKey]
ms (AcyclicSCC ModSummary
mod) =
if (NodeKey -> Bool) -> [NodeKey] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((NodeKey -> [NodeKey] -> Bool) -> [NodeKey] -> NodeKey -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip NodeKey -> [NodeKey] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem ([NodeKey] -> NodeKey -> Bool) -> [NodeKey] -> NodeKey -> Bool
forall a b. (a -> b) -> a -> b
$ Bool -> ModSummary -> [NodeKey]
unfilteredEdges Bool
False ModSummary
mod) [NodeKey]
ms
then ModSummary -> NodeKey
mkHomeBuildModule ModSummary
modNodeKey -> [NodeKey] -> [NodeKey]
forall a. a -> [a] -> [a]
:[NodeKey]
ms
else [NodeKey]
ms
sum_deps [NodeKey]
ms SCC ModSummary
_ = [NodeKey]
ms
dep_closure :: [NodeKey]
dep_closure = ([NodeKey] -> SCC ModSummary -> [NodeKey])
-> [NodeKey] -> [SCC ModSummary] -> [NodeKey]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [NodeKey] -> SCC ModSummary -> [NodeKey]
sum_deps [NodeKey]
this_mods [SCC ModSummary]
mods
dropped_ms :: [NodeKey]
dropped_ms = Int -> [NodeKey] -> [NodeKey]
forall a. Int -> [a] -> [a]
drop ([NodeKey] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NodeKey]
this_mods) ([NodeKey] -> [NodeKey]
forall a. [a] -> [a]
reverse [NodeKey]
dep_closure)
prunable :: SCC ModSummary -> Bool
prunable (AcyclicSCC ModSummary
mod) = NodeKey -> [NodeKey] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem (ModSummary -> NodeKey
mkHomeBuildModule ModSummary
mod) [NodeKey]
dep_closure
prunable SCC ModSummary
_ = Bool
False
mods' :: [SCC ModSummary]
mods' = (SCC ModSummary -> Bool) -> [SCC ModSummary] -> [SCC ModSummary]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (SCC ModSummary -> Bool) -> SCC ModSummary -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SCC ModSummary -> Bool
prunable) [SCC ModSummary]
mods
nmods' :: Int
nmods' = Int
nmods Int -> Int -> Int
forall a. Num a => a -> a -> a
- [NodeKey] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NodeKey]
dropped_ms
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [NodeKey] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [NodeKey]
dropped_ms) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
getSessionDynFlags
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> IO ()
fatalErrorMsg DynFlags
dflags ([ModuleName] -> SDoc
keepGoingPruneErr ([ModuleName] -> SDoc) -> [ModuleName] -> SDoc
forall a b. (a -> b) -> a -> b
$ NodeKey -> ModuleName
forall mod. GenWithIsBoot mod -> mod
gwib_mod (NodeKey -> ModuleName) -> [NodeKey] -> [ModuleName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [NodeKey]
dropped_ms)
(SuccessFlag
_, ModuleGraph
done') <- HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *).
GhcMonad m =>
HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
upsweep' HomePackageTable
old_hpt ModuleGraph
done [SCC ModSummary]
mods' (Int
mod_indexInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
nmods' [GenUnit UnitId]
uids_to_check UniqSet ModuleName
done_holes
(SuccessFlag, ModuleGraph) -> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
Failed, ModuleGraph
done')
upsweep'
:: GhcMonad m
=> HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [Unit]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
upsweep' :: forall (m :: * -> *).
GhcMonad m =>
HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
upsweep' HomePackageTable
_old_hpt ModuleGraph
done
[] Int
_ Int
_ [GenUnit UnitId]
uids_to_check UniqSet ModuleName
_
= do HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Hsc () -> IO ()) -> Hsc () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HscEnv -> Hsc () -> IO ()
forall a. HscEnv -> Hsc a -> IO a
runHsc HscEnv
hsc_env (Hsc () -> m ()) -> Hsc () -> m ()
forall a b. (a -> b) -> a -> b
$ (GenUnit UnitId -> Hsc ()) -> [GenUnit UnitId] -> Hsc ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (IO (Messages, Maybe ()) -> Hsc ()
forall a. IO (Messages, Maybe a) -> Hsc a
ioMsgMaybe (IO (Messages, Maybe ()) -> Hsc ())
-> (GenUnit UnitId -> IO (Messages, Maybe ()))
-> GenUnit UnitId
-> Hsc ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HscEnv -> GenUnit UnitId -> IO (Messages, Maybe ())
tcRnCheckUnit HscEnv
hsc_env) [GenUnit UnitId]
uids_to_check
(SuccessFlag, ModuleGraph) -> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
Succeeded, ModuleGraph
done)
upsweep' HomePackageTable
_old_hpt ModuleGraph
done
(CyclicSCC [ModSummary]
ms:[SCC ModSummary]
mods) Int
mod_index Int
nmods [GenUnit UnitId]
uids_to_check UniqSet ModuleName
done_holes
= do DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
getSessionDynFlags
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> IO ()
fatalErrorMsg DynFlags
dflags ([ModSummary] -> SDoc
cyclicModuleErr [ModSummary]
ms)
if GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_KeepGoing DynFlags
dflags
then [NodeKey]
-> HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
forall {m :: * -> *}.
GhcMonad m =>
[NodeKey]
-> HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
keep_going (ModSummary -> NodeKey
mkHomeBuildModule (ModSummary -> NodeKey) -> [ModSummary] -> [NodeKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModSummary]
ms) HomePackageTable
old_hpt ModuleGraph
done [SCC ModSummary]
mods Int
mod_index Int
nmods
[GenUnit UnitId]
uids_to_check UniqSet ModuleName
done_holes
else (SuccessFlag, ModuleGraph) -> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
Failed, ModuleGraph
done)
upsweep' HomePackageTable
old_hpt ModuleGraph
done
(AcyclicSCC ModSummary
mod:[SCC ModSummary]
mods) Int
mod_index Int
nmods [GenUnit UnitId]
uids_to_check UniqSet ModuleName
done_holes
= do
let logger :: p -> Maybe SourceError -> m ()
logger p
_mod = Maybe SourceError -> m ()
WarnErrLogger
defaultWarnErrLogger
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
let ([GenUnit UnitId]
ready_uids, [GenUnit UnitId]
uids_to_check')
= (GenUnit UnitId -> Bool)
-> [GenUnit UnitId] -> ([GenUnit UnitId], [GenUnit UnitId])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\GenUnit UnitId
uid -> UniqDSet ModuleName -> Bool
forall a. UniqDSet a -> Bool
isEmptyUniqDSet
(GenUnit UnitId -> UniqDSet ModuleName
forall u. GenUnit u -> UniqDSet ModuleName
unitFreeModuleHoles GenUnit UnitId
uid UniqDSet ModuleName -> UniqSet ModuleName -> UniqDSet ModuleName
forall a. UniqDSet a -> UniqSet a -> UniqDSet a
`uniqDSetMinusUniqSet` UniqSet ModuleName
done_holes))
[GenUnit UnitId]
uids_to_check
done_holes' :: UniqSet ModuleName
done_holes'
| ModSummary -> HscSource
ms_hsc_src ModSummary
mod HscSource -> HscSource -> Bool
forall a. Eq a => a -> a -> Bool
== HscSource
HsigFile
= UniqSet ModuleName -> ModuleName -> UniqSet ModuleName
forall a. Uniquable a => UniqSet a -> a -> UniqSet a
addOneToUniqSet UniqSet ModuleName
done_holes (ModSummary -> ModuleName
ms_mod_name ModSummary
mod)
| Bool
otherwise = UniqSet ModuleName
done_holes
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Hsc () -> IO ()) -> Hsc () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HscEnv -> Hsc () -> IO ()
forall a. HscEnv -> Hsc a -> IO a
runHsc HscEnv
hsc_env (Hsc () -> m ()) -> Hsc () -> m ()
forall a b. (a -> b) -> a -> b
$ (GenUnit UnitId -> Hsc ()) -> [GenUnit UnitId] -> Hsc ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (IO (Messages, Maybe ()) -> Hsc ()
forall a. IO (Messages, Maybe a) -> Hsc a
ioMsgMaybe (IO (Messages, Maybe ()) -> Hsc ())
-> (GenUnit UnitId -> IO (Messages, Maybe ()))
-> GenUnit UnitId
-> Hsc ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HscEnv -> GenUnit UnitId -> IO (Messages, Maybe ())
tcRnCheckUnit HscEnv
hsc_env) [GenUnit UnitId]
ready_uids
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (HscEnv -> IO ()
cleanup HscEnv
hsc_env)
IORef (NameEnv TyThing)
type_env_var <- IO (IORef (NameEnv TyThing)) -> m (IORef (NameEnv TyThing))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (NameEnv TyThing)) -> m (IORef (NameEnv TyThing)))
-> IO (IORef (NameEnv TyThing)) -> m (IORef (NameEnv TyThing))
forall a b. (a -> b) -> a -> b
$ NameEnv TyThing -> IO (IORef (NameEnv TyThing))
forall a. a -> IO (IORef a)
newIORef NameEnv TyThing
forall a. NameEnv a
emptyNameEnv
let hsc_env1 :: HscEnv
hsc_env1 = HscEnv
hsc_env { hsc_type_env_var :: Maybe (Module, IORef (NameEnv TyThing))
hsc_type_env_var =
(Module, IORef (NameEnv TyThing))
-> Maybe (Module, IORef (NameEnv TyThing))
forall a. a -> Maybe a
Just (ModSummary -> Module
ms_mod ModSummary
mod, IORef (NameEnv TyThing)
type_env_var) }
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env1
HscEnv
hsc_env2 <- IO HscEnv -> m HscEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO HscEnv -> m HscEnv) -> IO HscEnv -> m HscEnv
forall a b. (a -> b) -> a -> b
$ HscEnv -> ModSummary -> ModuleGraph -> IO HscEnv
reTypecheckLoop HscEnv
hsc_env1 ModSummary
mod ModuleGraph
done
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env2
Maybe HomeModInfo
mb_mod_info
<- (SourceError -> m (Maybe HomeModInfo))
-> m (Maybe HomeModInfo) -> m (Maybe HomeModInfo)
forall (m :: * -> *) a.
MonadCatch m =>
(SourceError -> m a) -> m a -> m a
handleSourceError
(\SourceError
err -> do ModSummary -> Maybe SourceError -> m ()
forall {m :: * -> *} {p}.
GhcMonad m =>
p -> Maybe SourceError -> m ()
logger ModSummary
mod (SourceError -> Maybe SourceError
forall a. a -> Maybe a
Just SourceError
err); Maybe HomeModInfo -> m (Maybe HomeModInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe HomeModInfo
forall a. Maybe a
Nothing) (m (Maybe HomeModInfo) -> m (Maybe HomeModInfo))
-> m (Maybe HomeModInfo) -> m (Maybe HomeModInfo)
forall a b. (a -> b) -> a -> b
$ do
HomeModInfo
mod_info <- IO HomeModInfo -> m HomeModInfo
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO HomeModInfo -> m HomeModInfo)
-> IO HomeModInfo -> m HomeModInfo
forall a b. (a -> b) -> a -> b
$ HscEnv
-> Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> ModSummary
-> Int
-> Int
-> IO HomeModInfo
upsweep_mod HscEnv
hsc_env2 Maybe Messager
mHscMessage HomePackageTable
old_hpt (UniqSet ModuleName, UniqSet ModuleName)
stable_mods
ModSummary
mod Int
mod_index Int
nmods
ModSummary -> Maybe SourceError -> m ()
forall {m :: * -> *} {p}.
GhcMonad m =>
p -> Maybe SourceError -> m ()
logger ModSummary
mod Maybe SourceError
forall a. Maybe a
Nothing
Maybe HomeModInfo -> m (Maybe HomeModInfo)
forall (m :: * -> *) a. Monad m => a -> m a
return (HomeModInfo -> Maybe HomeModInfo
forall a. a -> Maybe a
Just HomeModInfo
mod_info)
case Maybe HomeModInfo
mb_mod_info of
Maybe HomeModInfo
Nothing -> do
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
getSessionDynFlags
if GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_KeepGoing DynFlags
dflags
then [NodeKey]
-> HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
forall {m :: * -> *}.
GhcMonad m =>
[NodeKey]
-> HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
keep_going [ModSummary -> NodeKey
mkHomeBuildModule ModSummary
mod] HomePackageTable
old_hpt ModuleGraph
done [SCC ModSummary]
mods Int
mod_index Int
nmods
[GenUnit UnitId]
uids_to_check UniqSet ModuleName
done_holes
else (SuccessFlag, ModuleGraph) -> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *) a. Monad m => a -> m a
return (SuccessFlag
Failed, ModuleGraph
done)
Just HomeModInfo
mod_info -> do
let this_mod :: ModuleName
this_mod = ModSummary -> ModuleName
ms_mod_name ModSummary
mod
hpt1 :: HomePackageTable
hpt1 = HomePackageTable -> ModuleName -> HomeModInfo -> HomePackageTable
addToHpt (HscEnv -> HomePackageTable
hsc_HPT HscEnv
hsc_env2) ModuleName
this_mod HomeModInfo
mod_info
hsc_env3 :: HscEnv
hsc_env3 = HscEnv
hsc_env2 { hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable
hpt1, hsc_type_env_var :: Maybe (Module, IORef (NameEnv TyThing))
hsc_type_env_var = Maybe (Module, IORef (NameEnv TyThing))
forall a. Maybe a
Nothing }
old_hpt1 :: HomePackageTable
old_hpt1 = case ModSummary -> IsBootInterface
isBootSummary ModSummary
mod of
IsBootInterface
IsBoot -> HomePackageTable
old_hpt
IsBootInterface
NotBoot -> HomePackageTable -> ModuleName -> HomePackageTable
delFromHpt HomePackageTable
old_hpt ModuleName
this_mod
done' :: ModuleGraph
done' = ModuleGraph -> ModSummary -> ModuleGraph
extendMG ModuleGraph
done ModSummary
mod
HscEnv
hsc_env4 <- IO HscEnv -> m HscEnv
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO HscEnv -> m HscEnv) -> IO HscEnv -> m HscEnv
forall a b. (a -> b) -> a -> b
$ HscEnv -> ModSummary -> ModuleGraph -> IO HscEnv
reTypecheckLoop HscEnv
hsc_env3 ModSummary
mod ModuleGraph
done'
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env4
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (DynFlags -> HscTarget
hscTarget (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env4) HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
== HscTarget
HscInterpreted) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ HscEnv -> [SptEntry] -> IO ()
hscAddSptEntries HscEnv
hsc_env4
[ SptEntry
spt
| Just Linkable
linkable <- Maybe Linkable -> [Maybe Linkable]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Linkable -> [Maybe Linkable])
-> Maybe Linkable -> [Maybe Linkable]
forall a b. (a -> b) -> a -> b
$ HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
mod_info
, Unlinked
unlinked <- Linkable -> [Unlinked]
linkableUnlinked Linkable
linkable
, BCOs CompiledByteCode
_ [SptEntry]
spts <- Unlinked -> [Unlinked]
forall (f :: * -> *) a. Applicative f => a -> f a
pure Unlinked
unlinked
, SptEntry
spt <- [SptEntry]
spts
]
HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
forall (m :: * -> *).
GhcMonad m =>
HomePackageTable
-> ModuleGraph
-> [SCC ModSummary]
-> Int
-> Int
-> [GenUnit UnitId]
-> UniqSet ModuleName
-> m (SuccessFlag, ModuleGraph)
upsweep' HomePackageTable
old_hpt1 ModuleGraph
done' [SCC ModSummary]
mods (Int
mod_indexInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
nmods [GenUnit UnitId]
uids_to_check' UniqSet ModuleName
done_holes'
instantiatedUnitsToCheck :: DynFlags -> [Unit]
instantiatedUnitsToCheck :: DynFlags -> [GenUnit UnitId]
instantiatedUnitsToCheck DynFlags
dflags =
[GenUnit UnitId] -> [GenUnit UnitId]
forall a. Ord a => [a] -> [a]
nubSort ([GenUnit UnitId] -> [GenUnit UnitId])
-> [GenUnit UnitId] -> [GenUnit UnitId]
forall a b. (a -> b) -> a -> b
$ (GenUnit UnitId -> [GenUnit UnitId])
-> [GenUnit UnitId] -> [GenUnit UnitId]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap GenUnit UnitId -> [GenUnit UnitId]
forall {unit}. GenUnit unit -> [GenUnit unit]
goUnit (UnitState -> [GenUnit UnitId]
explicitUnits (DynFlags -> UnitState
unitState DynFlags
dflags))
where
goUnit :: GenUnit unit -> [GenUnit unit]
goUnit GenUnit unit
HoleUnit = []
goUnit (RealUnit Definite unit
_) = []
goUnit uid :: GenUnit unit
uid@(VirtUnit GenInstantiatedUnit unit
i) = GenUnit unit
uid GenUnit unit -> [GenUnit unit] -> [GenUnit unit]
forall a. a -> [a] -> [a]
: ((ModuleName, GenModule (GenUnit unit)) -> [GenUnit unit])
-> [(ModuleName, GenModule (GenUnit unit))] -> [GenUnit unit]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (GenUnit unit -> [GenUnit unit]
goUnit (GenUnit unit -> [GenUnit unit])
-> ((ModuleName, GenModule (GenUnit unit)) -> GenUnit unit)
-> (ModuleName, GenModule (GenUnit unit))
-> [GenUnit unit]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenModule (GenUnit unit) -> GenUnit unit
forall unit. GenModule unit -> unit
moduleUnit (GenModule (GenUnit unit) -> GenUnit unit)
-> ((ModuleName, GenModule (GenUnit unit))
-> GenModule (GenUnit unit))
-> (ModuleName, GenModule (GenUnit unit))
-> GenUnit unit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModuleName, GenModule (GenUnit unit)) -> GenModule (GenUnit unit)
forall a b. (a, b) -> b
snd) (GenInstantiatedUnit unit
-> [(ModuleName, GenModule (GenUnit unit))]
forall unit. GenInstantiatedUnit unit -> GenInstantiations unit
instUnitInsts GenInstantiatedUnit unit
i)
maybeGetIfaceDate :: DynFlags -> ModLocation -> IO (Maybe UTCTime)
maybeGetIfaceDate :: DynFlags -> ModLocation -> IO (Maybe UTCTime)
maybeGetIfaceDate DynFlags
dflags ModLocation
location
| DynFlags -> Bool
writeInterfaceOnlyMode DynFlags
dflags
= FilePath -> IO (Maybe UTCTime)
modificationTimeIfExists (ModLocation -> FilePath
ml_hi_file ModLocation
location)
| Bool
otherwise
= Maybe UTCTime -> IO (Maybe UTCTime)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe UTCTime
forall a. Maybe a
Nothing
upsweep_mod :: HscEnv
-> Maybe Messager
-> HomePackageTable
-> StableModules
-> ModSummary
-> Int
-> Int
-> IO HomeModInfo
upsweep_mod :: HscEnv
-> Maybe Messager
-> HomePackageTable
-> (UniqSet ModuleName, UniqSet ModuleName)
-> ModSummary
-> Int
-> Int
-> IO HomeModInfo
upsweep_mod HscEnv
hsc_env Maybe Messager
mHscMessage HomePackageTable
old_hpt (UniqSet ModuleName
stable_obj, UniqSet ModuleName
stable_bco) ModSummary
summary Int
mod_index Int
nmods
= let
this_mod_name :: ModuleName
this_mod_name = ModSummary -> ModuleName
ms_mod_name ModSummary
summary
this_mod :: Module
this_mod = ModSummary -> Module
ms_mod ModSummary
summary
mb_obj_date :: Maybe UTCTime
mb_obj_date = ModSummary -> Maybe UTCTime
ms_obj_date ModSummary
summary
mb_if_date :: Maybe UTCTime
mb_if_date = ModSummary -> Maybe UTCTime
ms_iface_date ModSummary
summary
obj_fn :: FilePath
obj_fn = ModLocation -> FilePath
ml_obj_file (ModSummary -> ModLocation
ms_location ModSummary
summary)
hs_date :: UTCTime
hs_date = ModSummary -> UTCTime
ms_hs_date ModSummary
summary
is_stable_obj :: Bool
is_stable_obj = ModuleName
this_mod_name ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_obj
is_stable_bco :: Bool
is_stable_bco = ModuleName
this_mod_name ModuleName -> UniqSet ModuleName -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet ModuleName
stable_bco
old_hmi :: Maybe HomeModInfo
old_hmi = HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
old_hpt ModuleName
this_mod_name
dflags :: DynFlags
dflags = ModSummary -> DynFlags
ms_hspp_opts ModSummary
summary
prevailing_target :: HscTarget
prevailing_target = DynFlags -> HscTarget
hscTarget (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env)
local_target :: HscTarget
local_target = DynFlags -> HscTarget
hscTarget DynFlags
dflags
target :: HscTarget
target = if HscTarget
prevailing_target HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
/= HscTarget
local_target
Bool -> Bool -> Bool
&& (Bool -> Bool
not (HscTarget -> Bool
isObjectTarget HscTarget
prevailing_target)
Bool -> Bool -> Bool
|| Bool -> Bool
not (HscTarget -> Bool
isObjectTarget HscTarget
local_target))
Bool -> Bool -> Bool
&& Bool -> Bool
not (HscTarget
prevailing_target HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
== HscTarget
HscNothing)
Bool -> Bool -> Bool
&& Bool -> Bool
not (HscTarget
prevailing_target HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
== HscTarget
HscInterpreted)
then HscTarget
prevailing_target
else HscTarget
local_target
summary' :: ModSummary
summary' = ModSummary
summary{ ms_hspp_opts :: DynFlags
ms_hspp_opts = DynFlags
dflags { hscTarget :: HscTarget
hscTarget = HscTarget
target } }
mb_old_iface :: Maybe (ModIface_ 'ModIfaceFinal)
mb_old_iface
= case Maybe HomeModInfo
old_hmi of
Maybe HomeModInfo
Nothing -> Maybe (ModIface_ 'ModIfaceFinal)
forall a. Maybe a
Nothing
Just HomeModInfo
hm_info | ModSummary -> IsBootInterface
isBootSummary ModSummary
summary IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
IsBoot -> ModIface_ 'ModIfaceFinal -> Maybe (ModIface_ 'ModIfaceFinal)
forall a. a -> Maybe a
Just ModIface_ 'ModIfaceFinal
iface
| ModIface_ 'ModIfaceFinal -> IsBootInterface
mi_boot ModIface_ 'ModIfaceFinal
iface IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
NotBoot -> ModIface_ 'ModIfaceFinal -> Maybe (ModIface_ 'ModIfaceFinal)
forall a. a -> Maybe a
Just ModIface_ 'ModIfaceFinal
iface
| Bool
otherwise -> Maybe (ModIface_ 'ModIfaceFinal)
forall a. Maybe a
Nothing
where
iface :: ModIface_ 'ModIfaceFinal
iface = HomeModInfo -> ModIface_ 'ModIfaceFinal
hm_iface HomeModInfo
hm_info
compile_it :: Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it :: Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it Maybe Linkable
mb_linkable SourceModified
src_modified =
Maybe TcGblEnv
-> Maybe Messager
-> HscEnv
-> ModSummary
-> Int
-> Int
-> Maybe (ModIface_ 'ModIfaceFinal)
-> Maybe Linkable
-> SourceModified
-> IO HomeModInfo
compileOne' Maybe TcGblEnv
forall a. Maybe a
Nothing Maybe Messager
mHscMessage HscEnv
hsc_env ModSummary
summary' Int
mod_index Int
nmods
Maybe (ModIface_ 'ModIfaceFinal)
mb_old_iface Maybe Linkable
mb_linkable SourceModified
src_modified
compile_it_discard_iface :: Maybe Linkable -> SourceModified
-> IO HomeModInfo
compile_it_discard_iface :: Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it_discard_iface Maybe Linkable
mb_linkable SourceModified
src_modified =
Maybe TcGblEnv
-> Maybe Messager
-> HscEnv
-> ModSummary
-> Int
-> Int
-> Maybe (ModIface_ 'ModIfaceFinal)
-> Maybe Linkable
-> SourceModified
-> IO HomeModInfo
compileOne' Maybe TcGblEnv
forall a. Maybe a
Nothing Maybe Messager
mHscMessage HscEnv
hsc_env ModSummary
summary' Int
mod_index Int
nmods
Maybe (ModIface_ 'ModIfaceFinal)
forall a. Maybe a
Nothing Maybe Linkable
mb_linkable SourceModified
src_modified
is_fake_linkable :: Bool
is_fake_linkable
| Just HomeModInfo
hmi <- Maybe HomeModInfo
old_hmi, Just Linkable
l <- HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi =
[Unlinked] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Linkable -> [Unlinked]
linkableUnlinked Linkable
l)
| Bool
otherwise =
Bool
False
implies :: Bool -> Bool -> Bool
implies Bool
False Bool
_ = Bool
True
implies Bool
True Bool
x = Bool
x
in
case () of
()
_
| Bool
is_stable_obj, Just HomeModInfo
hmi <- Maybe HomeModInfo
old_hmi -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"skipping stable obj mod:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
HomeModInfo -> IO HomeModInfo
forall (m :: * -> *) a. Monad m => a -> m a
return HomeModInfo
hmi
| Bool
is_stable_obj, Maybe HomeModInfo -> Bool
forall a. Maybe a -> Bool
isNothing Maybe HomeModInfo
old_hmi -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"compiling stable on-disk mod:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
Linkable
linkable <- IO Linkable -> IO Linkable
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Linkable -> IO Linkable) -> IO Linkable -> IO Linkable
forall a b. (a -> b) -> a -> b
$ Module -> FilePath -> UTCTime -> IO Linkable
findObjectLinkable Module
this_mod FilePath
obj_fn
(FilePath -> Maybe UTCTime -> UTCTime
forall a. HasCallStack => FilePath -> Maybe a -> a
expectJust FilePath
"upsweep1" Maybe UTCTime
mb_obj_date)
Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it (Linkable -> Maybe Linkable
forall a. a -> Maybe a
Just Linkable
linkable) SourceModified
SourceUnmodifiedAndStable
| Bool -> Bool
not (HscTarget -> Bool
isObjectTarget HscTarget
target), Bool
is_stable_bco,
(HscTarget
target HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
/= HscTarget
HscNothing) Bool -> Bool -> Bool
`implies` Bool -> Bool
not Bool
is_fake_linkable ->
ASSERT(isJust old_hmi)
let Just HomeModInfo
hmi = Maybe HomeModInfo
old_hmi in do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"skipping stable BCO mod:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
HomeModInfo -> IO HomeModInfo
forall (m :: * -> *) a. Monad m => a -> m a
return HomeModInfo
hmi
| Bool -> Bool
not (HscTarget -> Bool
isObjectTarget HscTarget
target),
Just HomeModInfo
hmi <- Maybe HomeModInfo
old_hmi,
Just Linkable
l <- HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi,
Bool -> Bool
not (Linkable -> Bool
isObjectLinkable Linkable
l),
(HscTarget
target HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
/= HscTarget
HscNothing) Bool -> Bool -> Bool
`implies` Bool -> Bool
not Bool
is_fake_linkable,
Linkable -> UTCTime
linkableTime Linkable
l UTCTime -> UTCTime -> Bool
forall a. Ord a => a -> a -> Bool
>= ModSummary -> UTCTime
ms_hs_date ModSummary
summary -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"compiling non-stable BCO mod:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it (Linkable -> Maybe Linkable
forall a. a -> Maybe a
Just Linkable
l) SourceModified
SourceUnmodified
| HscTarget -> Bool
isObjectTarget HscTarget
target,
Just UTCTime
obj_date <- Maybe UTCTime
mb_obj_date,
UTCTime
obj_date UTCTime -> UTCTime -> Bool
forall a. Ord a => a -> a -> Bool
>= UTCTime
hs_date -> do
case Maybe HomeModInfo
old_hmi of
Just HomeModInfo
hmi
| Just Linkable
l <- HomeModInfo -> Maybe Linkable
hm_linkable HomeModInfo
hmi,
Linkable -> Bool
isObjectLinkable Linkable
l Bool -> Bool -> Bool
&& Linkable -> UTCTime
linkableTime Linkable
l UTCTime -> UTCTime -> Bool
forall a. Eq a => a -> a -> Bool
== UTCTime
obj_date -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"compiling mod with new on-disk obj:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it (Linkable -> Maybe Linkable
forall a. a -> Maybe a
Just Linkable
l) SourceModified
SourceUnmodified
Maybe HomeModInfo
_otherwise -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"compiling mod with new on-disk obj2:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
Linkable
linkable <- IO Linkable -> IO Linkable
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Linkable -> IO Linkable) -> IO Linkable -> IO Linkable
forall a b. (a -> b) -> a -> b
$ Module -> FilePath -> UTCTime -> IO Linkable
findObjectLinkable Module
this_mod FilePath
obj_fn UTCTime
obj_date
Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it_discard_iface (Linkable -> Maybe Linkable
forall a. a -> Maybe a
Just Linkable
linkable) SourceModified
SourceUnmodified
| DynFlags -> Bool
writeInterfaceOnlyMode DynFlags
dflags,
Just UTCTime
if_date <- Maybe UTCTime
mb_if_date,
UTCTime
if_date UTCTime -> UTCTime -> Bool
forall a. Ord a => a -> a -> Bool
>= UTCTime
hs_date -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"skipping tc'd mod:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it Maybe Linkable
forall a. Maybe a
Nothing SourceModified
SourceUnmodified
()
_otherwise -> do
IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) Int
5
(FilePath -> SDoc
text FilePath
"compiling mod:" SDoc -> SDoc -> SDoc
<+> ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
this_mod_name)
Maybe Linkable -> SourceModified -> IO HomeModInfo
compile_it Maybe Linkable
forall a. Maybe a
Nothing SourceModified
SourceModified
retainInTopLevelEnvs :: [ModuleName] -> HomePackageTable -> HomePackageTable
retainInTopLevelEnvs :: [ModuleName] -> HomePackageTable -> HomePackageTable
retainInTopLevelEnvs [ModuleName]
keep_these HomePackageTable
hpt
= [(ModuleName, HomeModInfo)] -> HomePackageTable
listToHpt [ (ModuleName
mod, FilePath -> Maybe HomeModInfo -> HomeModInfo
forall a. HasCallStack => FilePath -> Maybe a -> a
expectJust FilePath
"retain" Maybe HomeModInfo
mb_mod_info)
| ModuleName
mod <- [ModuleName]
keep_these
, let mb_mod_info :: Maybe HomeModInfo
mb_mod_info = HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
hpt ModuleName
mod
, Maybe HomeModInfo -> Bool
forall a. Maybe a -> Bool
isJust Maybe HomeModInfo
mb_mod_info ]
reTypecheckLoop :: HscEnv -> ModSummary -> ModuleGraph -> IO HscEnv
reTypecheckLoop :: HscEnv -> ModSummary -> ModuleGraph -> IO HscEnv
reTypecheckLoop HscEnv
hsc_env ModSummary
ms ModuleGraph
graph
| Just [ModSummary]
loop <- ModSummary
-> [ModSummary] -> (Module -> Bool) -> Maybe [ModSummary]
getModLoop ModSummary
ms [ModSummary]
mss Module -> Bool
appearsAsBoot
, let non_boot :: [ModSummary]
non_boot = (ModSummary -> Bool) -> [ModSummary] -> [ModSummary]
forall a. (a -> Bool) -> [a] -> [a]
filter (\ModSummary
l -> Bool -> Bool
not (ModSummary -> IsBootInterface
isBootSummary ModSummary
l IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
IsBoot Bool -> Bool -> Bool
&&
ModSummary -> Module
ms_mod ModSummary
l Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
== ModSummary -> Module
ms_mod ModSummary
ms)) [ModSummary]
loop
= DynFlags -> HscEnv -> [ModuleName] -> IO HscEnv
typecheckLoop (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env) HscEnv
hsc_env ((ModSummary -> ModuleName) -> [ModSummary] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> ModuleName
ms_mod_name [ModSummary]
non_boot)
| Bool
otherwise
= HscEnv -> IO HscEnv
forall (m :: * -> *) a. Monad m => a -> m a
return HscEnv
hsc_env
where
mss :: [ModSummary]
mss = ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
graph
appearsAsBoot :: Module -> Bool
appearsAsBoot = (Module -> ModuleSet -> Bool
`elemModuleSet` ModuleGraph -> ModuleSet
mgBootModules ModuleGraph
graph)
getModLoop
:: ModSummary
-> [ModSummary]
-> (Module -> Bool)
-> Maybe [ModSummary]
getModLoop :: ModSummary
-> [ModSummary] -> (Module -> Bool) -> Maybe [ModSummary]
getModLoop ModSummary
ms [ModSummary]
graph Module -> Bool
appearsAsBoot
| ModSummary -> IsBootInterface
isBootSummary ModSummary
ms IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
NotBoot
, Module -> Bool
appearsAsBoot Module
this_mod
, let mss :: [ModSummary]
mss = ModuleName -> [ModSummary] -> [ModSummary]
reachableBackwards (ModSummary -> ModuleName
ms_mod_name ModSummary
ms) [ModSummary]
graph
= [ModSummary] -> Maybe [ModSummary]
forall a. a -> Maybe a
Just [ModSummary]
mss
| Bool
otherwise
= Maybe [ModSummary]
forall a. Maybe a
Nothing
where
this_mod :: Module
this_mod = ModSummary -> Module
ms_mod ModSummary
ms
typecheckLoop :: DynFlags -> HscEnv -> [ModuleName] -> IO HscEnv
typecheckLoop :: DynFlags -> HscEnv -> [ModuleName] -> IO HscEnv
typecheckLoop DynFlags
dflags HscEnv
hsc_env [ModuleName]
mods = do
DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags Int
2 (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$
FilePath -> SDoc
text FilePath
"Re-typechecking loop: " SDoc -> SDoc -> SDoc
<> [ModuleName] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ModuleName]
mods
HomePackageTable
new_hpt <-
(HomePackageTable -> IO HomePackageTable) -> IO HomePackageTable
forall a. (a -> IO a) -> IO a
fixIO ((HomePackageTable -> IO HomePackageTable) -> IO HomePackageTable)
-> (HomePackageTable -> IO HomePackageTable) -> IO HomePackageTable
forall a b. (a -> b) -> a -> b
$ \HomePackageTable
new_hpt -> do
let new_hsc_env :: HscEnv
new_hsc_env = HscEnv
hsc_env{ hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable
new_hpt }
[ModDetails]
mds <- SDoc -> HscEnv -> IfG [ModDetails] -> IO [ModDetails]
forall a. SDoc -> HscEnv -> IfG a -> IO a
initIfaceCheck (FilePath -> SDoc
text FilePath
"typecheckLoop") HscEnv
new_hsc_env (IfG [ModDetails] -> IO [ModDetails])
-> IfG [ModDetails] -> IO [ModDetails]
forall a b. (a -> b) -> a -> b
$
(HomeModInfo -> IOEnv (Env IfGblEnv ()) ModDetails)
-> [HomeModInfo] -> IfG [ModDetails]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (ModIface_ 'ModIfaceFinal -> IOEnv (Env IfGblEnv ()) ModDetails
typecheckIface (ModIface_ 'ModIfaceFinal -> IOEnv (Env IfGblEnv ()) ModDetails)
-> (HomeModInfo -> ModIface_ 'ModIfaceFinal)
-> HomeModInfo
-> IOEnv (Env IfGblEnv ()) ModDetails
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HomeModInfo -> ModIface_ 'ModIfaceFinal
hm_iface) [HomeModInfo]
hmis
let new_hpt :: HomePackageTable
new_hpt = HomePackageTable -> [(ModuleName, HomeModInfo)] -> HomePackageTable
addListToHpt HomePackageTable
old_hpt
([ModuleName] -> [HomeModInfo] -> [(ModuleName, HomeModInfo)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ModuleName]
mods [ HomeModInfo
hmi{ hm_details :: ModDetails
hm_details = ModDetails
details }
| (HomeModInfo
hmi,ModDetails
details) <- [HomeModInfo] -> [ModDetails] -> [(HomeModInfo, ModDetails)]
forall a b. [a] -> [b] -> [(a, b)]
zip [HomeModInfo]
hmis [ModDetails]
mds ])
HomePackageTable -> IO HomePackageTable
forall (m :: * -> *) a. Monad m => a -> m a
return HomePackageTable
new_hpt
HscEnv -> IO HscEnv
forall (m :: * -> *) a. Monad m => a -> m a
return HscEnv
hsc_env{ hsc_HPT :: HomePackageTable
hsc_HPT = HomePackageTable
new_hpt }
where
old_hpt :: HomePackageTable
old_hpt = HscEnv -> HomePackageTable
hsc_HPT HscEnv
hsc_env
hmis :: [HomeModInfo]
hmis = (ModuleName -> HomeModInfo) -> [ModuleName] -> [HomeModInfo]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> Maybe HomeModInfo -> HomeModInfo
forall a. HasCallStack => FilePath -> Maybe a -> a
expectJust FilePath
"typecheckLoop" (Maybe HomeModInfo -> HomeModInfo)
-> (ModuleName -> Maybe HomeModInfo) -> ModuleName -> HomeModInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HomePackageTable -> ModuleName -> Maybe HomeModInfo
lookupHpt HomePackageTable
old_hpt) [ModuleName]
mods
reachableBackwards :: ModuleName -> [ModSummary] -> [ModSummary]
reachableBackwards :: ModuleName -> [ModSummary] -> [ModSummary]
reachableBackwards ModuleName
mod [ModSummary]
summaries
= [ Node Int ModSummary -> ModSummary
forall key payload. Node key payload -> payload
node_payload Node Int ModSummary
node | Node Int ModSummary
node <- Graph (Node Int ModSummary)
-> Node Int ModSummary -> [Node Int ModSummary]
forall node. Graph node -> node -> [node]
reachableG (Graph (Node Int ModSummary) -> Graph (Node Int ModSummary)
forall node. Graph node -> Graph node
transposeG Graph (Node Int ModSummary)
graph) Node Int ModSummary
root ]
where
(Graph (Node Int ModSummary)
graph, NodeKey -> Maybe (Node Int ModSummary)
lookup_node) = Bool
-> [ModSummary]
-> (Graph (Node Int ModSummary),
NodeKey -> Maybe (Node Int ModSummary))
moduleGraphNodes Bool
False [ModSummary]
summaries
root :: Node Int ModSummary
root = FilePath -> Maybe (Node Int ModSummary) -> Node Int ModSummary
forall a. HasCallStack => FilePath -> Maybe a -> a
expectJust FilePath
"reachableBackwards" (NodeKey -> Maybe (Node Int ModSummary)
lookup_node (NodeKey -> Maybe (Node Int ModSummary))
-> NodeKey -> Maybe (Node Int ModSummary)
forall a b. (a -> b) -> a -> b
$ ModuleName -> IsBootInterface -> NodeKey
forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB ModuleName
mod IsBootInterface
IsBoot)
topSortModuleGraph
:: Bool
-> ModuleGraph
-> Maybe ModuleName
-> [SCC ModSummary]
topSortModuleGraph :: Bool -> ModuleGraph -> Maybe ModuleName -> [SCC ModSummary]
topSortModuleGraph Bool
drop_hs_boot_nodes ModuleGraph
module_graph Maybe ModuleName
mb_root_mod
= (SCC (Node Int ModSummary) -> SCC ModSummary)
-> [SCC (Node Int ModSummary)] -> [SCC ModSummary]
forall a b. (a -> b) -> [a] -> [b]
map ((Node Int ModSummary -> ModSummary)
-> SCC (Node Int ModSummary) -> SCC ModSummary
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Node Int ModSummary -> ModSummary
summaryNodeSummary) ([SCC (Node Int ModSummary)] -> [SCC ModSummary])
-> [SCC (Node Int ModSummary)] -> [SCC ModSummary]
forall a b. (a -> b) -> a -> b
$ Graph (Node Int ModSummary) -> [SCC (Node Int ModSummary)]
forall node. Graph node -> [SCC node]
stronglyConnCompG Graph (Node Int ModSummary)
initial_graph
where
summaries :: [ModSummary]
summaries = ModuleGraph -> [ModSummary]
mgModSummaries ModuleGraph
module_graph
(Graph (Node Int ModSummary)
graph, NodeKey -> Maybe (Node Int ModSummary)
lookup_node) =
Bool
-> [ModSummary]
-> (Graph (Node Int ModSummary),
NodeKey -> Maybe (Node Int ModSummary))
moduleGraphNodes Bool
drop_hs_boot_nodes ([ModSummary] -> [ModSummary]
forall a. [a] -> [a]
reverse [ModSummary]
summaries)
initial_graph :: Graph (Node Int ModSummary)
initial_graph = case Maybe ModuleName
mb_root_mod of
Maybe ModuleName
Nothing -> Graph (Node Int ModSummary)
graph
Just ModuleName
root_mod ->
let root :: Node Int ModSummary
root | Just Node Int ModSummary
node <- NodeKey -> Maybe (Node Int ModSummary)
lookup_node (NodeKey -> Maybe (Node Int ModSummary))
-> NodeKey -> Maybe (Node Int ModSummary)
forall a b. (a -> b) -> a -> b
$ ModuleName -> IsBootInterface -> NodeKey
forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB ModuleName
root_mod IsBootInterface
NotBoot
, Graph (Node Int ModSummary)
graph Graph (Node Int ModSummary) -> Node Int ModSummary -> Bool
forall node. Graph node -> node -> Bool
`hasVertexG` Node Int ModSummary
node
= Node Int ModSummary
node
| Bool
otherwise
= GhcException -> Node Int ModSummary
forall a. GhcException -> a
throwGhcException (FilePath -> GhcException
ProgramError FilePath
"module does not exist")
in [Node Int ModSummary] -> Graph (Node Int ModSummary)
forall key payload.
Uniquable key =>
[Node key payload] -> Graph (Node key payload)
graphFromEdgedVerticesUniq (Node Int ModSummary
-> [Node Int ModSummary] -> [Node Int ModSummary]
seq Node Int ModSummary
root (Graph (Node Int ModSummary)
-> Node Int ModSummary -> [Node Int ModSummary]
forall node. Graph node -> node -> [node]
reachableG Graph (Node Int ModSummary)
graph Node Int ModSummary
root))
type SummaryNode = Node Int ModSummary
summaryNodeKey :: SummaryNode -> Int
summaryNodeKey :: Node Int ModSummary -> Int
summaryNodeKey = Node Int ModSummary -> Int
forall key payload. Node key payload -> key
node_key
summaryNodeSummary :: SummaryNode -> ModSummary
summaryNodeSummary :: Node Int ModSummary -> ModSummary
summaryNodeSummary = Node Int ModSummary -> ModSummary
forall key payload. Node key payload -> payload
node_payload
unfilteredEdges :: Bool -> ModSummary -> [ModuleNameWithIsBoot]
unfilteredEdges :: Bool -> ModSummary -> [NodeKey]
unfilteredEdges Bool
drop_hs_boot_nodes ModSummary
ms =
((ModuleName -> IsBootInterface -> NodeKey)
-> IsBootInterface -> ModuleName -> NodeKey
forall a b c. (a -> b -> c) -> b -> a -> c
flip ModuleName -> IsBootInterface -> NodeKey
forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB IsBootInterface
hs_boot_key (ModuleName -> NodeKey)
-> (GenLocated SrcSpan ModuleName -> ModuleName)
-> GenLocated SrcSpan ModuleName
-> NodeKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc (GenLocated SrcSpan ModuleName -> NodeKey)
-> [GenLocated SrcSpan ModuleName] -> [NodeKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ModSummary -> [GenLocated SrcSpan ModuleName]
ms_home_srcimps ModSummary
ms) [NodeKey] -> [NodeKey] -> [NodeKey]
forall a. [a] -> [a] -> [a]
++
((ModuleName -> IsBootInterface -> NodeKey)
-> IsBootInterface -> ModuleName -> NodeKey
forall a b c. (a -> b -> c) -> b -> a -> c
flip ModuleName -> IsBootInterface -> NodeKey
forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB IsBootInterface
NotBoot (ModuleName -> NodeKey)
-> (GenLocated SrcSpan ModuleName -> ModuleName)
-> GenLocated SrcSpan ModuleName
-> NodeKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc (GenLocated SrcSpan ModuleName -> NodeKey)
-> [GenLocated SrcSpan ModuleName] -> [NodeKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ModSummary -> [GenLocated SrcSpan ModuleName]
ms_home_imps ModSummary
ms) [NodeKey] -> [NodeKey] -> [NodeKey]
forall a. [a] -> [a] -> [a]
++
[ ModuleName -> IsBootInterface -> NodeKey
forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB (ModSummary -> ModuleName
ms_mod_name ModSummary
ms) IsBootInterface
IsBoot
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Bool
drop_hs_boot_nodes Bool -> Bool -> Bool
|| ModSummary -> HscSource
ms_hsc_src ModSummary
ms HscSource -> HscSource -> Bool
forall a. Eq a => a -> a -> Bool
== HscSource
HsBootFile
]
where
hs_boot_key :: IsBootInterface
hs_boot_key | Bool
drop_hs_boot_nodes = IsBootInterface
NotBoot
| Bool
otherwise = IsBootInterface
IsBoot
moduleGraphNodes :: Bool -> [ModSummary]
-> (Graph SummaryNode, ModuleNameWithIsBoot -> Maybe SummaryNode)
moduleGraphNodes :: Bool
-> [ModSummary]
-> (Graph (Node Int ModSummary),
NodeKey -> Maybe (Node Int ModSummary))
moduleGraphNodes Bool
drop_hs_boot_nodes [ModSummary]
summaries =
([Node Int ModSummary] -> Graph (Node Int ModSummary)
forall key payload.
Uniquable key =>
[Node key payload] -> Graph (Node key payload)
graphFromEdgedVerticesUniq [Node Int ModSummary]
nodes, NodeKey -> Maybe (Node Int ModSummary)
lookup_node)
where
numbered_summaries :: [(ModSummary, Int)]
numbered_summaries = [ModSummary] -> [Int] -> [(ModSummary, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ModSummary]
summaries [Int
1..]
lookup_node :: ModuleNameWithIsBoot -> Maybe SummaryNode
lookup_node :: NodeKey -> Maybe (Node Int ModSummary)
lookup_node NodeKey
mnwib = NodeKey
-> Map NodeKey (Node Int ModSummary) -> Maybe (Node Int ModSummary)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup NodeKey
mnwib Map NodeKey (Node Int ModSummary)
node_map
lookup_key :: ModuleNameWithIsBoot -> Maybe Int
lookup_key :: NodeKey -> Maybe Int
lookup_key = (Node Int ModSummary -> Int)
-> Maybe (Node Int ModSummary) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Node Int ModSummary -> Int
summaryNodeKey (Maybe (Node Int ModSummary) -> Maybe Int)
-> (NodeKey -> Maybe (Node Int ModSummary)) -> NodeKey -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NodeKey -> Maybe (Node Int ModSummary)
lookup_node
node_map :: NodeMap SummaryNode
node_map :: Map NodeKey (Node Int ModSummary)
node_map = [(NodeKey, Node Int ModSummary)]
-> Map NodeKey (Node Int ModSummary)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (ModSummary -> NodeKey
mkHomeBuildModule ModSummary
s, Node Int ModSummary
node)
| Node Int ModSummary
node <- [Node Int ModSummary]
nodes
, let s :: ModSummary
s = Node Int ModSummary -> ModSummary
summaryNodeSummary Node Int ModSummary
node
]
nodes :: [SummaryNode]
nodes :: [Node Int ModSummary]
nodes = [ ModSummary -> Int -> [Int] -> Node Int ModSummary
forall key payload. payload -> key -> [key] -> Node key payload
DigraphNode ModSummary
s Int
key ([Int] -> Node Int ModSummary) -> [Int] -> Node Int ModSummary
forall a b. (a -> b) -> a -> b
$ [NodeKey] -> [Int]
out_edge_keys ([NodeKey] -> [Int]) -> [NodeKey] -> [Int]
forall a b. (a -> b) -> a -> b
$ Bool -> ModSummary -> [NodeKey]
unfilteredEdges Bool
drop_hs_boot_nodes ModSummary
s
| (ModSummary
s, Int
key) <- [(ModSummary, Int)]
numbered_summaries
, Bool -> Bool
not (ModSummary -> IsBootInterface
isBootSummary ModSummary
s IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
IsBoot Bool -> Bool -> Bool
&& Bool
drop_hs_boot_nodes)
]
out_edge_keys :: [ModuleNameWithIsBoot] -> [Int]
out_edge_keys :: [NodeKey] -> [Int]
out_edge_keys = (NodeKey -> Maybe Int) -> [NodeKey] -> [Int]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe NodeKey -> Maybe Int
lookup_key
type NodeKey = ModuleNameWithIsBoot
type NodeMap a = Map.Map NodeKey a
msKey :: ModSummary -> NodeKey
msKey :: ModSummary -> NodeKey
msKey (ModSummary { ms_mod :: ModSummary -> Module
ms_mod = Module
mod, ms_hsc_src :: ModSummary -> HscSource
ms_hsc_src = HscSource
boot })
= GWIB :: forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB
{ gwib_mod :: ModuleName
gwib_mod = Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
mod
, gwib_isBoot :: IsBootInterface
gwib_isBoot = HscSource -> IsBootInterface
hscSourceToIsBoot HscSource
boot
}
mkNodeMap :: [ModSummary] -> NodeMap ModSummary
mkNodeMap :: [ModSummary] -> NodeMap ModSummary
mkNodeMap [ModSummary]
summaries = [(NodeKey, ModSummary)] -> NodeMap ModSummary
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [ (ModSummary -> NodeKey
msKey ModSummary
s, ModSummary
s) | ModSummary
s <- [ModSummary]
summaries]
nodeMapElts :: NodeMap a -> [a]
nodeMapElts :: forall a. NodeMap a -> [a]
nodeMapElts = Map NodeKey a -> [a]
forall k a. Map k a -> [a]
Map.elems
warnUnnecessarySourceImports :: GhcMonad m => [SCC ModSummary] -> m ()
warnUnnecessarySourceImports :: forall (m :: * -> *). GhcMonad m => [SCC ModSummary] -> m ()
warnUnnecessarySourceImports [SCC ModSummary]
sccs = do
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnUnusedImports DynFlags
dflags)
(ErrorMessages -> m ()
forall (m :: * -> *). GhcMonad m => ErrorMessages -> m ()
logWarnings ([ErrMsg] -> ErrorMessages
forall a. [a] -> Bag a
listToBag ((SCC ModSummary -> [ErrMsg]) -> [SCC ModSummary] -> [ErrMsg]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (DynFlags -> [ModSummary] -> [ErrMsg]
check DynFlags
dflags ([ModSummary] -> [ErrMsg])
-> (SCC ModSummary -> [ModSummary]) -> SCC ModSummary -> [ErrMsg]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SCC ModSummary -> [ModSummary]
forall vertex. SCC vertex -> [vertex]
flattenSCC) [SCC ModSummary]
sccs)))
where check :: DynFlags -> [ModSummary] -> [ErrMsg]
check DynFlags
dflags [ModSummary]
ms =
let mods_in_this_cycle :: [ModuleName]
mods_in_this_cycle = (ModSummary -> ModuleName) -> [ModSummary] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map ModSummary -> ModuleName
ms_mod_name [ModSummary]
ms in
[ DynFlags -> GenLocated SrcSpan ModuleName -> ErrMsg
warn DynFlags
dflags GenLocated SrcSpan ModuleName
i | ModSummary
m <- [ModSummary]
ms, GenLocated SrcSpan ModuleName
i <- ModSummary -> [GenLocated SrcSpan ModuleName]
ms_home_srcimps ModSummary
m,
GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc GenLocated SrcSpan ModuleName
i ModuleName -> [ModuleName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [ModuleName]
mods_in_this_cycle ]
warn :: DynFlags -> Located ModuleName -> WarnMsg
warn :: DynFlags -> GenLocated SrcSpan ModuleName -> ErrMsg
warn DynFlags
dflags (L SrcSpan
loc ModuleName
mod) =
DynFlags -> SrcSpan -> SDoc -> ErrMsg
mkPlainErrMsg DynFlags
dflags SrcSpan
loc
(FilePath -> SDoc
text FilePath
"Warning: {-# SOURCE #-} unnecessary in import of "
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
quotes (ModuleName -> SDoc
forall a. Outputable a => a -> SDoc
ppr ModuleName
mod))
downsweep :: HscEnv
-> [ModSummary]
-> [ModuleName]
-> Bool
-> IO [Either ErrorMessages ModSummary]
downsweep :: HscEnv
-> [ModSummary]
-> [ModuleName]
-> Bool
-> IO [Either ErrorMessages ModSummary]
downsweep HscEnv
hsc_env [ModSummary]
old_summaries [ModuleName]
excl_mods Bool
allow_dup_roots
= do
[Either ErrorMessages ModSummary]
rootSummaries <- (Target -> IO (Either ErrorMessages ModSummary))
-> [Target] -> IO [Either ErrorMessages ModSummary]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Target -> IO (Either ErrorMessages ModSummary)
getRootSummary [Target]
roots
let ([ErrorMessages]
errs, [ModSummary]
rootSummariesOk) = [Either ErrorMessages ModSummary]
-> ([ErrorMessages], [ModSummary])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either ErrorMessages ModSummary]
rootSummaries
root_map :: NodeMap [Either ErrorMessages ModSummary]
root_map = [ModSummary] -> NodeMap [Either ErrorMessages ModSummary]
mkRootMap [ModSummary]
rootSummariesOk
NodeMap [Either ErrorMessages ModSummary] -> IO ()
checkDuplicates NodeMap [Either ErrorMessages ModSummary]
root_map
NodeMap [Either ErrorMessages ModSummary]
map0 <- [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop ((ModSummary -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)])
-> [ModSummary] -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ModSummary -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
calcDeps [ModSummary]
rootSummariesOk) NodeMap [Either ErrorMessages ModSummary]
root_map
NodeMap [Either ErrorMessages ModSummary]
map1 <- if DynFlags -> HscTarget
hscTarget DynFlags
dflags HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
== HscTarget
HscNothing
then HscTarget
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
enableCodeGenForTH
(DynFlags -> HscTarget
defaultObjectTarget DynFlags
dflags)
NodeMap [Either ErrorMessages ModSummary]
map0
else if DynFlags -> HscTarget
hscTarget DynFlags
dflags HscTarget -> HscTarget -> Bool
forall a. Eq a => a -> a -> Bool
== HscTarget
HscInterpreted
then HscTarget
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
enableCodeGenForUnboxedTuplesOrSums
(DynFlags -> HscTarget
defaultObjectTarget DynFlags
dflags)
NodeMap [Either ErrorMessages ModSummary]
map0
else NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return NodeMap [Either ErrorMessages ModSummary]
map0
if [ErrorMessages] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ErrorMessages]
errs
then [Either ErrorMessages ModSummary]
-> IO [Either ErrorMessages ModSummary]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Either ErrorMessages ModSummary]
-> IO [Either ErrorMessages ModSummary])
-> [Either ErrorMessages ModSummary]
-> IO [Either ErrorMessages ModSummary]
forall a b. (a -> b) -> a -> b
$ [[Either ErrorMessages ModSummary]]
-> [Either ErrorMessages ModSummary]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Either ErrorMessages ModSummary]]
-> [Either ErrorMessages ModSummary])
-> [[Either ErrorMessages ModSummary]]
-> [Either ErrorMessages ModSummary]
forall a b. (a -> b) -> a -> b
$ NodeMap [Either ErrorMessages ModSummary]
-> [[Either ErrorMessages ModSummary]]
forall a. NodeMap a -> [a]
nodeMapElts NodeMap [Either ErrorMessages ModSummary]
map1
else [Either ErrorMessages ModSummary]
-> IO [Either ErrorMessages ModSummary]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Either ErrorMessages ModSummary]
-> IO [Either ErrorMessages ModSummary])
-> [Either ErrorMessages ModSummary]
-> IO [Either ErrorMessages ModSummary]
forall a b. (a -> b) -> a -> b
$ (ErrorMessages -> Either ErrorMessages ModSummary)
-> [ErrorMessages] -> [Either ErrorMessages ModSummary]
forall a b. (a -> b) -> [a] -> [b]
map ErrorMessages -> Either ErrorMessages ModSummary
forall a b. a -> Either a b
Left [ErrorMessages]
errs
where
calcDeps :: ModSummary -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
calcDeps = ModSummary -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
msDeps
dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
roots :: [Target]
roots = HscEnv -> [Target]
hsc_targets HscEnv
hsc_env
old_summary_map :: NodeMap ModSummary
old_summary_map :: NodeMap ModSummary
old_summary_map = [ModSummary] -> NodeMap ModSummary
mkNodeMap [ModSummary]
old_summaries
getRootSummary :: Target -> IO (Either ErrorMessages ModSummary)
getRootSummary :: Target -> IO (Either ErrorMessages ModSummary)
getRootSummary (Target (TargetFile FilePath
file Maybe Phase
mb_phase) Bool
obj_allowed Maybe (InputFileBuffer, UTCTime)
maybe_buf)
= do Bool
exists <- IO Bool -> IO Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> IO Bool) -> IO Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> IO Bool
doesFileExist FilePath
file
if Bool
exists Bool -> Bool -> Bool
|| Maybe (InputFileBuffer, UTCTime) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (InputFileBuffer, UTCTime)
maybe_buf
then HscEnv
-> [ModSummary]
-> FilePath
-> Maybe Phase
-> Bool
-> Maybe (InputFileBuffer, UTCTime)
-> IO (Either ErrorMessages ModSummary)
summariseFile HscEnv
hsc_env [ModSummary]
old_summaries FilePath
file Maybe Phase
mb_phase
Bool
obj_allowed Maybe (InputFileBuffer, UTCTime)
maybe_buf
else Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary))
-> Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary)
forall a b. (a -> b) -> a -> b
$ ErrorMessages -> Either ErrorMessages ModSummary
forall a b. a -> Either a b
Left (ErrorMessages -> Either ErrorMessages ModSummary)
-> ErrorMessages -> Either ErrorMessages ModSummary
forall a b. (a -> b) -> a -> b
$ ErrMsg -> ErrorMessages
forall a. a -> Bag a
unitBag (ErrMsg -> ErrorMessages) -> ErrMsg -> ErrorMessages
forall a b. (a -> b) -> a -> b
$ DynFlags -> SrcSpan -> SDoc -> ErrMsg
mkPlainErrMsg DynFlags
dflags SrcSpan
noSrcSpan (SDoc -> ErrMsg) -> SDoc -> ErrMsg
forall a b. (a -> b) -> a -> b
$
FilePath -> SDoc
text FilePath
"can't find file:" SDoc -> SDoc -> SDoc
<+> FilePath -> SDoc
text FilePath
file
getRootSummary (Target (TargetModule ModuleName
modl) Bool
obj_allowed Maybe (InputFileBuffer, UTCTime)
maybe_buf)
= do Maybe (Either ErrorMessages ModSummary)
maybe_summary <- HscEnv
-> NodeMap ModSummary
-> IsBootInterface
-> GenLocated SrcSpan ModuleName
-> Bool
-> Maybe (InputFileBuffer, UTCTime)
-> [ModuleName]
-> IO (Maybe (Either ErrorMessages ModSummary))
summariseModule HscEnv
hsc_env NodeMap ModSummary
old_summary_map IsBootInterface
NotBoot
(SrcSpan -> ModuleName -> GenLocated SrcSpan ModuleName
forall l e. l -> e -> GenLocated l e
L SrcSpan
rootLoc ModuleName
modl) Bool
obj_allowed
Maybe (InputFileBuffer, UTCTime)
maybe_buf [ModuleName]
excl_mods
case Maybe (Either ErrorMessages ModSummary)
maybe_summary of
Maybe (Either ErrorMessages ModSummary)
Nothing -> Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary))
-> Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary)
forall a b. (a -> b) -> a -> b
$ ErrorMessages -> Either ErrorMessages ModSummary
forall a b. a -> Either a b
Left (ErrorMessages -> Either ErrorMessages ModSummary)
-> ErrorMessages -> Either ErrorMessages ModSummary
forall a b. (a -> b) -> a -> b
$ DynFlags -> ModuleName -> ErrorMessages
moduleNotFoundErr DynFlags
dflags ModuleName
modl
Just Either ErrorMessages ModSummary
s -> Either ErrorMessages ModSummary
-> IO (Either ErrorMessages ModSummary)
forall (m :: * -> *) a. Monad m => a -> m a
return Either ErrorMessages ModSummary
s
rootLoc :: SrcSpan
rootLoc = FastString -> SrcSpan
mkGeneralSrcSpan (FilePath -> FastString
fsLit FilePath
"<command line>")
checkDuplicates :: NodeMap [Either ErrorMessages ModSummary] -> IO ()
checkDuplicates :: NodeMap [Either ErrorMessages ModSummary] -> IO ()
checkDuplicates NodeMap [Either ErrorMessages ModSummary]
root_map
| Bool
allow_dup_roots = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| [[ModSummary]] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[ModSummary]]
dup_roots = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> [ModSummary] -> IO ()
multiRootsErr DynFlags
dflags ([[ModSummary]] -> [ModSummary]
forall a. [a] -> a
head [[ModSummary]]
dup_roots)
where
dup_roots :: [[ModSummary]]
dup_roots :: [[ModSummary]]
dup_roots = ([ModSummary] -> Bool) -> [[ModSummary]] -> [[ModSummary]]
forall a. (a -> Bool) -> [a] -> [a]
filterOut [ModSummary] -> Bool
forall a. [a] -> Bool
isSingleton ([[ModSummary]] -> [[ModSummary]])
-> [[ModSummary]] -> [[ModSummary]]
forall a b. (a -> b) -> a -> b
$ ([Either ErrorMessages ModSummary] -> [ModSummary])
-> [[Either ErrorMessages ModSummary]] -> [[ModSummary]]
forall a b. (a -> b) -> [a] -> [b]
map [Either ErrorMessages ModSummary] -> [ModSummary]
forall a b. [Either a b] -> [b]
rights ([[Either ErrorMessages ModSummary]] -> [[ModSummary]])
-> [[Either ErrorMessages ModSummary]] -> [[ModSummary]]
forall a b. (a -> b) -> a -> b
$ NodeMap [Either ErrorMessages ModSummary]
-> [[Either ErrorMessages ModSummary]]
forall a. NodeMap a -> [a]
nodeMapElts NodeMap [Either ErrorMessages ModSummary]
root_map
loop :: [GenWithIsBoot (Located ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop :: [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop [] NodeMap [Either ErrorMessages ModSummary]
done = NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return NodeMap [Either ErrorMessages ModSummary]
done
loop (GenWithIsBoot (GenLocated SrcSpan ModuleName)
s : [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
ss) NodeMap [Either ErrorMessages ModSummary]
done
| Just [Either ErrorMessages ModSummary]
summs <- NodeKey
-> NodeMap [Either ErrorMessages ModSummary]
-> Maybe [Either ErrorMessages ModSummary]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup NodeKey
key NodeMap [Either ErrorMessages ModSummary]
done
= if [Either ErrorMessages ModSummary] -> Bool
forall a. [a] -> Bool
isSingleton [Either ErrorMessages ModSummary]
summs then
[GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
ss NodeMap [Either ErrorMessages ModSummary]
done
else
do { DynFlags -> [ModSummary] -> IO ()
multiRootsErr DynFlags
dflags ([Either ErrorMessages ModSummary] -> [ModSummary]
forall a b. [Either a b] -> [b]
rights [Either ErrorMessages ModSummary]
summs); NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
forall (m :: * -> *) a. Monad m => a -> m a
return NodeMap [Either ErrorMessages ModSummary]
forall k a. Map k a
Map.empty }
| Bool
otherwise
= do Maybe (Either ErrorMessages ModSummary)
mb_s <- HscEnv
-> NodeMap ModSummary
-> IsBootInterface
-> GenLocated SrcSpan ModuleName
-> Bool
-> Maybe (InputFileBuffer, UTCTime)
-> [ModuleName]
-> IO (Maybe (Either ErrorMessages ModSummary))
summariseModule HscEnv
hsc_env NodeMap ModSummary
old_summary_map
IsBootInterface
is_boot GenLocated SrcSpan ModuleName
wanted_mod Bool
True
Maybe (InputFileBuffer, UTCTime)
forall a. Maybe a
Nothing [ModuleName]
excl_mods
case Maybe (Either ErrorMessages ModSummary)
mb_s of
Maybe (Either ErrorMessages ModSummary)
Nothing -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
ss NodeMap [Either ErrorMessages ModSummary]
done
Just (Left ErrorMessages
e) -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
ss (NodeKey
-> [Either ErrorMessages ModSummary]
-> NodeMap [Either ErrorMessages ModSummary]
-> NodeMap [Either ErrorMessages ModSummary]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert NodeKey
key [ErrorMessages -> Either ErrorMessages ModSummary
forall a b. a -> Either a b
Left ErrorMessages
e] NodeMap [Either ErrorMessages ModSummary]
done)
Just (Right ModSummary
s)-> do
NodeMap [Either ErrorMessages ModSummary]
new_map <-
[GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop (ModSummary -> [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
calcDeps ModSummary
s) (NodeKey
-> [Either ErrorMessages ModSummary]
-> NodeMap [Either ErrorMessages ModSummary]
-> NodeMap [Either ErrorMessages ModSummary]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert NodeKey
key [ModSummary -> Either ErrorMessages ModSummary
forall a b. b -> Either a b
Right ModSummary
s] NodeMap [Either ErrorMessages ModSummary]
done)
[GenWithIsBoot (GenLocated SrcSpan ModuleName)]
-> NodeMap [Either ErrorMessages ModSummary]
-> IO (NodeMap [Either ErrorMessages ModSummary])
loop [GenWithIsBoot (GenLocated SrcSpan ModuleName)]
ss NodeMap [Either ErrorMessages ModSummary]
new_map
where
GWIB { gwib_mod :: forall mod. GenWithIsBoot mod -> mod
gwib_mod = L SrcSpan
loc ModuleName
mod, gwib_isBoot :: forall mod. GenWithIsBoot mod -> IsBootInterface
gwib_isBoot = IsBootInterface
is_boot } = GenWithIsBoot (GenLocated SrcSpan ModuleName)
s
wanted_mod :: GenLocated SrcSpan ModuleName
wanted_mod = SrcSpan -> ModuleName -> GenLocated SrcSpan ModuleName
forall l e. l -> e -> GenLocated l e
L SrcSpan
loc ModuleName
mod
key :: NodeKey
key = GWIB :: forall mod. mod -> IsBootInterface -> GenWithIsBoot mod
GWIB
{ gwib_mod :: ModuleName
gwib_mod = GenLocated SrcSpan ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc GenLocated SrcSpan ModuleName
wanted_mod
, gwib_isBoot :: IsBootInterfac