summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2016-10-06 00:17:15 -0700
committerEdward Z. Yang <ezyang@cs.stanford.edu>2016-10-08 01:37:33 -0700
commit4e8a0607140b23561248a41aeaf837224aa6315b (patch)
tree8e03945afe5c40c13b41667e0175f14db15d0780 /compiler/main
parent00b530d5402aaa37e4085ecdcae0ae54454736c1 (diff)
downloadhaskell-4e8a0607140b23561248a41aeaf837224aa6315b.tar.gz
Distinguish between UnitId and InstalledUnitId.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/CodeOutput.hs6
-rw-r--r--compiler/main/DriverPipeline.hs24
-rw-r--r--compiler/main/Finder.hs203
-rw-r--r--compiler/main/GHC.hs6
-rw-r--r--compiler/main/GhcMake.hs3
-rw-r--r--compiler/main/HscMain.hs22
-rw-r--r--compiler/main/HscTypes.hs27
-rw-r--r--compiler/main/PackageConfig.hs23
-rw-r--r--compiler/main/Packages.hs186
-rw-r--r--compiler/main/SysTools.hs4
10 files changed, 324 insertions, 180 deletions
diff --git a/compiler/main/CodeOutput.hs b/compiler/main/CodeOutput.hs
index f172cf1259..f4681dcd27 100644
--- a/compiler/main/CodeOutput.hs
+++ b/compiler/main/CodeOutput.hs
@@ -50,7 +50,7 @@ codeOutput :: DynFlags
-> FilePath
-> ModLocation
-> ForeignStubs
- -> [UnitId]
+ -> [InstalledUnitId]
-> Stream IO RawCmmGroup () -- Compiled C--
-> IO (FilePath,
(Bool{-stub_h_exists-}, Maybe FilePath{-stub_c_exists-}))
@@ -107,7 +107,7 @@ doOutput filenm io_action = bracket (openFile filenm WriteMode) hClose io_action
outputC :: DynFlags
-> FilePath
-> Stream IO RawCmmGroup ()
- -> [UnitId]
+ -> [InstalledUnitId]
-> IO ()
outputC dflags filenm cmm_stream packages
@@ -131,7 +131,7 @@ outputC dflags filenm cmm_stream packages
'<':_ -> "#include "++h_file
_ -> "#include \""++h_file++"\""
- let pkg_names = map unitIdString packages
+ let pkg_names = map installedUnitIdString packages
doOutput filenm $ \ h -> do
hPutStr h ("/* GHC_PACKAGES " ++ unwords pkg_names ++ "\n*/\n")
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 30493f123e..b1f1f6c2e6 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -402,7 +402,7 @@ link' dflags batch_attempt_linking hpt
return Succeeded
-linkingNeeded :: DynFlags -> Bool -> [Linkable] -> [UnitId] -> IO Bool
+linkingNeeded :: DynFlags -> Bool -> [Linkable] -> [InstalledUnitId] -> IO Bool
linkingNeeded dflags staticLink linkables pkg_deps = do
-- if the modification time on the executable is later than the
-- modification times on all of the objects and libraries, then omit
@@ -424,7 +424,7 @@ linkingNeeded dflags staticLink linkables pkg_deps = do
-- next, check libraries. XXX this only checks Haskell libraries,
-- not extra_libraries or -l things from the command line.
let pkg_hslibs = [ (libraryDirs c, lib)
- | Just c <- map (lookupPackage dflags) pkg_deps,
+ | Just c <- map (lookupInstalledPackage dflags) pkg_deps,
lib <- packageHsLibs dflags c ]
pkg_libfiles <- mapM (uncurry (findHSLib dflags)) pkg_hslibs
@@ -438,7 +438,7 @@ linkingNeeded dflags staticLink linkables pkg_deps = do
-- Returns 'False' if it was, and we can avoid linking, because the
-- previous binary was linked with "the same options".
-checkLinkInfo :: DynFlags -> [UnitId] -> FilePath -> IO Bool
+checkLinkInfo :: DynFlags -> [InstalledUnitId] -> FilePath -> IO Bool
checkLinkInfo dflags pkg_deps exe_file
| not (platformSupportsSavingLinkOpts (platformOS (targetPlatform dflags)))
-- ToDo: Windows and OS X do not use the ELF binary format, so
@@ -1652,7 +1652,7 @@ mkExtraObjToLinkIntoBinary dflags = do
-- this was included as inline assembly in the main.c file but this
-- is pretty fragile. gas gets upset trying to calculate relative offsets
-- that span the .note section (notably .text) when debug info is present
-mkNoteObjsToLinkIntoBinary :: DynFlags -> [UnitId] -> IO [FilePath]
+mkNoteObjsToLinkIntoBinary :: DynFlags -> [InstalledUnitId] -> IO [FilePath]
mkNoteObjsToLinkIntoBinary dflags dep_packages = do
link_info <- getLinkInfo dflags dep_packages
@@ -1677,7 +1677,7 @@ mkNoteObjsToLinkIntoBinary dflags dep_packages = do
-- | Return the "link info" string
--
-- See Note [LinkInfo section]
-getLinkInfo :: DynFlags -> [UnitId] -> IO String
+getLinkInfo :: DynFlags -> [InstalledUnitId] -> IO String
getLinkInfo dflags dep_packages = do
package_link_opts <- getPackageLinkOpts dflags dep_packages
pkg_frameworks <- if platformUsesFrameworks (targetPlatform dflags)
@@ -1714,13 +1714,13 @@ not follow the specified record-based format (see #11022).
-----------------------------------------------------------------------------
-- Look for the /* GHC_PACKAGES ... */ comment at the top of a .hc file
-getHCFilePackages :: FilePath -> IO [UnitId]
+getHCFilePackages :: FilePath -> IO [InstalledUnitId]
getHCFilePackages filename =
Exception.bracket (openFile filename ReadMode) hClose $ \h -> do
l <- hGetLine h
case l of
'/':'*':' ':'G':'H':'C':'_':'P':'A':'C':'K':'A':'G':'E':'S':rest ->
- return (map stringToUnitId (words rest))
+ return (map stringToInstalledUnitId (words rest))
_other ->
return []
@@ -1737,10 +1737,10 @@ getHCFilePackages filename =
-- read any interface files), so the user must explicitly specify all
-- the packages.
-linkBinary :: DynFlags -> [FilePath] -> [UnitId] -> IO ()
+linkBinary :: DynFlags -> [FilePath] -> [InstalledUnitId] -> IO ()
linkBinary = linkBinary' False
-linkBinary' :: Bool -> DynFlags -> [FilePath] -> [UnitId] -> IO ()
+linkBinary' :: Bool -> DynFlags -> [FilePath] -> [InstalledUnitId] -> IO ()
linkBinary' staticLink dflags o_files dep_packages = do
let platform = targetPlatform dflags
mySettings = settings dflags
@@ -1987,7 +1987,7 @@ maybeCreateManifest dflags exe_filename
| otherwise = return []
-linkDynLibCheck :: DynFlags -> [String] -> [UnitId] -> IO ()
+linkDynLibCheck :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
linkDynLibCheck dflags o_files dep_packages
= do
when (haveRtsOptsFlags dflags) $ do
@@ -1997,7 +1997,7 @@ linkDynLibCheck dflags o_files dep_packages
linkDynLib dflags o_files dep_packages
-linkStaticLibCheck :: DynFlags -> [String] -> [UnitId] -> IO ()
+linkStaticLibCheck :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
linkStaticLibCheck dflags o_files dep_packages
= do
when (platformOS (targetPlatform dflags) `notElem` [OSiOS, OSDarwin]) $
@@ -2229,7 +2229,7 @@ haveRtsOptsFlags dflags =
-- | Find out path to @ghcversion.h@ file
getGhcVersionPathName :: DynFlags -> IO FilePath
getGhcVersionPathName dflags = do
- dirs <- getPackageIncludePath dflags [rtsUnitId]
+ dirs <- getPackageIncludePath dflags [toInstalledUnitId rtsUnitId]
found <- filterM doesFileExist (map (</> "ghcversion.h") dirs)
case found of
diff --git a/compiler/main/Finder.hs b/compiler/main/Finder.hs
index e813e9e52c..2bcdd3360c 100644
--- a/compiler/main/Finder.hs
+++ b/compiler/main/Finder.hs
@@ -71,25 +71,25 @@ type BaseName = String -- Basename of file
-- assumed to not move around during a session.
flushFinderCaches :: HscEnv -> IO ()
flushFinderCaches hsc_env =
- atomicModifyIORef' fc_ref $ \fm -> (filterModuleEnv is_ext fm, ())
+ atomicModifyIORef' fc_ref $ \fm -> (filterInstalledModuleEnv is_ext fm, ())
where
this_pkg = thisPackage (hsc_dflags hsc_env)
fc_ref = hsc_FC hsc_env
- is_ext mod _ | moduleUnitId mod /= this_pkg = True
+ is_ext mod _ | not (installedModuleUnitId mod `installedUnitIdEq` this_pkg) = True
| otherwise = False
-addToFinderCache :: IORef FinderCache -> Module -> FindResult -> IO ()
+addToFinderCache :: IORef FinderCache -> InstalledModule -> InstalledFindResult -> IO ()
addToFinderCache ref key val =
- atomicModifyIORef' ref $ \c -> (extendModuleEnv c key val, ())
+ atomicModifyIORef' ref $ \c -> (extendInstalledModuleEnv c key val, ())
-removeFromFinderCache :: IORef FinderCache -> Module -> IO ()
+removeFromFinderCache :: IORef FinderCache -> InstalledModule -> IO ()
removeFromFinderCache ref key =
- atomicModifyIORef' ref $ \c -> (delModuleEnv c key, ())
+ atomicModifyIORef' ref $ \c -> (delInstalledModuleEnv c key, ())
-lookupFinderCache :: IORef FinderCache -> VirginModule -> IO (Maybe FindResult)
+lookupFinderCache :: IORef FinderCache -> InstalledModule -> IO (Maybe InstalledFindResult)
lookupFinderCache ref key = do
c <- readIORef ref
- return $! lookupModuleEnv c key
+ return $! lookupInstalledModuleEnv c key
-- -----------------------------------------------------------------------------
-- The three external entry points
@@ -131,11 +131,11 @@ findPluginModule hsc_env mod_name =
-- reading the interface for a module mentioned by another interface,
-- for example (a "system import").
-findExactModule :: HscEnv -> VirginModule -> IO FindResult
+findExactModule :: HscEnv -> InstalledModule -> IO InstalledFindResult
findExactModule hsc_env mod =
let dflags = hsc_dflags hsc_env
- in if moduleUnitId mod == thisPackage dflags
- then findHomeModule hsc_env (moduleName mod)
+ in if installedModuleUnitId mod `installedUnitIdEq` thisPackage dflags
+ then findInstalledHomeModule hsc_env (installedModuleName mod)
else findPackageModule hsc_env mod
-- -----------------------------------------------------------------------------
@@ -169,9 +169,9 @@ orIfNotFound this or_this = do
-- been done. Otherwise, do the lookup (with the IO action) and save
-- the result in the finder cache and the module location cache (if it
-- was successful.)
-homeSearchCache :: HscEnv -> ModuleName -> IO FindResult -> IO FindResult
+homeSearchCache :: HscEnv -> ModuleName -> IO InstalledFindResult -> IO InstalledFindResult
homeSearchCache hsc_env mod_name do_this = do
- let mod = mkModule (thisPackage (hsc_dflags hsc_env)) mod_name
+ let mod = mkHomeInstalledModule (hsc_dflags hsc_env) mod_name
modLocationCache hsc_env mod do_this
findExposedPackageModule :: HscEnv -> ModuleName -> Maybe FastString
@@ -190,8 +190,20 @@ findExposedPluginPackageModule hsc_env mod_name
findLookupResult :: HscEnv -> LookupResult -> IO FindResult
findLookupResult hsc_env r = case r of
- LookupFound m pkg_conf ->
- findPackageModule_ hsc_env m pkg_conf
+ LookupFound m pkg_conf -> do
+ let im = fst (splitModuleInsts m)
+ r' <- findPackageModule_ hsc_env im pkg_conf
+ case r' of
+ -- TODO: ghc -M is unlikely to do the right thing
+ -- with just the location of the thing that was
+ -- instantiated; you probably also need all of the
+ -- implicit locations from the instances
+ InstalledFound loc _ -> return (Found loc m)
+ InstalledNoPackage _ -> return (NoPackage (moduleUnitId m))
+ InstalledNotFound fp _ -> return (NotFound{ fr_paths = fp, fr_pkg = Just (moduleUnitId m)
+ , fr_pkgs_hidden = []
+ , fr_mods_hidden = []
+ , fr_suggestions = []})
LookupMultiple rs ->
return (FoundMultiple rs)
LookupHidden pkg_hiddens mod_hiddens ->
@@ -205,7 +217,7 @@ findLookupResult hsc_env r = case r of
, fr_mods_hidden = []
, fr_suggestions = suggest })
-modLocationCache :: HscEnv -> VirginModule -> IO FindResult -> IO FindResult
+modLocationCache :: HscEnv -> InstalledModule -> IO InstalledFindResult -> IO InstalledFindResult
modLocationCache hsc_env mod do_this = do
m <- lookupFinderCache (hsc_FC hsc_env) mod
case m of
@@ -215,20 +227,43 @@ modLocationCache hsc_env mod do_this = do
addToFinderCache (hsc_FC hsc_env) mod result
return result
+mkHomeInstalledModule :: DynFlags -> ModuleName -> InstalledModule
+mkHomeInstalledModule dflags mod_name =
+ let iuid = fst (splitUnitIdInsts (thisPackage dflags))
+ in InstalledModule iuid mod_name
+
+-- This returns a module because it's more convenient for users
addHomeModuleToFinder :: HscEnv -> ModuleName -> ModLocation -> IO Module
addHomeModuleToFinder hsc_env mod_name loc = do
- let mod = mkModule (thisPackage (hsc_dflags hsc_env)) mod_name
- addToFinderCache (hsc_FC hsc_env) mod (Found loc mod)
- return mod
+ let mod = mkHomeInstalledModule (hsc_dflags hsc_env) mod_name
+ addToFinderCache (hsc_FC hsc_env) mod (InstalledFound loc mod)
+ return (mkModule (thisPackage (hsc_dflags hsc_env)) mod_name)
uncacheModule :: HscEnv -> ModuleName -> IO ()
-uncacheModule hsc_env mod = do
- let this_pkg = thisPackage (hsc_dflags hsc_env)
- removeFromFinderCache (hsc_FC hsc_env) (mkModule this_pkg mod)
+uncacheModule hsc_env mod_name = do
+ let mod = mkHomeInstalledModule (hsc_dflags hsc_env) mod_name
+ removeFromFinderCache (hsc_FC hsc_env) mod
-- -----------------------------------------------------------------------------
-- The internal workers
+findHomeModule :: HscEnv -> ModuleName -> IO FindResult
+findHomeModule hsc_env mod_name = do
+ r <- findInstalledHomeModule hsc_env mod_name
+ return $ case r of
+ InstalledFound loc _ -> Found loc (mkModule uid mod_name)
+ InstalledNoPackage _ -> NoPackage uid -- impossible
+ InstalledNotFound fps _ -> NotFound {
+ fr_paths = fps,
+ fr_pkg = Just uid,
+ fr_mods_hidden = [],
+ fr_pkgs_hidden = [],
+ fr_suggestions = []
+ }
+ where
+ dflags = hsc_dflags hsc_env
+ uid = thisPackage dflags
+
-- | Implements the search for a module name in the home package only. Calling
-- this function directly is usually *not* what you want; currently, it's used
-- as a building block for the following operations:
@@ -245,14 +280,14 @@ uncacheModule hsc_env mod = do
--
-- 4. Some special-case code in GHCi (ToDo: Figure out why that needs to
-- call this.)
-findHomeModule :: HscEnv -> ModuleName -> IO FindResult
-findHomeModule hsc_env mod_name =
+findInstalledHomeModule :: HscEnv -> ModuleName -> IO InstalledFindResult
+findInstalledHomeModule hsc_env mod_name =
homeSearchCache hsc_env mod_name $
let
dflags = hsc_dflags hsc_env
home_path = importPaths dflags
hisuf = hiSuf dflags
- mod = mkModule (thisPackage dflags) mod_name
+ mod = mkHomeInstalledModule dflags mod_name
source_exts =
[ ("hs", mkHomeModLocationSearched dflags mod_name "hs")
@@ -275,20 +310,20 @@ findHomeModule hsc_env mod_name =
-- special case for GHC.Prim; we won't find it in the filesystem.
-- This is important only when compiling the base package (where GHC.Prim
-- is a home module).
- if mod == gHC_PRIM
- then return (Found (error "GHC.Prim ModLocation") mod)
+ if mod `installedModuleEq` gHC_PRIM
+ then return (InstalledFound (error "GHC.Prim ModLocation") mod)
else searchPathExts home_path mod exts
-- | Search for a module in external packages only.
-findPackageModule :: HscEnv -> VirginModule -> IO FindResult
+findPackageModule :: HscEnv -> InstalledModule -> IO InstalledFindResult
findPackageModule hsc_env mod = do
let
dflags = hsc_dflags hsc_env
- pkg_id = moduleUnitId mod
+ pkg_id = installedModuleUnitId mod
--
- case lookupPackage dflags pkg_id of
- Nothing -> return (NoPackage pkg_id)
+ case lookupInstalledPackage dflags pkg_id of
+ Nothing -> return (InstalledNoPackage pkg_id)
Just pkg_conf -> findPackageModule_ hsc_env mod pkg_conf
-- | Look up the interface file associated with module @mod@. This function
@@ -298,14 +333,14 @@ findPackageModule hsc_env mod = do
-- the 'PackageConfig' must be consistent with the unit id in the 'Module'.
-- The redundancy is to avoid an extra lookup in the package state
-- for the appropriate config.
-findPackageModule_ :: HscEnv -> VirginModule -> PackageConfig -> IO FindResult
+findPackageModule_ :: HscEnv -> InstalledModule -> PackageConfig -> IO InstalledFindResult
findPackageModule_ hsc_env mod pkg_conf =
- ASSERT( moduleUnitId mod == packageConfigId pkg_conf )
+ ASSERT( installedModuleUnitId mod == installedPackageConfigId pkg_conf )
modLocationCache hsc_env mod $
-- special case for GHC.Prim; we won't find it in the filesystem.
- if mod == gHC_PRIM
- then return (Found (error "GHC.Prim ModLocation") mod)
+ if mod `installedModuleEq` gHC_PRIM
+ then return (InstalledFound (error "GHC.Prim ModLocation") mod)
else
let
@@ -326,9 +361,9 @@ findPackageModule_ hsc_env mod pkg_conf =
[one] | MkDepend <- ghcMode dflags -> do
-- there's only one place that this .hi file can be, so
-- don't bother looking for it.
- let basename = moduleNameSlashes (moduleName mod)
+ let basename = moduleNameSlashes (installedModuleName mod)
loc <- mk_hi_loc one basename
- return (Found loc mod)
+ return (InstalledFound loc mod)
_otherwise ->
searchPathExts import_dirs mod [(package_hisuf, mk_hi_loc)]
@@ -337,13 +372,13 @@ findPackageModule_ hsc_env mod pkg_conf =
searchPathExts
:: [FilePath] -- paths to search
- -> Module -- module name
+ -> InstalledModule -- module name
-> [ (
FileExt, -- suffix
FilePath -> BaseName -> IO ModLocation -- action
)
]
- -> IO FindResult
+ -> IO InstalledFindResult
searchPathExts paths mod exts
= do result <- search to_search
@@ -358,7 +393,7 @@ searchPathExts paths mod exts
return result
where
- basename = moduleNameSlashes (moduleName mod)
+ basename = moduleNameSlashes (installedModuleName mod)
to_search :: [(FilePath, IO ModLocation)]
to_search = [ (file, fn path basename)
@@ -369,15 +404,12 @@ searchPathExts paths mod exts
file = base <.> ext
]
- search [] = return (NotFound { fr_paths = map fst to_search
- , fr_pkg = Just (moduleUnitId mod)
- , fr_mods_hidden = [], fr_pkgs_hidden = []
- , fr_suggestions = [] })
+ search [] = return (InstalledNotFound (map fst to_search) (Just (installedModuleUnitId mod)))
search ((file, mk_result) : rest) = do
b <- doesFileExist file
if b
- then do { loc <- mk_result; return (Found loc mod) }
+ then do { loc <- mk_result; return (InstalledFound loc mod) }
else search rest
mkHomeModLocationSearched :: DynFlags -> ModuleName -> FileExt
@@ -539,9 +571,9 @@ cannotFindModule :: DynFlags -> ModuleName -> FindResult -> SDoc
cannotFindModule = cantFindErr (sLit "Could not find module")
(sLit "Ambiguous module name")
-cannotFindInterface :: DynFlags -> ModuleName -> FindResult -> SDoc
-cannotFindInterface = cantFindErr (sLit "Failed to load interface for")
- (sLit "Ambiguous interface for")
+cannotFindInterface :: DynFlags -> ModuleName -> InstalledFindResult -> SDoc
+cannotFindInterface = cantFindInstalledErr (sLit "Failed to load interface for")
+ (sLit "Ambiguous interface for")
cantFindErr :: LitString -> LitString -> DynFlags -> ModuleName -> FindResult
-> SDoc
@@ -581,7 +613,7 @@ cantFindErr cannot_find _ dflags mod_name find_result
= case find_result of
NoPackage pkg
-> text "no unit id matching" <+> quotes (ppr pkg) <+>
- text "was found" $$ looks_like_srcpkgid pkg
+ text "was found"
NotFound { fr_paths = files, fr_pkg = mb_pkg
, fr_mods_hidden = mod_hiddens, fr_pkgs_hidden = pkg_hiddens
@@ -642,18 +674,6 @@ cantFindErr cannot_find _ dflags mod_name find_result
text "to the build-depends in your .cabal file."
| otherwise = Outputable.empty
- looks_like_srcpkgid :: UnitId -> SDoc
- looks_like_srcpkgid pk
- -- Unsafely coerce a unit id FastString into a source package ID
- -- FastString and see if it means anything.
- | (pkg:pkgs) <- searchPackageId dflags (SourcePackageId (unitIdFS pk))
- = parens (text "This unit ID looks like the source package ID;" $$
- text "the real unit ID is" <+> quotes (ftext (unitIdFS (unitId pkg))) $$
- (if null pkgs then Outputable.empty
- else text "and" <+> int (length pkgs) <+> text "other candidates"))
- -- Todo: also check if it looks like a package name!
- | otherwise = Outputable.empty
-
mod_hidden pkg =
text "it is a hidden module in the package" <+> quotes (ppr pkg)
@@ -693,3 +713,64 @@ cantFindErr cannot_find _ dflags mod_name find_result
= parens (text "needs flag -package-id"
<+> ppr (packageConfigId pkg))
| otherwise = Outputable.empty
+
+cantFindInstalledErr :: LitString -> LitString -> DynFlags -> ModuleName -> InstalledFindResult
+ -> SDoc
+cantFindInstalledErr cannot_find _ dflags mod_name find_result
+ = ptext cannot_find <+> quotes (ppr mod_name)
+ $$ more_info
+ where
+ more_info
+ = case find_result of
+ InstalledNoPackage pkg
+ -> text "no unit id matching" <+> quotes (ppr pkg) <+>
+ text "was found" $$ looks_like_srcpkgid pkg
+
+ InstalledNotFound files mb_pkg
+ | Just pkg <- mb_pkg, not (pkg `installedUnitIdEq` thisPackage dflags)
+ -> not_found_in_package pkg files
+
+ | null files
+ -> text "It is not a module in the current program, or in any known package."
+
+ | otherwise
+ -> tried_these files
+
+ _ -> panic "cantFindInstalledErr"
+
+ build_tag = buildTag dflags
+
+ looks_like_srcpkgid :: InstalledUnitId -> SDoc
+ looks_like_srcpkgid pk
+ -- Unsafely coerce a unit id FastString into a source package ID
+ -- FastString and see if it means anything.
+ | (pkg:pkgs) <- searchPackageId dflags (SourcePackageId (installedUnitIdFS pk))
+ = parens (text "This unit ID looks like the source package ID;" $$
+ text "the real unit ID is" <+> quotes (ftext (installedUnitIdFS (unitId pkg))) $$
+ (if null pkgs then Outputable.empty
+ else text "and" <+> int (length pkgs) <+> text "other candidates"))
+ -- Todo: also check if it looks like a package name!
+ | otherwise = Outputable.empty
+
+ not_found_in_package pkg files
+ | build_tag /= ""
+ = let
+ build = if build_tag == "p" then "profiling"
+ else "\"" ++ build_tag ++ "\""
+ in
+ text "Perhaps you haven't installed the " <> text build <>
+ text " libraries for package " <> quotes (ppr pkg) <> char '?' $$
+ tried_these files
+
+ | otherwise
+ = text "There are files missing in the " <> quotes (ppr pkg) <>
+ text " package," $$
+ text "try running 'ghc-pkg check'." $$
+ tried_these files
+
+ tried_these files
+ | null files = Outputable.empty
+ | verbosity dflags < 3 =
+ text "Use -v to see a list of the files searched for."
+ | otherwise =
+ hang (text "Locations searched:") 2 $ vcat (map text files)
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs
index 6a3887a0e9..5122329acf 100644
--- a/compiler/main/GHC.hs
+++ b/compiler/main/GHC.hs
@@ -576,7 +576,7 @@ checkBrokenTablesNextToCode' dflags
-- flags. If you are not doing linking or doing static linking, you
-- can ignore the list of packages returned.
--
-setSessionDynFlags :: GhcMonad m => DynFlags -> m [UnitId]
+setSessionDynFlags :: GhcMonad m => DynFlags -> m [InstalledUnitId]
setSessionDynFlags dflags = do
dflags' <- checkNewDynFlags dflags
(dflags'', preload) <- liftIO $ initPackages dflags'
@@ -586,7 +586,7 @@ setSessionDynFlags dflags = do
return preload
-- | Sets the program 'DynFlags'.
-setProgramDynFlags :: GhcMonad m => DynFlags -> m [UnitId]
+setProgramDynFlags :: GhcMonad m => DynFlags -> m [InstalledUnitId]
setProgramDynFlags dflags = do
dflags' <- checkNewDynFlags dflags
(dflags'', preload) <- liftIO $ initPackages dflags'
@@ -1435,7 +1435,7 @@ isModuleTrusted m = withSession $ \hsc_env ->
liftIO $ hscCheckSafe hsc_env m noSrcSpan
-- | Return if a module is trusted and the pkgs it depends on to be trusted.
-moduleTrustReqs :: GhcMonad m => Module -> m (Bool, [UnitId])
+moduleTrustReqs :: GhcMonad m => Module -> m (Bool, [InstalledUnitId])
moduleTrustReqs m = withSession $ \hsc_env ->
liftIO $ hscGetSafe hsc_env m noSrcSpan
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index 998d68c11a..0921a58531 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -1916,7 +1916,8 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
extra_sig_imports <- findExtraSigImports hsc_env hsc_src mod_name
required_by_imports <- implicitRequirements hsc_env the_imps
- return (ModSummary { ms_mod = mod, ms_hsc_src = hsc_src,
+ return (ModSummary { ms_mod = mod,
+ ms_hsc_src = hsc_src,
ms_location = location,
ms_hspp_file = hspp_fn,
ms_hspp_opts = dflags',
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index cd8b56843f..ae6ad7d068 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -179,7 +179,7 @@ newHscEnv dflags = do
eps_var <- newIORef initExternalPackageState
us <- mkSplitUniqSupply 'r'
nc_var <- newIORef (initNameCache us allKnownKeyNames)
- fc_var <- newIORef emptyModuleEnv
+ fc_var <- newIORef emptyInstalledModuleEnv
#ifdef GHCI
iserv_mvar <- newMVar Nothing
#endif
@@ -444,12 +444,14 @@ hscTypecheck keep_rn mod_summary mb_rdr_module = do
let hsc_src = ms_hsc_src mod_summary
dflags = hsc_dflags hsc_env
outer_mod = ms_mod mod_summary
- inner_mod = canonicalizeHomeModule dflags (moduleName outer_mod)
+ mod_name = moduleName outer_mod
+ outer_mod' = mkModule (thisPackage dflags) mod_name
+ inner_mod = canonicalizeHomeModule dflags mod_name
src_filename = ms_hspp_file mod_summary
real_loc = realSrcLocSpan $ mkRealSrcLoc (mkFastString src_filename) 1 1
MASSERT( moduleUnitId outer_mod == thisPackage dflags )
if hsc_src == HsigFile && not (isHoleModule inner_mod)
- then ioMsgMaybe $ tcRnInstantiateSignature hsc_env outer_mod real_loc
+ then ioMsgMaybe $ tcRnInstantiateSignature hsc_env outer_mod' real_loc
else
do hpm <- case mb_rdr_module of
Just hpm -> return hpm
@@ -1021,7 +1023,7 @@ hscCheckSafe hsc_env m l = runHsc hsc_env $ do
return $ isEmptyBag errs
-- | Return if a module is trusted and the pkgs it depends on to be trusted.
-hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, [UnitId])
+hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, [InstalledUnitId])
hscGetSafe hsc_env m l = runHsc hsc_env $ do
dflags <- getDynFlags
(self, pkgs) <- hscCheckSafe' dflags m l
@@ -1035,15 +1037,17 @@ hscGetSafe hsc_env m l = runHsc hsc_env $ do
-- Return (regardless of trusted or not) if the trust type requires the modules
-- own package be trusted and a list of other packages required to be trusted
-- (these later ones haven't been checked) but the own package trust has been.
-hscCheckSafe' :: DynFlags -> Module -> SrcSpan -> Hsc (Maybe UnitId, [UnitId])
+hscCheckSafe' :: DynFlags -> Module -> SrcSpan -> Hsc (Maybe InstalledUnitId, [InstalledUnitId])
hscCheckSafe' dflags m l = do
(tw, pkgs) <- isModSafe m l
case tw of
False -> return (Nothing, pkgs)
True | isHomePkg m -> return (Nothing, pkgs)
- | otherwise -> return (Just $ moduleUnitId m, pkgs)
+ -- TODO: do we also have to check the trust of the instantiation?
+ -- Not necessary if that is reflected in dependencies
+ | otherwise -> return (Just $ toInstalledUnitId (moduleUnitId m), pkgs)
where
- isModSafe :: Module -> SrcSpan -> Hsc (Bool, [UnitId])
+ isModSafe :: Module -> SrcSpan -> Hsc (Bool, [InstalledUnitId])
isModSafe m l = do
iface <- lookup' m
case iface of
@@ -1123,7 +1127,7 @@ hscCheckSafe' dflags m l = do
| otherwise = False
-- | Check the list of packages are trusted.
-checkPkgTrust :: DynFlags -> [UnitId] -> Hsc ()
+checkPkgTrust :: DynFlags -> [InstalledUnitId] -> Hsc ()
checkPkgTrust dflags pkgs =
case errors of
[] -> return ()
@@ -1131,7 +1135,7 @@ checkPkgTrust dflags pkgs =
where
errors = catMaybes $ map go pkgs
go pkg
- | trusted $ getPackageDetails dflags pkg
+ | trusted $ getInstalledPackageDetails dflags pkg
= Nothing
| otherwise
= Just $ mkErrMsg dflags noSrcSpan (pkgQual dflags)
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index c2d2938b45..1320a57e9a 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -10,7 +10,7 @@
module HscTypes (
-- * compilation state
HscEnv(..), hscEPS,
- FinderCache, FindResult(..),
+ FinderCache, FindResult(..), InstalledFindResult(..),
Target(..), TargetId(..), pprTarget, pprTargetId,
ModuleGraph, emptyMG,
HscStatus(..),
@@ -26,7 +26,7 @@ module HscTypes (
ModGuts(..), CgGuts(..), ForeignStubs(..), appendStubC,
ImportedMods, ImportedModsVal(..),
- ModSummary(..), ms_imps, ms_mod_name, showModMsg, isBootSummary,
+ ModSummary(..), ms_imps, ms_installed_mod, ms_mod_name, showModMsg, isBootSummary,
msHsFilePath, msHiFilePath, msObjFilePath,
SourceModified(..),
@@ -771,16 +771,18 @@ prepareAnnotations hsc_env mb_guts = do
-- modules along the search path. On @:load@, we flush the entire
-- contents of this cache.
--
--- Although the @FinderCache@ range is 'FindResult' for convenience,
--- in fact it will only ever contain 'Found' or 'NotFound' entries.
---
-type FinderCache = VirginModuleEnv FindResult
+type FinderCache = InstalledModuleEnv InstalledFindResult
+
+data InstalledFindResult
+ = InstalledFound ModLocation InstalledModule
+ | InstalledNoPackage InstalledUnitId
+ | InstalledNotFound [FilePath] (Maybe InstalledUnitId)
-- | The result of searching for an imported module.
--
-- NB: FindResult manages both user source-import lookups
-- (which can result in 'Module') as well as direct imports
--- for interfaces (which always result in 'VirginModule').
+-- for interfaces (which always result in 'InstalledModule').
data FindResult
= Found ModLocation Module
-- ^ The module was found
@@ -1272,8 +1274,8 @@ data CgGuts
-- as part of the code-gen of tycons
cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs
- cg_dep_pkgs :: ![UnitId], -- ^ Dependent packages, used to
- -- generate #includes for C code gen
+ cg_dep_pkgs :: ![InstalledUnitId], -- ^ Dependent packages, used to
+ -- generate #includes for C code gen
cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information
cg_modBreaks :: !(Maybe ModBreaks) -- ^ Module breakpoints
}
@@ -2240,7 +2242,7 @@ data Dependencies
-- I.e. modules that this one imports, or that are in the
-- dep_mods of those directly-imported modules
- , dep_pkgs :: [(UnitId, Bool)]
+ , dep_pkgs :: [(InstalledUnitId, Bool)]
-- ^ All packages transitively below this module
-- I.e. packages to which this module's direct imports belong,
-- or that are in the dep_pkgs of those modules
@@ -2449,7 +2451,7 @@ data ExternalPackageState
--
-- * Deprecations and warnings
- eps_free_holes :: ModuleEnv (UniqDSet ModuleName),
+ eps_free_holes :: InstalledModuleEnv (UniqDSet ModuleName),
-- ^ Cache for 'mi_free_holes'. Ordinarily, we can rely on
-- the 'eps_PIT' for this information, EXCEPT that when
-- we do dependency analysis, we need to look at the
@@ -2602,6 +2604,9 @@ data ModSummary
-- ^ The actual preprocessed source, if we have it
}
+ms_installed_mod :: ModSummary -> InstalledModule
+ms_installed_mod = fst . splitModuleInsts . ms_mod
+
ms_mod_name :: ModSummary -> ModuleName
ms_mod_name = moduleName . ms_mod
diff --git a/compiler/main/PackageConfig.hs b/compiler/main/PackageConfig.hs
index f16c902a7e..6e3e2f1c9b 100644
--- a/compiler/main/PackageConfig.hs
+++ b/compiler/main/PackageConfig.hs
@@ -12,6 +12,8 @@ module PackageConfig (
-- * UnitId
packageConfigId,
expandedPackageConfigId,
+ definitePackageConfigId,
+ installedPackageConfigId,
-- * The PackageConfig type: information about a package
PackageConfig,
@@ -35,6 +37,7 @@ import FastString
import Outputable
import Module
import Unique
+import UniqDSet
-- -----------------------------------------------------------------------------
-- Our PackageConfig type is the InstalledPackageInfo from ghc-boot,
@@ -44,7 +47,7 @@ type PackageConfig = InstalledPackageInfo
ComponentId
SourcePackageId
PackageName
- Module.UnitId
+ Module.InstalledUnitId
Module.UnitId
Module.ModuleName
Module.Module
@@ -129,11 +132,21 @@ pprPackageConfig InstalledPackageInfo {..} =
-- version is, so these are handled specially; see #wired_in_packages#.
-- | Get the GHC 'UnitId' right out of a Cabalish 'PackageConfig'
+installedPackageConfigId :: PackageConfig -> InstalledUnitId
+installedPackageConfigId = unitId
+
packageConfigId :: PackageConfig -> UnitId
-packageConfigId = unitId
+packageConfigId p =
+ if indefinite p
+ then newUnitId (installedUnitIdComponentId (unitId p)) (instantiatedWith p)
+ else DefiniteUnitId (DefUnitId (unitId p))
expandedPackageConfigId :: PackageConfig -> UnitId
expandedPackageConfigId p =
- case instantiatedWith p of
- [] -> packageConfigId p
- _ -> newUnitId (unitIdComponentId (packageConfigId p)) (instantiatedWith p)
+ newUnitId (installedUnitIdComponentId (unitId p)) (instantiatedWith p)
+
+definitePackageConfigId :: PackageConfig -> Maybe DefUnitId
+definitePackageConfigId p =
+ case packageConfigId p of
+ DefiniteUnitId def_uid -> Just def_uid
+ _ -> Nothing
diff --git a/compiler/main/Packages.hs b/compiler/main/Packages.hs
index 3003e015b6..566d998899 100644
--- a/compiler/main/Packages.hs
+++ b/compiler/main/Packages.hs
@@ -20,11 +20,12 @@ module Packages (
-- * Querying the package config
lookupPackage,
lookupPackage',
+ lookupInstalledPackage,
lookupPackageName,
- lookupComponentId,
improveUnitId,
searchPackageId,
getPackageDetails,
+ getInstalledPackageDetails,
componentIdString,
listVisibleModuleNames,
lookupModuleInAllPackages,
@@ -65,6 +66,7 @@ import DynFlags
import Name ( Name, nameModule_maybe )
import UniqFM
import UniqDFM
+import UniqSet
import Module
import Util
import Panic
@@ -238,12 +240,18 @@ originEmpty :: ModuleOrigin -> Bool
originEmpty (ModOrigin Nothing [] [] False) = True
originEmpty _ = False
--- | 'UniqFM' map from 'UnitId'
-type UnitIdMap = UniqDFM
-
--- | 'UniqFM' map from 'UnitId' to 'PackageConfig'
--- (newtyped so we can put it in boot.)
-newtype PackageConfigMap = PackageConfigMap { unPackageConfigMap :: UnitIdMap PackageConfig }
+-- | 'UniqFM' map from 'InstalledUnitId'
+type InstalledUnitIdMap = UniqDFM
+
+-- | 'UniqFM' map from 'UnitId' to 'PackageConfig', plus
+-- the transitive closure of preload packages.
+data PackageConfigMap = PackageConfigMap {
+ unPackageConfigMap :: InstalledUnitIdMap PackageConfig,
+ -- | The set of transitively reachable packages according
+ -- to the explicitly provided command line arguments.
+ -- See Note [UnitId to InstalledUnitId improvement]
+ preloadClosure :: UniqSet InstalledUnitId
+ }
-- | 'UniqFM' map from 'UnitId' to a 'UnitVisibility'.
type VisibilityMap = Map UnitId UnitVisibility
@@ -294,6 +302,9 @@ instance Monoid UnitVisibility where
, uv_explicit = uv_explicit uv1 || uv_explicit uv2
}
+type WiredUnitId = DefUnitId
+type PreloadUnitId = InstalledUnitId
+
-- | Map from 'ModuleName' to 'Module' to all the origins of the bindings
-- in scope. The 'PackageConf' is not cached, mostly for convenience reasons
-- (since this is the slow path, we'll just look it up again).
@@ -314,12 +325,12 @@ data PackageState = PackageState {
-- | A mapping from wired in names to the original names from the
-- package database.
- unwireMap :: Map UnitId UnitId,
+ unwireMap :: Map WiredUnitId WiredUnitId,
-- | The packages we're going to link in eagerly. This list
-- should be in reverse dependency order; that is, a package
-- is always mentioned before the packages it depends on.
- preloadPackages :: [UnitId],
+ preloadPackages :: [PreloadUnitId],
-- | Packages which we explicitly depend on (from a command line flag).
-- We'll use this to generate version macros.
@@ -355,11 +366,11 @@ emptyPackageState = PackageState {
requirementContext = Map.empty
}
-type InstalledPackageIndex = Map UnitId PackageConfig
+type InstalledPackageIndex = Map InstalledUnitId PackageConfig
-- | Empty package configuration map
emptyPackageConfigMap :: PackageConfigMap
-emptyPackageConfigMap = PackageConfigMap emptyUDFM
+emptyPackageConfigMap = PackageConfigMap emptyUDFM emptyUniqSet
-- | Find the package we know about with the given unit id, if any
lookupPackage :: DynFlags -> UnitId -> Maybe PackageConfig
@@ -370,14 +381,15 @@ lookupPackage dflags = lookupPackage' (isIndefinite dflags) (pkgIdMap (pkgState
-- just a 'PackageConfigMap' rather than a 'DynFlags' (so it can
-- be used while we're initializing 'DynFlags'
lookupPackage' :: Bool -> PackageConfigMap -> UnitId -> Maybe PackageConfig
-lookupPackage' False (PackageConfigMap pkg_map) uid = lookupUDFM pkg_map uid
-lookupPackage' True (PackageConfigMap pkg_map) uid =
+lookupPackage' False (PackageConfigMap pkg_map _) uid = lookupUDFM pkg_map uid
+lookupPackage' True m@(PackageConfigMap pkg_map _) uid =
case splitUnitIdInsts uid of
(iuid, Just insts) ->
- fmap (renamePackage (PackageConfigMap pkg_map) insts)
+ fmap (renamePackage m insts)
(lookupUDFM pkg_map iuid)
(_, Nothing) -> lookupUDFM pkg_map uid
+{-
-- | Find the indefinite package for a given 'ComponentId'.
-- The way this works is just by fiat'ing that every indefinite package's
-- unit key is precisely its component ID; and that they share uniques.
@@ -385,6 +397,7 @@ lookupComponentId :: DynFlags -> ComponentId -> Maybe PackageConfig
lookupComponentId dflags (ComponentId cid_fs) = lookupUDFM pkg_map cid_fs
where
PackageConfigMap pkg_map = pkgIdMap (pkgState dflags)
+-}
-- | Find the package we know about with the given package name (e.g. @foo@), if any
-- (NB: there might be a locally defined unit name which overrides this)
@@ -399,12 +412,12 @@ searchPackageId dflags pid = filter ((pid ==) . sourcePackageId)
-- | Extends the package configuration map with a list of package configs.
extendPackageConfigMap
:: PackageConfigMap -> [PackageConfig] -> PackageConfigMap
-extendPackageConfigMap (PackageConfigMap pkg_map) new_pkgs
- = PackageConfigMap (foldl add pkg_map new_pkgs)
+extendPackageConfigMap (PackageConfigMap pkg_map closure) new_pkgs
+ = PackageConfigMap (foldl add pkg_map new_pkgs) closure
-- We also add the expanded version of the packageConfigId, so that
-- 'improveUnitId' can find it.
where add pkg_map p = addToUDFM (addToUDFM pkg_map (expandedPackageConfigId p) p)
- (packageConfigId p) p
+ (installedPackageConfigId p) p
-- | Looks up the package with the given id in the package state, panicing if it is
-- not found
@@ -412,6 +425,17 @@ getPackageDetails :: DynFlags -> UnitId -> PackageConfig
getPackageDetails dflags pid =
expectJust "getPackageDetails" (lookupPackage dflags pid)
+lookupInstalledPackage :: DynFlags -> InstalledUnitId -> Maybe PackageConfig
+lookupInstalledPackage dflags uid = lookupInstalledPackage' (pkgIdMap (pkgState dflags)) uid
+
+lookupInstalledPackage' :: PackageConfigMap -> InstalledUnitId -> Maybe PackageConfig
+lookupInstalledPackage' (PackageConfigMap db _) uid = lookupUDFM db uid
+
+getInstalledPackageDetails :: DynFlags -> InstalledUnitId -> PackageConfig
+getInstalledPackageDetails dflags uid =
+ expectJust "getInstalledPackageDetails" $
+ lookupInstalledPackage dflags uid
+
-- | Get a list of entries from the package database. NB: be careful with
-- this function, although all packages in this map are "visible", this
-- does not imply that the exposed-modules of the package are available
@@ -419,7 +443,7 @@ getPackageDetails dflags pid =
listPackageConfigMap :: DynFlags -> [PackageConfig]
listPackageConfigMap dflags = eltsUDFM pkg_map
where
- PackageConfigMap pkg_map = pkgIdMap (pkgState dflags)
+ PackageConfigMap pkg_map _ = pkgIdMap (pkgState dflags)
-- ----------------------------------------------------------------------------
-- Loading the package db files and building up the package state
@@ -437,7 +461,7 @@ listPackageConfigMap dflags = eltsUDFM pkg_map
-- 'packageFlags' field of the 'DynFlags', and it will update the
-- 'pkgState' in 'DynFlags' and return a list of packages to
-- link in.
-initPackages :: DynFlags -> IO (DynFlags, [UnitId])
+initPackages :: DynFlags -> IO (DynFlags, [PreloadUnitId])
initPackages dflags0 = do
dflags <- interpretPackageEnv dflags0
pkg_db <-
@@ -741,7 +765,7 @@ findPackages pkg_db arg pkgs unusable
else Nothing
finder (UnitIdArg uid) p
= let (iuid, mb_insts) = splitUnitIdInsts uid
- in if iuid == packageConfigId p
+ in if iuid == installedPackageConfigId p
then Just (case mb_insts of
Nothing -> p
Just insts -> renamePackage pkg_db insts p)
@@ -765,12 +789,10 @@ renamePackage :: PackageConfigMap -> [(ModuleName, Module)]
-> PackageConfig -> PackageConfig
renamePackage pkg_map insts conf =
let hsubst = listToUFM insts
- smod = renameHoleModule' pkg_map hsubst
- suid = renameHoleUnitId' pkg_map hsubst
- new_uid = suid (unitId conf)
+ smod = renameHoleModule' pkg_map hsubst
+ new_insts = map (\(k,v) -> (k,smod v)) (instantiatedWith conf)
in conf {
- unitId = new_uid,
- depends = map suid (depends conf),
+ instantiatedWith = new_insts,
exposedModules = map (\(mod_name, mb_mod) -> (mod_name, fmap smod mb_mod))
(exposedModules conf)
}
@@ -783,12 +805,13 @@ matchingStr str p
= str == sourcePackageIdString p
|| str == packageNameString p
-matchingId :: UnitId -> PackageConfig -> Bool
-matchingId uid p = uid == packageConfigId p
+matchingId :: InstalledUnitId -> PackageConfig -> Bool
+matchingId uid p = uid == installedPackageConfigId p
matching :: PackageArg -> PackageConfig -> Bool
matching (PackageArg str) = matchingStr str
-matching (UnitIdArg uid) = matchingId uid
+matching (UnitIdArg (DefiniteUnitId (DefUnitId uid))) = matchingId uid
+matching (UnitIdArg _) = \_ -> False -- TODO: warn in this case
sortByVersion :: [PackageConfig] -> [PackageConfig]
sortByVersion = sortBy (flip (comparing packageVersion))
@@ -849,7 +872,7 @@ pprTrustFlag flag = case flag of
wired_in_pkgids :: [String]
wired_in_pkgids = map unitIdString wiredInUnitIds
-type WiredPackagesMap = Map UnitId UnitId
+type WiredPackagesMap = Map WiredUnitId WiredUnitId
findWiredInPackages
:: DynFlags
@@ -918,7 +941,7 @@ findWiredInPackages dflags pkgs vis_map = do
mb_wired_in_pkgs <- mapM (findWiredInPackage pkgs) wired_in_pkgids
let
wired_in_pkgs = catMaybes mb_wired_in_pkgs
- wired_in_ids = map unitId wired_in_pkgs
+ wired_in_ids = mapMaybe definitePackageConfigId wired_in_pkgs
-- this is old: we used to assume that if there were
-- multiple versions of wired-in packages installed that
@@ -933,30 +956,38 @@ findWiredInPackages dflags pkgs vis_map = do
&& package p `notElem` map fst wired_in_ids
-}
- wiredInMap :: Map UnitId UnitId
+ wiredInMap :: Map WiredUnitId WiredUnitId
wiredInMap = foldl' add_mapping Map.empty pkgs
where add_mapping m pkg
- | let key = unitId pkg
+ | Just key <- definitePackageConfigId pkg
, key `elem` wired_in_ids
- = Map.insert key (stringToUnitId (packageNameString pkg)) m
+ = Map.insert key (DefUnitId (stringToInstalledUnitId (packageNameString pkg))) m
| otherwise = m
updateWiredInDependencies pkgs = map (upd_deps . upd_pkg) pkgs
where upd_pkg pkg
- | unitId pkg `elem` wired_in_ids
+ | Just def_uid <- definitePackageConfigId pkg
+ , def_uid `elem` wired_in_ids
= pkg {
unitId = let PackageName fs = packageName pkg
- in fsToUnitId fs
+ in fsToInstalledUnitId fs
}
| otherwise
= pkg
upd_deps pkg = pkg {
- depends = map upd_wired_in (depends pkg),
+ -- temporary harmless DefUnitId invariant violation
+ depends = map (unDefUnitId . upd_wired_in . DefUnitId) (depends pkg),
exposedModules
= map (\(k,v) -> (k, fmap upd_wired_in_mod v))
(exposedModules pkg)
}
- upd_wired_in_mod (Module uid m) = Module (upd_wired_in uid) m
+ upd_wired_in_mod (Module uid m) = Module (upd_wired_in_uid uid) m
+ upd_wired_in_uid (DefiniteUnitId def_uid) =
+ DefiniteUnitId (upd_wired_in def_uid)
+ upd_wired_in_uid (IndefiniteUnitId indef_uid) =
+ IndefiniteUnitId $ newIndefUnitId
+ (indefUnitIdComponentId indef_uid)
+ (map (\(x,y) -> (x,upd_wired_in_mod y)) (indefUnitIdInsts indef_uid))
upd_wired_in key
| Just key' <- Map.lookup key wiredInMap = key'
| otherwise = key
@@ -966,9 +997,10 @@ findWiredInPackages dflags pkgs vis_map = do
updateVisibilityMap :: WiredPackagesMap -> VisibilityMap -> VisibilityMap
updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (Map.toList wiredInMap)
- where f vm (from, to) = case Map.lookup from vis_map of
+ where f vm (from, to) = case Map.lookup (DefiniteUnitId from) vis_map of
Nothing -> vm
- Just r -> Map.insert to r (Map.delete from vm)
+ Just r -> Map.insert (DefiniteUnitId to) r
+ (Map.delete (DefiniteUnitId from) vm)
-- ----------------------------------------------------------------------------
@@ -976,13 +1008,13 @@ updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (Map.toList wiredInMap
type IsShadowed = Bool
data UnusablePackageReason
= IgnoredWithFlag
- | MissingDependencies IsShadowed [UnitId]
+ | MissingDependencies IsShadowed [InstalledUnitId]
instance Outputable UnusablePackageReason where
ppr IgnoredWithFlag = text "[ignored with flag]"
ppr (MissingDependencies b uids) =
brackets (if b then text "shadowed" else empty <+> ppr uids)
-type UnusablePackages = Map UnitId
+type UnusablePackages = Map InstalledUnitId
(PackageConfig, UnusablePackageReason)
pprReason :: SDoc -> UnusablePackageReason -> SDoc
@@ -1014,7 +1046,7 @@ reportUnusable dflags pkgs = mapM_ report (Map.toList pkgs)
--
findBroken :: IsShadowed
-> [PackageConfig]
- -> Map UnitId PackageConfig
+ -> Map InstalledUnitId PackageConfig
-> UnusablePackages
findBroken is_shadowed pkgs pkg_map0 = go [] pkg_map0 pkgs
where
@@ -1031,7 +1063,7 @@ findBroken is_shadowed pkgs pkg_map0 = go [] pkg_map0 pkgs
depsAvailable :: InstalledPackageIndex
-> PackageConfig
- -> Either PackageConfig (PackageConfig, [UnitId])
+ -> Either PackageConfig (PackageConfig, [InstalledUnitId])
depsAvailable pkg_map pkg
| null dangling = Left pkg
| otherwise = Right (pkg, dangling)
@@ -1058,9 +1090,9 @@ ignorePackages flags pkgs = Map.fromList (concatMap doit flags)
mkPackageState
:: DynFlags
-> [(FilePath, [PackageConfig])] -- initial databases
- -> [UnitId] -- preloaded packages
+ -> [PreloadUnitId] -- preloaded packages
-> IO (PackageState,
- [UnitId]) -- new packages to preload
+ [PreloadUnitId]) -- new packages to preload
mkPackageState dflags dbs preload0 = do
-- Compute the unit id
@@ -1138,7 +1170,7 @@ mkPackageState dflags dbs preload0 = do
`Map.union` unusable)
where -- The set of UnitIds which appear in both
-- db and pkgs (to be shadowed from pkgs)
- shadow_set :: Set UnitId
+ shadow_set :: Set InstalledUnitId
shadow_set = foldr ins Set.empty db
where ins pkg s
-- If the package from the upper database is
@@ -1180,7 +1212,7 @@ mkPackageState dflags dbs preload0 = do
-- Now merge the sets together (NB: later overrides
-- earlier!)
- pkg_map' :: Map UnitId PackageConfig
+ pkg_map' :: Map InstalledUnitId PackageConfig
pkg_map' = mk_pkg_map (shadowed_pkgs ++ db3)
(pkg_map1, unusable) <- foldM merge (Map.empty, Map.empty) dbs
@@ -1309,7 +1341,7 @@ mkPackageState dflags dbs preload0 = do
$ (basicLinkedPackages ++ preload2)
-- Close the preload packages with their dependencies
- dep_preload <- closeDeps dflags pkg_db (zip preload3 (repeat Nothing))
+ dep_preload <- closeDeps dflags pkg_db (zip (map toInstalledUnitId preload3) (repeat Nothing))
let new_dep_preload = filter (`notElem` preload0) dep_preload
let mod_map = mkModuleToPkgConfAll dflags pkg_db vis_map
@@ -1333,8 +1365,9 @@ mkPackageState dflags dbs preload0 = do
-- | Given a wired-in 'UnitId', "unwire" it into the 'UnitId'
-- that it was recorded as in the package database.
unwireUnitId :: DynFlags -> UnitId -> UnitId
-unwireUnitId dflags uid =
- fromMaybe uid (Map.lookup uid (unwireMap (pkgState dflags)))
+unwireUnitId dflags uid@(DefiniteUnitId def_uid) =
+ maybe uid DefiniteUnitId (Map.lookup def_uid (unwireMap (pkgState dflags)))
+unwireUnitId _ uid = uid
-- -----------------------------------------------------------------------------
-- | Makes the mapping from module to package info
@@ -1415,7 +1448,7 @@ mkModuleToPkgConfAll dflags pkg_db vis_map =
-- use.
-- | Find all the include directories in these and the preload packages
-getPackageIncludePath :: DynFlags -> [UnitId] -> IO [String]
+getPackageIncludePath :: DynFlags -> [PreloadUnitId] -> IO [String]
getPackageIncludePath dflags pkgs =
collectIncludeDirs `fmap` getPreloadPackagesAnd dflags pkgs
@@ -1423,7 +1456,7 @@ collectIncludeDirs :: [PackageConfig] -> [FilePath]
collectIncludeDirs ps = nub (filter notNull (concatMap includeDirs ps))
-- | Find all the library paths in these and the preload packages
-getPackageLibraryPath :: DynFlags -> [UnitId] -> IO [String]
+getPackageLibraryPath :: DynFlags -> [PreloadUnitId] -> IO [String]
getPackageLibraryPath dflags pkgs =
collectLibraryPaths `fmap` getPreloadPackagesAnd dflags pkgs
@@ -1432,7 +1465,7 @@ collectLibraryPaths ps = nub (filter notNull (concatMap libraryDirs ps))
-- | Find all the link options in these and the preload packages,
-- returning (package hs lib options, extra library options, other flags)
-getPackageLinkOpts :: DynFlags -> [UnitId] -> IO ([String], [String], [String])
+getPackageLinkOpts :: DynFlags -> [PreloadUnitId] -> IO ([String], [String], [String])
getPackageLinkOpts dflags pkgs =
collectLinkOpts dflags `fmap` getPreloadPackagesAnd dflags pkgs
@@ -1481,19 +1514,19 @@ packageHsLibs dflags p = map (mkDynName . addSuffix) (hsLibraries p)
| otherwise = '_':t
-- | Find all the C-compiler options in these and the preload packages
-getPackageExtraCcOpts :: DynFlags -> [UnitId] -> IO [String]
+getPackageExtraCcOpts :: DynFlags -> [PreloadUnitId] -> IO [String]
getPackageExtraCcOpts dflags pkgs = do
ps <- getPreloadPackagesAnd dflags pkgs
return (concatMap ccOptions ps)
-- | Find all the package framework paths in these and the preload packages
-getPackageFrameworkPath :: DynFlags -> [UnitId] -> IO [String]
+getPackageFrameworkPath :: DynFlags -> [PreloadUnitId] -> IO [String]
getPackageFrameworkPath dflags pkgs = do
ps <- getPreloadPackagesAnd dflags pkgs
return (nub (filter notNull (concatMap frameworkDirs ps)))
-- | Find all the package frameworks in these and the preload packages
-getPackageFrameworks :: DynFlags -> [UnitId] -> IO [String]
+getPackageFrameworks :: DynFlags -> [PreloadUnitId] -> IO [String]
getPackageFrameworks dflags pkgs = do
ps <- getPreloadPackagesAnd dflags pkgs
return (concatMap frameworks ps)
@@ -1616,7 +1649,7 @@ listVisibleModuleNames dflags =
-- | Find all the 'PackageConfig' in both the preload packages from 'DynFlags' and corresponding to the list of
-- 'PackageConfig's
-getPreloadPackagesAnd :: DynFlags -> [UnitId] -> IO [PackageConfig]
+getPreloadPackagesAnd :: DynFlags -> [PreloadUnitId] -> IO [PackageConfig]
getPreloadPackagesAnd dflags pkgids =
let
state = pkgState dflags
@@ -1625,14 +1658,14 @@ getPreloadPackagesAnd dflags pkgids =
pairs = zip pkgids (repeat Nothing)
in do
all_pkgs <- throwErr dflags (foldM (add_package dflags pkg_map) preload pairs)
- return (map (getPackageDetails dflags) all_pkgs)
+ return (map (getInstalledPackageDetails dflags) all_pkgs)
-- Takes a list of packages, and returns the list with dependencies included,
-- in reverse dependency order (a package appears before those it depends on).
closeDeps :: DynFlags
-> PackageConfigMap
- -> [(UnitId, Maybe UnitId)]
- -> IO [UnitId]
+ -> [(InstalledUnitId, Maybe InstalledUnitId)]
+ -> IO [InstalledUnitId]
closeDeps dflags pkg_map ps
= throwErr dflags (closeDepsErr dflags pkg_map ps)
@@ -1644,20 +1677,20 @@ throwErr dflags m
closeDepsErr :: DynFlags
-> PackageConfigMap
- -> [(UnitId,Maybe UnitId)]
- -> MaybeErr MsgDoc [UnitId]
+ -> [(InstalledUnitId,Maybe InstalledUnitId)]
+ -> MaybeErr MsgDoc [InstalledUnitId]
closeDepsErr dflags pkg_map ps = foldM (add_package dflags pkg_map) [] ps
-- internal helper
add_package :: DynFlags
-> PackageConfigMap
- -> [UnitId]
- -> (UnitId,Maybe UnitId)
- -> MaybeErr MsgDoc [UnitId]
+ -> [PreloadUnitId]
+ -> (PreloadUnitId,Maybe PreloadUnitId)
+ -> MaybeErr MsgDoc [PreloadUnitId]
add_package dflags pkg_db ps (p, mb_parent)
| p `elem` ps = return ps -- Check if we've already added this package
| otherwise =
- case lookupPackage' (isIndefinite dflags) pkg_db p of
+ case lookupInstalledPackage' pkg_db p of
Nothing -> Failed (missingPackageMsg p <>
missingDependencyMsg mb_parent)
Just pkg -> do
@@ -1671,19 +1704,19 @@ add_package dflags pkg_db ps (p, mb_parent)
missingPackageMsg :: Outputable pkgid => pkgid -> SDoc
missingPackageMsg p = text "unknown package:" <+> ppr p
-missingDependencyMsg :: Maybe UnitId -> SDoc
+missingDependencyMsg :: Maybe InstalledUnitId -> SDoc
missingDependencyMsg Nothing = Outputable.empty
missingDependencyMsg (Just parent)
- = space <> parens (text "dependency of" <+> ftext (unitIdFS parent))
+ = space <> parens (text "dependency of" <+> ftext (installedUnitIdFS parent))
-- -----------------------------------------------------------------------------
componentIdString :: DynFlags -> ComponentId -> Maybe String
componentIdString dflags cid =
- fmap sourcePackageIdString (lookupComponentId dflags cid)
+ fmap sourcePackageIdString (lookupInstalledPackage dflags (newInstalledUnitId cid Nothing))
-- | Will the 'Name' come from a dynamically linked library?
-isDllName :: DynFlags -> UnitId -> Module -> Name -> Bool
+isDllName :: DynFlags -> UnitId {- not used -} -> Module -> Name -> Bool
-- Despite the "dll", I think this function just means that
-- the symbol comes from another dynamically-linked package,
-- and applies on all platforms, not just Windows
@@ -1732,7 +1765,7 @@ pprPackagesWith pprIPI dflags =
-- be different from the package databases (exposure, trust)
pprPackagesSimple :: DynFlags -> SDoc
pprPackagesSimple = pprPackagesWith pprIPI
- where pprIPI ipi = let i = unitIdFS (unitId ipi)
+ where pprIPI ipi = let i = installedUnitIdFS (unitId ipi)
e = if exposed ipi then text "E" else text " "
t = if trusted ipi then text "T" else text " "
in e <> t <> text " " <> ftext i
@@ -1752,13 +1785,20 @@ fsPackageName :: PackageConfig -> FastString
fsPackageName = mkFastString . packageNameString
-- | Given a fully instantiated 'UnitId', improve it into a
--- 'HashedUnitId' if we can find it in the package database.
+-- 'InstalledUnitId' if we can find it in the package database.
improveUnitId :: PackageConfigMap -> UnitId -> UnitId
+improveUnitId _ uid@(DefiniteUnitId _) = uid -- short circuit
improveUnitId pkg_map uid =
-- Do NOT lookup indefinite ones, they won't be useful!
case lookupPackage' False pkg_map uid of
Nothing -> uid
- Just pkg -> packageConfigId pkg -- use the hashed version!
+ Just pkg ->
+ -- Do NOT improve if the indefinite unit id is not
+ -- part of the closure unique set. See
+ -- Note [UnitId to InstalledUnitId improvement]
+ if installedPackageConfigId pkg `elementOfUniqSet` preloadClosure pkg_map
+ then packageConfigId pkg
+ else uid
-- | Retrieve the 'PackageConfigMap' from 'DynFlags'; used
-- in the @hs-boot@ loop-breaker.
diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs
index e40b1d679f..e901bde06e 100644
--- a/compiler/main/SysTools.hs
+++ b/compiler/main/SysTools.hs
@@ -1564,7 +1564,7 @@ linesPlatform xs =
#endif
-linkDynLib :: DynFlags -> [String] -> [UnitId] -> IO ()
+linkDynLib :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
linkDynLib dflags0 o_files dep_packages
= do
let -- This is a rather ugly hack to fix dynamically linked
@@ -1741,7 +1741,7 @@ linkDynLib dflags0 o_files dep_packages
++ map Option pkg_link_opts
)
-getPkgFrameworkOpts :: DynFlags -> Platform -> [UnitId] -> IO [String]
+getPkgFrameworkOpts :: DynFlags -> Platform -> [InstalledUnitId] -> IO [String]
getPkgFrameworkOpts dflags platform dep_packages
| platformUsesFrameworks platform = do
pkg_framework_path_opts <- do