summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/CodeOutput.lhs16
-rw-r--r--compiler/main/DriverMkDepend.hs29
-rw-r--r--compiler/main/DriverPipeline.hs56
-rw-r--r--compiler/main/DynFlags.hs25
-rw-r--r--compiler/main/Finder.lhs404
-rw-r--r--compiler/main/GHC.hs265
-rw-r--r--compiler/main/HeaderInfo.hs16
-rw-r--r--compiler/main/HscMain.lhs20
-rw-r--r--compiler/main/HscTypes.lhs208
-rw-r--r--compiler/main/PackageConfig.hs48
-rw-r--r--compiler/main/Packages.lhs270
-rw-r--r--compiler/main/TidyPgm.lhs31
12 files changed, 742 insertions, 646 deletions
diff --git a/compiler/main/CodeOutput.lhs b/compiler/main/CodeOutput.lhs
index d1b293353a..30f273ebaa 100644
--- a/compiler/main/CodeOutput.lhs
+++ b/compiler/main/CodeOutput.lhs
@@ -27,6 +27,7 @@ import Finder ( mkStubPaths )
import PprC ( writeCs )
import CmmLint ( cmmLint )
import Packages
+import PackageConfig ( rtsPackageId )
import Util
import FastString ( unpackFS )
import Cmm ( Cmm )
@@ -35,7 +36,7 @@ import DynFlags
import ErrUtils ( dumpIfSet_dyn, showPass, ghcExit )
import Outputable
import Pretty ( Mode(..), printDoc )
-import Module ( Module, ModLocation(..) )
+import Module ( Module, ModLocation(..), moduleName )
import List ( nub )
import Maybes ( firstJust )
@@ -156,7 +157,7 @@ outputC dflags filenm mod location flat_absC
hPutStrLn h ("#include \"" ++ (filenameOf stub_h) ++ "\"")
writeCs dflags h flat_absC
where
- (_, stub_h) = mkStubPaths dflags mod location
+ (_, stub_h) = mkStubPaths dflags (moduleName mod) location
\end{code}
@@ -259,12 +260,9 @@ outputForeignStubs dflags mod location stubs
"Foreign export header file" stub_h_output_d
-- we need the #includes from the rts package for the stub files
- let rtsid = rtsPackageId (pkgState dflags)
- rts_includes
- | ExtPackage pid <- rtsid =
- let rts_pkg = getPackageDetails (pkgState dflags) pid in
- concatMap mk_include (includes rts_pkg)
- | otherwise = []
+ let rts_includes =
+ let rts_pkg = getPackageDetails (pkgState dflags) rtsPackageId in
+ concatMap mk_include (includes rts_pkg)
mk_include i = "#include \"" ++ i ++ "\"\n"
stub_h_file_exists
@@ -287,7 +285,7 @@ outputForeignStubs dflags mod location stubs
return (stub_h_file_exists, stub_c_file_exists)
where
- (stub_c, stub_h) = mkStubPaths dflags mod location
+ (stub_c, stub_h) = mkStubPaths dflags (moduleName mod) location
cplusplus_hdr = "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
cplusplus_ftr = "#ifdef __cplusplus\n}\n#endif\n"
diff --git a/compiler/main/DriverMkDepend.hs b/compiler/main/DriverMkDepend.hs
index 80d906c4a7..56f57f0f71 100644
--- a/compiler/main/DriverMkDepend.hs
+++ b/compiler/main/DriverMkDepend.hs
@@ -17,13 +17,12 @@ import GHC ( Session, ModSummary(..) )
import DynFlags ( DynFlags( verbosity, opt_dep ), getOpts )
import Util ( escapeSpaces, splitFilename, joinFileExt )
import HscTypes ( HscEnv, IsBootInterface, msObjFilePath, msHsFilePath )
-import Packages ( PackageIdH(..) )
import SysTools ( newTempName )
import qualified SysTools
-import Module ( Module, ModLocation(..), mkModule,
+import Module ( ModuleName, ModLocation(..), mkModuleName,
addBootSuffix_maybe )
import Digraph ( SCC(..) )
-import Finder ( findModule, FindResult(..) )
+import Finder ( findImportedModule, FindResult(..) )
import Util ( global, consIORef )
import Outputable
import Panic
@@ -153,7 +152,7 @@ beginMkDependHS dflags = do
-----------------------------------------------------------------
processDeps :: Session
- -> [Module]
+ -> [ModuleName]
-> Handle -- Write dependencies to here
-> SCC ModSummary
-> IO ()
@@ -217,24 +216,24 @@ processDeps session excl_mods hdl (AcyclicSCC node)
findDependency :: HscEnv
-> FilePath -- Importing module: used only for error msg
- -> Module -- Imported module
+ -> ModuleName -- Imported module
-> IsBootInterface -- Source import
-> Bool -- Record dependency on package modules
-> IO (Maybe FilePath) -- Interface file file
findDependency hsc_env src imp is_boot include_pkg_deps
= do { -- Find the module; this will be fast because
-- we've done it once during downsweep
- r <- findModule hsc_env imp True {-explicit-}
+ r <- findImportedModule hsc_env imp Nothing
; case r of
- Found loc pkg
- -- Not in this package: we don't need a dependency
- | ExtPackage _ <- pkg, not include_pkg_deps
- -> return Nothing
-
+ Found loc mod
-- Home package: just depend on the .hi or hi-boot file
- | otherwise
+ | isJust (ml_hs_file loc)
-> return (Just (addBootSuffix_maybe is_boot (ml_hi_file loc)))
+ -- Not in this package: we don't need a dependency
+ | otherwise
+ -> return Nothing
+
_ -> panic "findDependency"
}
@@ -322,7 +321,7 @@ endMkDependHS dflags
-- Flags
GLOBAL_VAR(v_Dep_makefile, "Makefile", String);
GLOBAL_VAR(v_Dep_include_pkg_deps, False, Bool);
-GLOBAL_VAR(v_Dep_exclude_mods, [], [Module]);
+GLOBAL_VAR(v_Dep_exclude_mods, [], [ModuleName]);
GLOBAL_VAR(v_Dep_suffixes, [], [String]);
GLOBAL_VAR(v_Dep_warnings, True, Bool);
@@ -337,6 +336,6 @@ dep_opts =
, ( "w", NoArg (writeIORef v_Dep_warnings False) )
, ( "-include-prelude", NoArg (writeIORef v_Dep_include_pkg_deps True) )
, ( "-include-pkg-deps", NoArg (writeIORef v_Dep_include_pkg_deps True) )
- , ( "-exclude-module=", Prefix (consIORef v_Dep_exclude_mods . mkModule) )
- , ( "x", Prefix (consIORef v_Dep_exclude_mods . mkModule) )
+ , ( "-exclude-module=", Prefix (consIORef v_Dep_exclude_mods . mkModuleName) )
+ , ( "x", Prefix (consIORef v_Dep_exclude_mods . mkModuleName) )
]
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index a39ca38a99..800baf1480 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -36,6 +36,7 @@ import Finder
import HscTypes
import Outputable
import Module
+import UniqFM ( eltsUFM )
import ErrUtils
import DynFlags
import StaticFlags ( v_Ld_inputs, opt_Static, WayName(..) )
@@ -235,7 +236,7 @@ compileStub dflags mod location = do
stub_o = o_base ++ "_stub" `joinFileExt` o_ext
-- compile the _stub.c file w/ gcc
- let (stub_c,_) = mkStubPaths dflags mod location
+ let (stub_c,_) = mkStubPaths dflags (moduleName mod) location
runPipeline StopLn dflags (stub_c,Nothing)
(SpecificFile stub_o) Nothing{-no ModLocation-}
@@ -271,7 +272,7 @@ link BatchCompile dflags batch_attempt_linking hpt
| batch_attempt_linking
= do
let
- home_mod_infos = moduleEnvElts hpt
+ home_mod_infos = eltsUFM hpt
-- the packages we depend on
pkg_deps = concatMap (dep_pkgs . mi_deps . hm_iface) home_mod_infos
@@ -376,9 +377,7 @@ doLink dflags stop_phase o_files
where
-- Always link in the haskell98 package for static linking. Other
-- packages have to be specified via the -package flag.
- link_pkgs
- | ExtPackage h98_id <- haskell98PackageId (pkgState dflags) = [h98_id]
- | otherwise = []
+ link_pkgs = [haskell98PackageId]
-- ---------------------------------------------------------------------------
@@ -640,7 +639,7 @@ runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _ma
case src_flavour of
ExtCoreFile -> do { -- no explicit imports in ExtCore input.
; m <- getCoreModuleName input_fn
- ; return (Nothing, mkModule m) }
+ ; return (Nothing, mkModuleName m) }
other -> do { buf <- hGetStringBuffer input_fn
; (_,_,L _ mod_name) <- getImports dflags buf input_fn
@@ -677,22 +676,6 @@ runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _ma
= location3 { ml_obj_file = ofile }
| otherwise = location3
- -- Make the ModSummary to hand to hscMain
- src_timestamp <- getModificationTime (basename `joinFileExt` suff)
- let
- unused_field = panic "runPhase:ModSummary field"
- -- Some fields are not looked at by hscMain
- mod_summary = ModSummary { ms_mod = mod_name,
- ms_hsc_src = src_flavour,
- ms_hspp_file = input_fn,
- ms_hspp_opts = dflags,
- ms_hspp_buf = hspp_buf,
- ms_location = location4,
- ms_hs_date = src_timestamp,
- ms_obj_date = Nothing,
- ms_imps = unused_field,
- ms_srcimps = unused_field }
-
o_file = ml_obj_file location4 -- The real object file
@@ -703,6 +686,8 @@ runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _ma
-- changed (which the compiler itself figures out).
-- Setting source_unchanged to False tells the compiler that M.o is out of
-- date wrt M.hs (or M.o doesn't exist) so we must recompile regardless.
+ src_timestamp <- getModificationTime (basename `joinFileExt` suff)
+
let do_recomp = dopt Opt_RecompChecking dflags
source_unchanged <-
if not do_recomp || not (isStopLn stop)
@@ -731,7 +716,22 @@ runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _ma
hsc_env <- newHscEnv dflags'
-- Tell the finder cache about this module
- addHomeModuleToFinder hsc_env mod_name location4
+ mod <- addHomeModuleToFinder hsc_env mod_name location4
+
+ -- Make the ModSummary to hand to hscMain
+ let
+ unused_field = panic "runPhase:ModSummary field"
+ -- Some fields are not looked at by hscMain
+ mod_summary = ModSummary { ms_mod = mod,
+ ms_hsc_src = src_flavour,
+ ms_hspp_file = input_fn,
+ ms_hspp_opts = dflags,
+ ms_hspp_buf = hspp_buf,
+ ms_location = location4,
+ ms_hs_date = src_timestamp,
+ ms_obj_date = Nothing,
+ ms_imps = unused_field,
+ ms_srcimps = unused_field }
-- run the compiler!
mbResult <- hscCompileOneShot hsc_env
@@ -749,7 +749,7 @@ runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _ma
return (StopLn, dflags', Just location4, o_file)
Just (HscRecomp hasStub)
-> do when hasStub $
- do stub_o <- compileStub dflags' mod_name location4
+ do stub_o <- compileStub dflags' mod location4
consIORef v_Ld_inputs stub_o
-- In the case of hs-boot files, generate a dummy .o-boot
-- stamp file for the benefit of Make
@@ -1272,12 +1272,8 @@ doMkDLL dflags o_files dep_packages = do
let extra_ld_opts = getOpts dflags opt_dll
let pstate = pkgState dflags
- rts_id | ExtPackage id <- rtsPackageId pstate = id
- | otherwise = panic "staticLink: rts package missing"
- base_id | ExtPackage id <- basePackageId pstate = id
- | otherwise = panic "staticLink: base package missing"
- rts_pkg = getPackageDetails pstate rts_id
- base_pkg = getPackageDetails pstate base_id
+ rts_pkg = getPackageDetails pstate rtsPackageId
+ base_pkg = getPackageDetails pstate basePackageId
let extra_os = if static || no_hs_main
then []
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 731ac29b49..bc6a0af300 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -49,10 +49,14 @@ module DynFlags (
#include "HsVersions.h"
-import Module ( Module, mkModule )
+import Module ( Module, mkModuleName, mkModule )
+import PackageConfig
import PrelNames ( mAIN )
-import StaticFlags ( opt_Static, opt_PIC,
- WayName(..), v_Ways, v_Build_tag, v_RTS_Build_tag )
+#ifdef i386_TARGET_ARCH
+import StaticFlags ( opt_Static )
+#endif
+import StaticFlags ( opt_PIC, WayName(..), v_Ways, v_Build_tag,
+ v_RTS_Build_tag )
import {-# SOURCE #-} Packages (PackageState)
import DriverPhases ( Phase(..), phaseInputExt )
import Config
@@ -210,6 +214,7 @@ data DynFlags = DynFlags {
importPaths :: [FilePath],
mainModIs :: Module,
mainFunIs :: Maybe String,
+ thisPackage :: PackageId,
-- ways
wayNames :: [WayName], -- way flags from the cmd line
@@ -344,6 +349,7 @@ defaultDynFlags =
importPaths = ["."],
mainModIs = mAIN,
mainFunIs = Nothing,
+ thisPackage = mainPackageId,
wayNames = panic "ways",
buildTag = panic "buildTag",
@@ -864,7 +870,7 @@ dynamic_flags = [
------- Packages ----------------------------------------------------
, ( "package-conf" , HasArg extraPkgConf_ )
, ( "no-user-package-conf", NoArg (unSetDynFlag Opt_ReadUserPackageConf) )
- , ( "package-name" , HasArg ignorePackage ) -- for compatibility
+ , ( "package-name" , HasArg setPackageName )
, ( "package" , HasArg exposePackage )
, ( "hide-package" , HasArg hidePackage )
, ( "hide-all-packages", NoArg (setDynFlag Opt_HideAllPackages) )
@@ -1073,6 +1079,13 @@ hidePackage p =
upd (\s -> s{ packageFlags = HidePackage p : packageFlags s })
ignorePackage p =
upd (\s -> s{ packageFlags = IgnorePackage p : packageFlags s })
+setPackageName p
+ | Nothing <- unpackPackageId pid
+ = throwDyn (CmdLineError ("cannot parse \'" ++ p ++ "\' as a package identifier"))
+ | otherwise
+ = upd (\s -> s{ thisPackage = pid })
+ where
+ pid = stringToPackageId p
-- we can only switch between HscC, HscAsmm, and HscILX with dynamic flags
-- (-fvia-C, -fasm, -filx respectively).
@@ -1096,10 +1109,10 @@ setMainIs :: String -> DynP ()
setMainIs arg
| not (null main_fn) -- The arg looked like "Foo.baz"
= upd $ \d -> d{ mainFunIs = Just main_fn,
- mainModIs = mkModule main_mod }
+ mainModIs = mkModule mainPackageId (mkModuleName main_mod) }
| isUpper (head main_mod) -- The arg looked like "Foo"
- = upd $ \d -> d{ mainModIs = mkModule main_mod }
+ = upd $ \d -> d{ mainModIs = mkModule mainPackageId (mkModuleName main_mod) }
| otherwise -- The arg looked like "baz"
= upd $ \d -> d{ mainFunIs = Just main_mod }
diff --git a/compiler/main/Finder.lhs b/compiler/main/Finder.lhs
index fbde40f6ea..fd0982da19 100644
--- a/compiler/main/Finder.lhs
+++ b/compiler/main/Finder.lhs
@@ -1,45 +1,47 @@
%
-% (c) The University of Glasgow, 2000
+% (c) The University of Glasgow, 2000-2006
%
\section[Finder]{Module Finder}
\begin{code}
module Finder (
- flushFinderCache, -- :: IO ()
+ flushFinderCaches,
FindResult(..),
- findModule, -- :: ModuleName -> Bool -> IO FindResult
- findPackageModule, -- :: ModuleName -> Bool -> IO FindResult
- mkHomeModLocation, -- :: ModuleName -> FilePath -> IO ModLocation
- mkHomeModLocation2, -- :: ModuleName -> FilePath -> String -> IO ModLocation
- addHomeModuleToFinder, -- :: HscEnv -> Module -> ModLocation -> IO ()
- uncacheModule, -- :: HscEnv -> Module -> IO ()
+ findImportedModule,
+ findExactModule,
+ findHomeModule,
+ mkHomeModLocation,
+ mkHomeModLocation2,
+ addHomeModuleToFinder,
+ uncacheModule,
mkStubPaths,
findObjectLinkableMaybe,
findObjectLinkable,
- cantFindError, -- :: DynFlags -> Module -> FindResult -> SDoc
+ cantFindError,
) where
#include "HsVersions.h"
import Module
-import UniqFM ( filterUFM, delFromUFM )
import HscTypes
import Packages
import FastString
import Util
+import PrelNames ( gHC_PRIM )
import DynFlags ( DynFlags(..), isOneShot, GhcMode(..) )
import Outputable
+import FiniteMap
+import UniqFM
import Maybes ( expectJust )
-import DATA_IOREF ( IORef, writeIORef, readIORef )
+import DATA_IOREF ( IORef, writeIORef, readIORef, modifyIORef )
import Data.List
import System.Directory
import System.IO
import Control.Monad
-import Data.Maybe ( isNothing )
import Time ( ClockTime )
@@ -61,137 +63,174 @@ type BaseName = String -- Basename of file
-- remove all the home modules from the cache; package modules are
-- assumed to not move around during a session.
-flushFinderCache :: IORef FinderCache -> IO ()
-flushFinderCache finder_cache = do
- fm <- readIORef finder_cache
- writeIORef finder_cache $! filterUFM (\(loc,m) -> isNothing m) fm
-
-addToFinderCache :: IORef FinderCache -> Module -> FinderCacheEntry -> IO ()
-addToFinderCache finder_cache mod_name entry = do
- fm <- readIORef finder_cache
- writeIORef finder_cache $! extendModuleEnv fm mod_name entry
-
-removeFromFinderCache :: IORef FinderCache -> Module -> IO ()
-removeFromFinderCache finder_cache mod_name = do
- fm <- readIORef finder_cache
- writeIORef finder_cache $! delFromUFM fm mod_name
-
-lookupFinderCache :: IORef FinderCache -> Module -> IO (Maybe FinderCacheEntry)
-lookupFinderCache finder_cache mod_name = do
- fm <- readIORef finder_cache
- return $! lookupModuleEnv fm mod_name
+flushFinderCaches :: HscEnv -> IO ()
+flushFinderCaches hsc_env = do
+ writeIORef fc_ref emptyUFM
+ flushModLocationCache this_pkg mlc_ref
+ where
+ this_pkg = thisPackage (hsc_dflags hsc_env)
+ fc_ref = hsc_FC hsc_env
+ mlc_ref = hsc_MLC hsc_env
+
+flushModLocationCache :: PackageId -> IORef ModLocationCache -> IO ()
+flushModLocationCache this_pkg ref = do
+ fm <- readIORef ref
+ writeIORef ref $! filterFM is_ext fm
+ return ()
+ where is_ext mod _ | modulePackageId mod /= this_pkg = True
+ | otherwise = False
+
+addToFinderCache ref key val = modifyIORef ref $ \c -> addToUFM c key val
+addToModLocationCache ref key val = modifyIORef ref $ \c -> addToFM c key val
+
+removeFromFinderCache ref key = modifyIORef ref $ \c -> delFromUFM c key
+removeFromModLocationCache ref key = modifyIORef ref $ \c -> delFromFM c key
+
+lookupFinderCache ref key = do
+ c <- readIORef ref
+ return $! lookupUFM c key
+
+lookupModLocationCache ref key = do
+ c <- readIORef ref
+ return $! lookupFM c key
-- -----------------------------------------------------------------------------
-- The two external entry points
--- This is the main interface to the finder, which maps ModuleNames to
--- Modules and ModLocations.
---
--- The Module contains one crucial bit of information about a module:
--- whether it lives in the current ("home") package or not (see Module
--- for more details).
---
--- The ModLocation contains the names of all the files associated with
--- that module: its source file, .hi file, object file, etc.
-
-data FindResult
- = Found ModLocation PackageIdH
- -- the module was found
- | FoundMultiple [PackageId]
- -- *error*: both in multiple packages
- | PackageHidden PackageId
- -- for an explicit source import: the package containing the module is
- -- not exposed.
- | ModuleHidden PackageId
- -- for an explicit source import: the package containing the module is
- -- exposed, but the module itself is hidden.
- | NotFound [FilePath]
- -- the module was not found, the specified places were searched.
-
-findModule :: HscEnv -> Module -> Bool -> IO FindResult
-findModule = findModule' True
-
-findPackageModule :: HscEnv -> Module -> Bool -> IO FindResult
-findPackageModule = findModule' False
-
-
-data LocalFindResult
- = Ok FinderCacheEntry
- | CantFindAmongst [FilePath]
- | MultiplePackages [PackageId]
-
-findModule' :: Bool -> HscEnv -> Module -> Bool -> IO FindResult
-findModule' home_allowed hsc_env name explicit
- = do -- First try the cache
- mb_entry <- lookupFinderCache cache name
- case mb_entry of
- Just old_entry -> return $! found old_entry
- Nothing -> not_cached
+-- | Locate a module that was imported by the user. We have the
+-- module's name, and possibly a package name. Without a package
+-- name, this function will use the search path and the known exposed
+-- packages to find the module, if a package is specified then only
+-- that package is searched for the module.
+
+findImportedModule :: HscEnv -> ModuleName -> Maybe PackageId -> IO FindResult
+findImportedModule hsc_env mod_name mb_pkgid =
+ case mb_pkgid of
+ Nothing -> unqual_import
+ Just pkg | pkg == this_pkg -> home_import
+ | otherwise -> pkg_import pkg
+ where
+ dflags = hsc_dflags hsc_env
+ this_pkg = thisPackage dflags
+
+ home_import = findHomeModule hsc_env mod_name
+
+ pkg_import pkg = findPackageModule hsc_env (mkModule pkg mod_name)
+ -- ToDo: this isn't quite right, the module we want
+ -- might actually be in another package, but re-exposed
+ -- ToDo: should return NotFoundInPackage if
+ -- the module isn't exposed by the package.
+
+ unqual_import = home_import
+ `orIfNotFound`
+ findExposedPackageModule hsc_env mod_name
+
+-- | Locate a specific 'Module'. The purpose of this function is to
+-- create a 'ModLocation' for a given 'Module', that is to find out
+-- where the files associated with this module live. It is used when
+-- reading the interface for a module mentioned by another interface,
+-- for example (a "system import").
+
+findExactModule :: HscEnv -> Module -> IO FindResult
+findExactModule hsc_env mod =
+ let dflags = hsc_dflags hsc_env in
+ if modulePackageId mod == thisPackage dflags
+ then findHomeModule hsc_env (moduleName mod)
+ else findPackageModule hsc_env mod
- where
- cache = hsc_FC hsc_env
- dflags = hsc_dflags hsc_env
-
- -- We've found the module, so the remaining question is
- -- whether it's visible or not
- found :: FinderCacheEntry -> FindResult
- found (loc, Nothing)
- | home_allowed = Found loc HomePackage
- | otherwise = NotFound []
- found (loc, Just (pkg, exposed_mod))
- | explicit && not exposed_mod = ModuleHidden pkg_name
- | explicit && not (exposed pkg) = PackageHidden pkg_name
- | otherwise =
- Found loc (ExtPackage (mkPackageId (package pkg)))
- where
- pkg_name = packageConfigId pkg
-
- found_new entry = do
- addToFinderCache cache name entry
- return $! found entry
-
- not_cached
- | not home_allowed = do
- j <- findPackageModule' dflags name
- case j of
- Ok entry -> found_new entry
- MultiplePackages pkgs -> return (FoundMultiple pkgs)
- CantFindAmongst paths -> return (NotFound paths)
-
- | otherwise = do
- j <- findHomeModule' dflags name
- case j of
- Ok entry -> found_new entry
- MultiplePackages pkgs -> return (FoundMultiple pkgs)
- CantFindAmongst home_files -> do
- r <- findPackageModule' dflags name
- case r of
- CantFindAmongst pkg_files ->
- return (NotFound (home_files ++ pkg_files))
- MultiplePackages pkgs ->
- return (FoundMultiple pkgs)
- Ok entry ->
- found_new entry
-
-addHomeModuleToFinder :: HscEnv -> Module -> ModLocation -> IO ()
-addHomeModuleToFinder hsc_env mod loc
- = addToFinderCache (hsc_FC hsc_env) mod (loc, Nothing)
-
-uncacheModule :: HscEnv -> Module -> IO ()
-uncacheModule hsc_env mod = removeFromFinderCache (hsc_FC hsc_env) mod
+-- -----------------------------------------------------------------------------
+-- Helpers
+
+this `orIfNotFound` or_this = do
+ res <- this
+ case res of
+ NotFound here -> do
+ res2 <- or_this
+ case res2 of
+ NotFound or_here -> return (NotFound (here ++ or_here))
+ _other -> return res2
+ _other -> return res
+
+
+homeSearchCache :: HscEnv -> ModuleName -> IO FindResult -> IO FindResult
+homeSearchCache hsc_env mod_name do_this = do
+ m <- lookupFinderCache (hsc_FC hsc_env) mod_name
+ case m of
+ Just result -> return result
+ Nothing -> do
+ result <- do_this
+ addToFinderCache (hsc_FC hsc_env) mod_name result
+ case result of
+ Found loc mod -> addToModLocationCache (hsc_MLC hsc_env) mod loc
+ _other -> return ()
+ return result
+
+findExposedPackageModule :: HscEnv -> ModuleName -> IO FindResult
+findExposedPackageModule hsc_env mod_name
+ -- not found in any package:
+ | null found = return (NotFound [])
+ -- found in just one exposed package:
+ | [(pkg_conf, _)] <- found_exposed
+ = let pkgid = mkPackageId (package pkg_conf) in
+ findPackageModule_ hsc_env (mkModule pkgid mod_name) pkg_conf
+ -- not found in any exposed package, report how it was hidden:
+ | null found_exposed, ((pkg_conf, exposed_mod):_) <- found
+ = let pkgid = mkPackageId (package pkg_conf) in
+ if not (exposed_mod)
+ then return (ModuleHidden pkgid)
+ else return (PackageHidden pkgid)
+ | otherwise
+ = return (FoundMultiple (map (mkPackageId.package.fst) found_exposed))
+ where
+ dflags = hsc_dflags hsc_env
+ found = lookupModuleInAllPackages dflags mod_name
+ found_exposed = filter is_exposed found
+ is_exposed (pkg_conf,exposed_mod) = exposed pkg_conf && exposed_mod
+
+
+modLocationCache :: HscEnv -> Module -> IO FindResult -> IO FindResult
+modLocationCache hsc_env mod do_this = do
+ mb_loc <- lookupModLocationCache mlc mod
+ case mb_loc of
+ Just loc -> return (Found loc mod)
+ Nothing -> do
+ result <- do_this
+ case result of
+ Found loc mod -> addToModLocationCache (hsc_MLC hsc_env) mod loc
+ _other -> return ()
+ return result
+ where
+ mlc = hsc_MLC hsc_env
+
+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_name (Found loc mod)
+ addToModLocationCache (hsc_MLC hsc_env) mod loc
+ return mod
+
+uncacheModule :: HscEnv -> ModuleName -> IO ()
+uncacheModule hsc_env mod = do
+ let this_pkg = thisPackage (hsc_dflags hsc_env)
+ removeFromFinderCache (hsc_FC hsc_env) mod
+ removeFromModLocationCache (hsc_MLC hsc_env) (mkModule this_pkg mod)
-- -----------------------------------------------------------------------------
-- The internal workers
-findHomeModule' :: DynFlags -> Module -> IO LocalFindResult
-findHomeModule' dflags mod = do
- let home_path = importPaths dflags
- hisuf = hiSuf dflags
+-- | Search for a module in the home package only.
+findHomeModule :: HscEnv -> ModuleName -> IO FindResult
+findHomeModule 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
- let
source_exts =
- [ ("hs", mkHomeModLocationSearched dflags mod "hs")
- , ("lhs", mkHomeModLocationSearched dflags mod "lhs")
+ [ ("hs", mkHomeModLocationSearched dflags mod_name "hs")
+ , ("lhs", mkHomeModLocationSearched dflags mod_name "lhs")
]
hi_exts = [ (hisuf, mkHiOnlyModLocation dflags hisuf)
@@ -203,31 +242,43 @@ findHomeModule' dflags mod = do
-- compilation mode we look for .hi and .hi-boot files only.
exts | isOneShot (ghcMode dflags) = hi_exts
| otherwise = source_exts
-
+ in
searchPathExts home_path mod exts
-
-findPackageModule' :: DynFlags -> Module -> IO LocalFindResult
-findPackageModule' dflags mod
- = case lookupModuleInAllPackages dflags mod of
- [] -> return (CantFindAmongst [])
- [pkg_info] -> findPackageIface dflags mod pkg_info
- many -> return (MultiplePackages (map (mkPackageId.package.fst) many))
-
-findPackageIface :: DynFlags -> Module -> (PackageConfig,Bool) -> IO LocalFindResult
-findPackageIface dflags mod pkg_info@(pkg_conf, _) = do
+
+
+-- | Search for a module in external packages only.
+findPackageModule :: HscEnv -> Module -> IO FindResult
+findPackageModule hsc_env mod = do
let
+ dflags = hsc_dflags hsc_env
+ pkg_id = modulePackageId mod
+ pkg_map = pkgIdMap (pkgState dflags)
+ --
+ case lookupPackage pkg_map pkg_id of
+ Nothing -> return (NoPackage pkg_id)
+ Just pkg_conf -> findPackageModule_ hsc_env mod pkg_conf
+
+findPackageModule_ hsc_env mod 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)
+ else
+
+ let
+ dflags = hsc_dflags hsc_env
tag = buildTag dflags
-- hi-suffix for packages depends on the build tag.
package_hisuf | null tag = "hi"
| otherwise = tag ++ "_hi"
hi_exts =
- [ (package_hisuf,
- mkPackageModLocation dflags pkg_info package_hisuf) ]
+ [ (package_hisuf, mkHiOnlyModLocation dflags package_hisuf) ]
source_exts =
- [ ("hs", mkPackageModLocation dflags pkg_info package_hisuf)
- , ("lhs", mkPackageModLocation dflags pkg_info package_hisuf)
+ [ ("hs", mkHiOnlyModLocation dflags package_hisuf)
+ , ("lhs", mkHiOnlyModLocation dflags package_hisuf)
]
-- mkdependHS needs to look for source files in packages too, so
@@ -238,7 +289,7 @@ findPackageIface dflags mod pkg_info@(pkg_conf, _) = do
| otherwise = hi_exts
-- we never look for a .hi-boot file in an external package;
-- .hi-boot files only make sense for the home package.
-
+ in
searchPathExts (importDirs pkg_conf) mod exts
-- -----------------------------------------------------------------------------
@@ -248,11 +299,11 @@ searchPathExts
:: [FilePath] -- paths to search
-> Module -- module name
-> [ (
- FileExt, -- suffix
- FilePath -> BaseName -> IO FinderCacheEntry -- action
+ FileExt, -- suffix
+ FilePath -> BaseName -> IO ModLocation -- action
)
]
- -> IO LocalFindResult
+ -> IO FindResult
searchPathExts paths mod exts
= do result <- search to_search
@@ -267,9 +318,9 @@ searchPathExts paths mod exts
return result
where
- basename = dots_to_slashes (moduleString mod)
+ basename = dots_to_slashes (moduleNameString (moduleName mod))
- to_search :: [(FilePath, IO FinderCacheEntry)]
+ to_search :: [(FilePath, IO ModLocation)]
to_search = [ (file, fn path basename)
| path <- paths,
(ext,fn) <- exts,
@@ -278,30 +329,17 @@ searchPathExts paths mod exts
file = base `joinFileExt` ext
]
- search [] = return (CantFindAmongst (map fst to_search))
+ search [] = return (NotFound (map fst to_search))
search ((file, mk_result) : rest) = do
b <- doesFileExist file
if b
- then do { res <- mk_result; return (Ok res) }
+ then do { loc <- mk_result; return (Found loc mod) }
else search rest
-mkHomeModLocationSearched :: DynFlags -> Module -> FileExt
- -> FilePath -> BaseName -> IO FinderCacheEntry
+mkHomeModLocationSearched :: DynFlags -> ModuleName -> FileExt
+ -> FilePath -> BaseName -> IO ModLocation
mkHomeModLocationSearched dflags mod suff path basename = do
- loc <- mkHomeModLocation2 dflags mod (path `joinFileName` basename) suff
- return (loc, Nothing)
-
-mkHiOnlyModLocation :: DynFlags -> FileExt -> FilePath -> BaseName
- -> IO FinderCacheEntry
-mkHiOnlyModLocation dflags hisuf path basename = do
- loc <- hiOnlyModLocation dflags path basename hisuf
- return (loc, Nothing)
-
-mkPackageModLocation :: DynFlags -> (PackageConfig, Bool) -> FileExt
- -> FilePath -> BaseName -> IO FinderCacheEntry
-mkPackageModLocation dflags pkg_info hisuf path basename = do
- loc <- hiOnlyModLocation dflags path basename hisuf
- return (loc, Just pkg_info)
+ mkHomeModLocation2 dflags mod (path `joinFileName` basename) suff
-- -----------------------------------------------------------------------------
-- Constructing a home module location
@@ -336,18 +374,18 @@ mkPackageModLocation dflags pkg_info hisuf path basename = do
-- ext
-- The filename extension of the source file (usually "hs" or "lhs").
-mkHomeModLocation :: DynFlags -> Module -> FilePath -> IO ModLocation
+mkHomeModLocation :: DynFlags -> ModuleName -> FilePath -> IO ModLocation
mkHomeModLocation dflags mod src_filename = do
let (basename,extension) = splitFilename src_filename
mkHomeModLocation2 dflags mod basename extension
mkHomeModLocation2 :: DynFlags
- -> Module
+ -> ModuleName
-> FilePath -- Of source module, without suffix
-> String -- Suffix
-> IO ModLocation
mkHomeModLocation2 dflags mod src_basename ext = do
- let mod_basename = dots_to_slashes (moduleString mod)
+ let mod_basename = dots_to_slashes (moduleNameString mod)
obj_fn <- mkObjPath dflags src_basename mod_basename
hi_fn <- mkHiPath dflags src_basename mod_basename
@@ -356,8 +394,9 @@ mkHomeModLocation2 dflags mod src_basename ext = do
ml_hi_file = hi_fn,
ml_obj_file = obj_fn })
-hiOnlyModLocation :: DynFlags -> FilePath -> String -> Suffix -> IO ModLocation
-hiOnlyModLocation dflags path basename hisuf
+mkHiOnlyModLocation :: DynFlags -> Suffix -> FilePath -> String
+ -> IO ModLocation
+mkHiOnlyModLocation dflags hisuf path basename
= do let full_basename = path `joinFileName` basename
obj_fn <- mkObjPath dflags full_basename basename
return ModLocation{ ml_hs_file = Nothing,
@@ -412,7 +451,7 @@ mkHiPath dflags basename mod_basename
mkStubPaths
:: DynFlags
- -> Module
+ -> ModuleName
-> ModLocation
-> (FilePath,FilePath)
@@ -420,7 +459,7 @@ mkStubPaths dflags mod location
= let
stubdir = stubDir dflags
- mod_basename = dots_to_slashes (moduleString mod)
+ mod_basename = dots_to_slashes (moduleNameString mod)
src_basename = basenameOf (expectJust "mkStubPaths"
(ml_hs_file location))
@@ -466,7 +505,7 @@ dots_to_slashes = map (\c -> if c == '.' then '/' else c)
-- -----------------------------------------------------------------------------
-- Error messages
-cantFindError :: DynFlags -> Module -> FindResult -> SDoc
+cantFindError :: DynFlags -> ModuleName -> FindResult -> SDoc
cantFindError dflags mod_name (FoundMultiple pkgs)
= hang (ptext SLIT("Cannot import") <+> quotes (ppr mod_name) <> colon) 2 (
sep [ptext SLIT("it was found in multiple packages:"),
@@ -486,6 +525,10 @@ cantFindError dflags mod_name find_result
-> ptext SLIT("it is hidden") <+> parens (ptext SLIT("in package")
<+> ppr pkg)
+ NoPackage pkg
+ -> ptext SLIT("no package matching") <+> ppr pkg <+>
+ ptext SLIT("was found")
+
NotFound files
| null files
-> ptext SLIT("it is not a module in the current program, or in any known package.")
@@ -495,5 +538,8 @@ cantFindError dflags mod_name find_result
-> hang (ptext SLIT("locations searched:"))
2 (vcat (map text files))
+ NotFoundInPackage pkg
+ -> ptext SLIT("it is not in package") <+> ppr pkg
+
_ -> panic "cantFindErr"
\end{code}
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs
index 5f82cf3fdb..543d2a940d 100644
--- a/compiler/main/GHC.hs
+++ b/compiler/main/GHC.hs
@@ -43,7 +43,7 @@ module GHC (
TypecheckedSource, ParsedSource, RenamedSource,
-- * Inspecting the module structure of the program
- ModuleGraph, ModSummary(..), ModLocation(..),
+ ModuleGraph, ModSummary(..), ms_mod_name, ModLocation(..),
getModuleGraph,
isLoaded,
topSortModuleGraph,
@@ -65,6 +65,7 @@ module GHC (
-- * Interactive evaluation
getBindings, getPrintUnqual,
+ findModule,
#ifdef GHCI
setContext, getContext,
getNamesInScope,
@@ -83,8 +84,12 @@ module GHC (
-- * Abstract syntax elements
+ -- ** Packages
+ PackageId,
+
-- ** Modules
- Module, mkModule, pprModule,
+ Module, mkModule, pprModule, moduleName, modulePackageId,
+ ModuleName, mkModuleName, moduleNameString,
-- ** Names
Name,
@@ -177,6 +182,7 @@ import RdrName ( plusGlobalRdrEnv, Provenance(..),
ImportSpec(..), ImpDeclSpec(..), ImpItemSpec(..),
mkGlobalRdrEnv )
import HscMain ( hscParseIdentifier, hscStmt, hscTcExpr, hscKcType )
+import Name ( nameOccName )
import Type ( tidyType )
import VarEnv ( emptyTidyEnv )
import GHC.Exts ( unsafeCoerce# )
@@ -208,7 +214,7 @@ import DataCon ( DataCon, dataConWrapId, dataConSig, dataConTyCon,
dataConFieldLabels, dataConStrictMarks,
dataConIsInfix, isVanillaDataCon )
import Name ( Name, nameModule, NamedThing(..), nameParent_maybe,
- nameSrcLoc, nameOccName )
+ nameSrcLoc )
import OccName ( parenSymOcc )
import NameEnv ( nameEnvElts )
import InstEnv ( Instance, instanceDFunId, pprInstance, pprInstanceHdr )
@@ -216,19 +222,20 @@ import SrcLoc
import DriverPipeline
import DriverPhases ( Phase(..), isHaskellSrcFilename, startPhase )
import HeaderInfo ( getImports, getOptions )
-import Packages ( isHomePackage )
import Finder
import HscMain ( newHscEnv, hscFileCheck, HscChecked(..) )
import HscTypes
import DynFlags
import SysTools ( initSysTools, cleanTempFiles )
import Module
+import UniqFM
+import PackageConfig ( PackageId )
import FiniteMap
import Panic
import Digraph
import Bag ( unitBag )
import ErrUtils ( Severity(..), showPass, fatalErrorMsg, debugTraceMsg,
- mkPlainErrMsg, printBagOfErrors, printErrorsAndWarnings )
+ mkPlainErrMsg, printBagOfErrors )
import qualified ErrUtils
import Util
import StringBuffer ( StringBuffer, hGetStringBuffer )
@@ -448,7 +455,7 @@ guessTarget file Nothing
if exists
then return (Target (TargetFile lhs_file Nothing) Nothing)
else do
- return (Target (TargetModule (mkModule file)) Nothing)
+ return (Target (TargetModule (mkModuleName file)) Nothing)
where
hs_file = file `joinFileExt` "hs"
lhs_file = file `joinFileExt` "lhs"
@@ -483,7 +490,7 @@ setGlobalTypeScope session ids
-- Perform a dependency analysis starting from the current targets
-- and update the session with the new module graph.
-depanal :: Session -> [Module] -> Bool -> IO (Maybe ModuleGraph)
+depanal :: Session -> [ModuleName] -> Bool -> IO (Maybe ModuleGraph)
depanal (Session ref) excluded_mods allow_dup_roots = do
hsc_env <- readIORef ref
let
@@ -522,8 +529,8 @@ data ErrMsg = ErrMsg {
data LoadHowMuch
= LoadAllTargets
- | LoadUpTo Module
- | LoadDependenciesOf Module
+ | LoadUpTo ModuleName
+ | LoadDependenciesOf ModuleName
-- | Try to load the program. If a Module is supplied, then just
-- attempt to load up to this target. If no Module is supplied,
@@ -552,10 +559,11 @@ load2 s@(Session ref) how_much mod_graph = do
-- B.hs-boot in the module graph, but no B.hs
-- The downsweep should have ensured this does not happen
-- (see msDeps)
- let all_home_mods = [ms_mod s | s <- mod_graph, not (isBootSummary s)]
+ let all_home_mods = [ms_mod_name s
+ | s <- mod_graph, not (isBootSummary s)]
#ifdef DEBUG
bad_boot_mods = [s | s <- mod_graph, isBootSummary s,
- not (ms_mod s `elem` all_home_mods)]
+ not (ms_mod_name s `elem` all_home_mods)]
#endif
ASSERT( null bad_boot_mods ) return ()
@@ -586,7 +594,7 @@ load2 s@(Session ref) how_much mod_graph = do
-- Unload any modules which are going to be re-linked this time around.
let stable_linkables = [ linkable
| m <- stable_obj++stable_bco,
- Just hmi <- [lookupModuleEnv pruned_hpt m],
+ Just hmi <- [lookupUFM pruned_hpt m],
Just linkable <- [hm_linkable hmi] ]
unload hsc_env stable_linkables
@@ -623,7 +631,7 @@ load2 s@(Session ref) how_much mod_graph = do
partial_mg
| LoadDependenciesOf mod <- how_much
= ASSERT( case last partial_mg0 of
- AcyclicSCC ms -> ms_mod ms == mod; _ -> False )
+ AcyclicSCC ms -> ms_mod_name ms == mod; _ -> False )
List.init partial_mg0
| otherwise
= partial_mg0
@@ -631,9 +639,9 @@ load2 s@(Session ref) how_much mod_graph = do
stable_mg =
[ AcyclicSCC ms
| AcyclicSCC ms <- full_mg,
- ms_mod ms `elem` stable_obj++stable_bco,
- ms_mod ms `notElem` [ ms_mod ms' |
- AcyclicSCC ms' <- partial_mg ] ]
+ ms_mod_name ms `elem` stable_obj++stable_bco,
+ ms_mod_name ms `notElem` [ ms_mod_name ms' |
+ AcyclicSCC ms' <- partial_mg ] ]
mg = stable_mg ++ partial_mg
@@ -679,7 +687,7 @@ load2 s@(Session ref) how_much mod_graph = do
when (ghci_mode == BatchCompile && isJust ofile && not do_linking) $
debugTraceMsg dflags 1 (text ("Warning: output was redirected with -o, " ++
"but no output will be generated\n" ++
- "because there is no " ++ moduleString main_mod ++ " module."))
+ "because there is no " ++ moduleNameString (moduleName main_mod) ++ " module."))
-- link everything together
linkresult <- link ghci_mode dflags do_linking (hsc_HPT hsc_env1)
@@ -701,7 +709,7 @@ load2 s@(Session ref) how_much mod_graph = do
= filter ((`notElem` mods_to_zap_names).ms_mod)
modsDone
- let hpt4 = retainInTopLevelEnvs (map ms_mod mods_to_keep)
+ let hpt4 = retainInTopLevelEnvs (map ms_mod_name mods_to_keep)
(hsc_HPT hsc_env1)
-- Clean up after ourselves
@@ -709,7 +717,7 @@ load2 s@(Session ref) how_much mod_graph = do
-- there should be no Nothings where linkables should be, now
ASSERT(all (isJust.hm_linkable)
- (moduleEnvElts (hsc_HPT hsc_env))) do
+ (eltsUFM (hsc_HPT hsc_env))) do
-- Link everything together
linkresult <- link ghci_mode dflags False hpt4
@@ -780,7 +788,7 @@ type TypecheckedSource = LHsBinds Id
-- for a module. 'checkModule' loads all the dependencies of the specified
-- module in the Session, and then attempts to typecheck the module. If
-- successful, it returns the abstract syntax for the module.
-checkModule :: Session -> Module -> IO (Maybe CheckedModule)
+checkModule :: Session -> ModuleName -> IO (Maybe CheckedModule)
checkModule session@(Session ref) mod = do
-- load up the dependencies first
r <- load session (LoadDependenciesOf mod)
@@ -789,7 +797,7 @@ checkModule session@(Session ref) mod = do
-- now parse & typecheck the module
hsc_env <- readIORef ref
let mg = hsc_mod_graph hsc_env
- case [ ms | ms <- mg, ms_mod ms == mod ] of
+ case [ ms | ms <- mg, ms_mod_name ms == mod ] of
[] -> return Nothing
(ms:_) -> do
mbChecked <- hscFileCheck hsc_env{hsc_dflags=ms_hspp_opts ms} ms
@@ -885,9 +893,9 @@ unload hsc_env stable_linkables -- Unload everthing *except* 'stable_linkables'
checkStability
:: HomePackageTable -- HPT from last compilation
-> [SCC ModSummary] -- current module graph (cyclic)
- -> [Module] -- all home modules
- -> ([Module], -- stableObject
- [Module]) -- stableBCO
+ -> [ModuleName] -- all home modules
+ -> ([ModuleName], -- stableObject
+ [ModuleName]) -- stableBCO
checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
where
@@ -897,7 +905,7 @@ checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
| otherwise = (stable_obj, stable_bco)
where
scc = flattenSCC scc0
- scc_mods = map ms_mod scc
+ scc_mods = map ms_mod_name scc
home_module m = m `elem` all_home_mods && m `notElem` scc_mods
scc_allimps = nub (filter home_module (concatMap ms_allimps scc))
@@ -919,7 +927,7 @@ checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
&& same_as_prev t
| otherwise = False
where
- same_as_prev t = case lookupModuleEnv hpt (ms_mod ms) of
+ same_as_prev t = case lookupUFM hpt (ms_mod_name ms) of
Just hmi | Just l <- hm_linkable hmi
-> isObjectLinkable l && t == linkableTime l
_other -> True
@@ -931,13 +939,13 @@ checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
-- make's behaviour.
bco_ok ms
- = case lookupModuleEnv hpt (ms_mod ms) of
+ = case lookupUFM hpt (ms_mod_name ms) of
Just hmi | Just l <- hm_linkable hmi ->
not (isObjectLinkable l) &&
linkableTime l >= ms_hs_date ms
_other -> False
-ms_allimps :: ModSummary -> [Module]
+ms_allimps :: ModSummary -> [ModuleName]
ms_allimps ms = map unLoc (ms_srcimps ms ++ ms_imps ms)
-- -----------------------------------------------------------------------------
@@ -958,23 +966,23 @@ ms_allimps ms = map unLoc (ms_srcimps ms ++ ms_imps ms)
pruneHomePackageTable
:: HomePackageTable
-> [ModSummary]
- -> ([Module],[Module])
+ -> ([ModuleName],[ModuleName])
-> HomePackageTable
pruneHomePackageTable hpt summ (stable_obj, stable_bco)
- = mapModuleEnv prune hpt
+ = mapUFM prune hpt
where prune hmi
| is_stable modl = hmi'
| otherwise = hmi'{ hm_details = emptyModDetails }
where
- modl = mi_module (hm_iface hmi)
+ modl = moduleName (mi_module (hm_iface hmi))
hmi' | Just l <- hm_linkable hmi, linkableTime l < ms_hs_date ms
= hmi{ hm_linkable = Nothing }
| otherwise
= hmi
- where ms = expectJust "prune" (lookupModuleEnv ms_map modl)
+ where ms = expectJust "prune" (lookupUFM ms_map modl)
- ms_map = mkModuleEnv [(ms_mod ms, ms) | ms <- summ]
+ ms_map = listToUFM [(ms_mod_name ms, ms) | ms <- summ]
is_stable m = m `elem` stable_obj || m `elem` stable_bco
@@ -1011,7 +1019,7 @@ findPartiallyCompletedCycles modsDone theGraph
upsweep
:: HscEnv -- Includes initially-empty HPT
-> HomePackageTable -- HPT from last time round (pruned)
- -> ([Module],[Module]) -- stable modules (see checkStability)
+ -> ([ModuleName],[ModuleName]) -- stable modules (see checkStability)
-> IO () -- How to clean up unwanted tmp files
-> [SCC ModSummary] -- Mods to do (the worklist)
-> IO (SuccessFlag,
@@ -1044,11 +1052,10 @@ upsweep' hsc_env old_hpt stable_mods cleanup
case mb_mod_info of
Nothing -> return (Failed, hsc_env, [])
Just mod_info -> do
- { let this_mod = ms_mod mod
+ { let this_mod = ms_mod_name mod
-- Add new info to hsc_env
- hpt1 = extendModuleEnv (hsc_HPT hsc_env)
- this_mod mod_info
+ hpt1 = addToUFM (hsc_HPT hsc_env) this_mod mod_info
hsc_env1 = hsc_env { hsc_HPT = hpt1 }
-- Space-saving: delete the old HPT entry
@@ -1058,7 +1065,7 @@ upsweep' hsc_env old_hpt stable_mods cleanup
-- main Haskell source file. Deleting it
-- would force .. (what?? --SDM)
old_hpt1 | isBootSummary mod = old_hpt
- | otherwise = delModuleEnv old_hpt this_mod
+ | otherwise = delFromUFM old_hpt this_mod
; (restOK, hsc_env2, modOKs)
<- upsweep' hsc_env1 old_hpt1 stable_mods cleanup
@@ -1071,7 +1078,7 @@ upsweep' hsc_env old_hpt stable_mods cleanup
-- successful. If no compilation happened, return the old Linkable.
upsweep_mod :: HscEnv
-> HomePackageTable
- -> ([Module],[Module])
+ -> ([ModuleName],[ModuleName])
-> ModSummary
-> Int -- index of module
-> Int -- total number of modules
@@ -1080,13 +1087,14 @@ upsweep_mod :: HscEnv
upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
= do
let
+ this_mod_name = ms_mod_name summary
this_mod = ms_mod summary
mb_obj_date = ms_obj_date summary
obj_fn = ml_obj_file (ms_location summary)
hs_date = ms_hs_date summary
compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
- compile_it = upsweep_compile hsc_env old_hpt this_mod
+ compile_it = upsweep_compile hsc_env old_hpt this_mod_name
summary mod_index nmods
case ghcMode (hsc_dflags hsc_env) of
@@ -1134,10 +1142,10 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
compile_it Nothing
-- no existing code at all: we must recompile.
where
- is_stable_obj = this_mod `elem` stable_obj
- is_stable_bco = this_mod `elem` stable_bco
+ is_stable_obj = this_mod_name `elem` stable_obj
+ is_stable_bco = this_mod_name `elem` stable_bco
- old_hmi = lookupModuleEnv old_hpt this_mod
+ old_hmi = lookupUFM old_hpt this_mod_name
-- Run hsc to compile a module
upsweep_compile hsc_env old_hpt this_mod summary
@@ -1154,7 +1162,7 @@ upsweep_compile hsc_env old_hpt this_mod summary
-- will always be recompiled
mb_old_iface
- = case lookupModuleEnv old_hpt this_mod of
+ = case lookupUFM old_hpt this_mod of
Nothing -> Nothing
Just hm_info | isBootSummary summary -> Just iface
| not (mi_boot iface) -> Just iface
@@ -1180,11 +1188,11 @@ upsweep_compile hsc_env old_hpt this_mod summary
-- Filter modules in the HPT
-retainInTopLevelEnvs :: [Module] -> HomePackageTable -> HomePackageTable
+retainInTopLevelEnvs :: [ModuleName] -> HomePackageTable -> HomePackageTable
retainInTopLevelEnvs keep_these hpt
- = mkModuleEnv [ (mod, expectJust "retain" mb_mod_info)
+ = listToUFM [ (mod, expectJust "retain" mb_mod_info)
| mod <- keep_these
- , let mb_mod_info = lookupModuleEnv hpt mod
+ , let mb_mod_info = lookupUFM hpt mod
, isJust mb_mod_info ]
-- ---------------------------------------------------------------------------
@@ -1193,7 +1201,7 @@ retainInTopLevelEnvs keep_these hpt
topSortModuleGraph
:: Bool -- Drop hi-boot nodes? (see below)
-> [ModSummary]
- -> Maybe Module
+ -> Maybe ModuleName
-> [SCC ModSummary]
-- Calculate SCCs of the module graph, possibly dropping the hi-boot nodes
-- The resulting list of strongly-connected-components is in topologically
@@ -1226,7 +1234,7 @@ topSortModuleGraph drop_hs_boot_nodes summaries (Just mod)
| otherwise = throwDyn (ProgramError "module does not exist")
moduleGraphNodes :: Bool -> [ModSummary]
- -> ([(ModSummary, Int, [Int])], HscSource -> Module -> Maybe Int)
+ -> ([(ModSummary, Int, [Int])], HscSource -> ModuleName -> Maybe Int)
moduleGraphNodes drop_hs_boot_nodes summaries = (nodes, lookup_key)
where
-- Drop hs-boot nodes by using HsSrcFile as the key
@@ -1235,7 +1243,7 @@ moduleGraphNodes drop_hs_boot_nodes summaries = (nodes, lookup_key)
-- We use integers as the keys for the SCC algorithm
nodes :: [(ModSummary, Int, [Int])]
- nodes = [(s, expectJust "topSort" (lookup_key (ms_hsc_src s) (ms_mod s)),
+ nodes = [(s, expectJust "topSort" (lookup_key (ms_hsc_src s) (ms_mod_name s)),
out_edge_keys hs_boot_key (map unLoc (ms_srcimps s)) ++
out_edge_keys HsSrcFile (map unLoc (ms_imps s)) )
| s <- summaries
@@ -1243,23 +1251,24 @@ moduleGraphNodes drop_hs_boot_nodes summaries = (nodes, lookup_key)
-- Drop the hi-boot ones if told to do so
key_map :: NodeMap Int
- key_map = listToFM ([(ms_mod s, ms_hsc_src s) | s <- summaries]
+ key_map = listToFM ([(moduleName (ms_mod s), ms_hsc_src s)
+ | s <- summaries]
`zip` [1..])
- lookup_key :: HscSource -> Module -> Maybe Int
+ lookup_key :: HscSource -> ModuleName -> Maybe Int
lookup_key hs_src mod = lookupFM key_map (mod, hs_src)
- out_edge_keys :: HscSource -> [Module] -> [Int]
+ out_edge_keys :: HscSource -> [ModuleName] -> [Int]
out_edge_keys hi_boot ms = mapCatMaybes (lookup_key hi_boot) ms
-- If we want keep_hi_boot_nodes, then we do lookup_key with
-- the IsBootInterface parameter True; else False
-type NodeKey = (Module, HscSource) -- The nodes of the graph are
+type NodeKey = (ModuleName, HscSource) -- The nodes of the graph are
type NodeMap a = FiniteMap NodeKey a -- keyed by (mod, src_file_type) pairs
msKey :: ModSummary -> NodeKey
-msKey (ModSummary { ms_mod = mod, ms_hsc_src = boot }) = (mod,boot)
+msKey (ModSummary { ms_mod = mod, ms_hsc_src = boot }) = (moduleName mod,boot)
mkNodeMap :: [ModSummary] -> NodeMap ModSummary
mkNodeMap summaries = listToFM [ (msKey s, s) | s <- summaries]
@@ -1267,6 +1276,9 @@ mkNodeMap summaries = listToFM [ (msKey s, s) | s <- summaries]
nodeMapElts :: NodeMap a -> [a]
nodeMapElts = eltsFM
+ms_mod_name :: ModSummary -> ModuleName
+ms_mod_name = moduleName . ms_mod
+
-----------------------------------------------------------------------------
-- Downsweep (dependency analysis)
@@ -1284,7 +1296,7 @@ nodeMapElts = eltsFM
downsweep :: HscEnv
-> [ModSummary] -- Old summaries
- -> [Module] -- Ignore dependencies on these; treat
+ -> [ModuleName] -- Ignore dependencies on these; treat
-- them as if they were package modules
-> Bool -- True <=> allow multiple targets to have
-- the same module name; this is
@@ -1336,7 +1348,7 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots
dup_roots :: [[ModSummary]] -- Each at least of length 2
dup_roots = filterOut isSingleton (nodeMapElts root_map)
- loop :: [(Located Module,IsBootInterface)]
+ loop :: [(Located ModuleName,IsBootInterface)]
-- Work list: process these modules
-> NodeMap [ModSummary]
-- Visited set; the range is a list because
@@ -1365,7 +1377,7 @@ mkRootMap :: [ModSummary] -> NodeMap [ModSummary]
mkRootMap summaries = addListToFM_C (++) emptyFM
[ (msKey s, [s]) | s <- summaries ]
-msDeps :: ModSummary -> [(Located Module, IsBootInterface)]
+msDeps :: ModSummary -> [(Located ModuleName, IsBootInterface)]
-- (msDeps s) returns the dependencies of the ModSummary s.
-- A wrinkle is that for a {-# SOURCE #-} import we return
-- *both* the hs-boot file
@@ -1432,14 +1444,14 @@ summariseFile hsc_env old_summaries file mb_phase maybe_buf
(dflags', hspp_fn, buf)
<- preprocessFile dflags file mb_phase maybe_buf
- (srcimps,the_imps, L _ mod) <- getImports dflags' buf hspp_fn
+ (srcimps,the_imps, L _ mod_name) <- getImports dflags' buf hspp_fn
-- Make a ModLocation for this file
- location <- mkHomeModLocation dflags mod file
+ location <- mkHomeModLocation dflags mod_name file
-- Tell the Finder cache where it is, so that subsequent calls
-- to findModule will find it, even if it's not on any search path
- addHomeModuleToFinder hsc_env mod location
+ mod <- addHomeModuleToFinder hsc_env mod_name location
src_timestamp <- case maybe_buf of
Just (_,t) -> return t
@@ -1469,9 +1481,9 @@ summariseModule
:: HscEnv
-> NodeMap ModSummary -- Map of old summaries
-> IsBootInterface -- True <=> a {-# SOURCE #-} import
- -> Located Module -- Imported module to be summarised
+ -> Located ModuleName -- Imported module to be summarised
-> Maybe (StringBuffer, ClockTime)
- -> [Module] -- Modules to exclude
+ -> [ModuleName] -- Modules to exclude
-> IO (Maybe ModSummary) -- Its new summary
summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf excl_mods
@@ -1508,9 +1520,8 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
obj_timestamp <- getObjTimestamp location is_boot
return (Just old_summary{ ms_obj_date = obj_timestamp })
| otherwise =
- -- source changed: find and re-summarise. We call the finder
- -- again, because the user may have moved the source file.
- new_summary location src_fn src_timestamp
+ -- source changed: re-summarise.
+ new_summary location (ms_mod old_summary) src_fn src_timestamp
find_it = do
-- Don't use the Finder's cache this time. If the module was
@@ -1518,17 +1529,22 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
-- search path, so we want to consider it to be a home module. If
-- the module was previously a home module, it may have moved.
uncacheModule hsc_env wanted_mod
- found <- findModule hsc_env wanted_mod True {-explicit-}
+ found <- findImportedModule hsc_env wanted_mod Nothing
case found of
- Found location pkg
- | not (isHomePackage pkg) -> return Nothing
- -- Drop external-pkg
- | isJust (ml_hs_file location) -> just_found location
+ Found location mod
+ | isJust (ml_hs_file location) ->
-- Home package
+ just_found location mod
+ | otherwise ->
+ -- Drop external-pkg
+ ASSERT(modulePackageId mod /= thisPackage dflags)
+ return Nothing
+ where
+
err -> noModError dflags loc wanted_mod err
-- Not found
- just_found location = do
+ just_found location mod = do
-- Adjust location to point to the hs-boot source file,
-- hi file, object file, when is_boot says so
let location' | is_boot = addBootSuffixLocn location
@@ -1540,10 +1556,10 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
maybe_t <- modificationTimeIfExists src_fn
case maybe_t of
Nothing -> noHsFileErr loc src_fn
- Just t -> new_summary location' src_fn t
+ Just t -> new_summary location' mod src_fn t
- new_summary location src_fn src_timestamp
+ new_summary location mod src_fn src_timestamp
= do
-- Preprocess the source file and get its imports
-- The dflags' contains the OPTIONS pragmas
@@ -1558,7 +1574,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
-- Find the object timestamp, and return the summary
obj_timestamp <- getObjTimestamp location is_boot
- return (Just ( ModSummary { ms_mod = wanted_mod,
+ return (Just ( ModSummary { ms_mod = mod,
ms_hsc_src = hsc_src,
ms_location = location,
ms_hspp_file = hspp_fn,
@@ -1610,7 +1626,7 @@ preprocessFile dflags src_fn mb_phase (Just (buf, time))
-- Error messages
-----------------------------------------------------------------------------
-noModError :: DynFlags -> SrcSpan -> Module -> FindResult -> IO ab
+noModError :: DynFlags -> SrcSpan -> ModuleName -> FindResult -> IO ab
-- ToDo: we don't have a proper line number for this error
noModError dflags loc wanted_mod err
= throwDyn $ mkPlainErrMsg loc $ cantFindError dflags wanted_mod err
@@ -1650,8 +1666,7 @@ cyclicModuleErr ms
-- Note: if you change the working directory, you should also unload
-- the current program (set targets to empty, followed by load).
workingDirectoryChanged :: Session -> IO ()
-workingDirectoryChanged s = withSession s $ \hsc_env ->
- flushFinderCache (hsc_FC hsc_env)
+workingDirectoryChanged s = withSession s $ flushFinderCaches
-- -----------------------------------------------------------------------------
-- inspecting the session
@@ -1660,9 +1675,9 @@ workingDirectoryChanged s = withSession s $ \hsc_env ->
getModuleGraph :: Session -> IO ModuleGraph -- ToDo: DiGraph ModSummary
getModuleGraph s = withSession s (return . hsc_mod_graph)
-isLoaded :: Session -> Module -> IO Bool
+isLoaded :: Session -> ModuleName -> IO Bool
isLoaded s m = withSession s $ \hsc_env ->
- return $! isJust (lookupModuleEnv (hsc_HPT hsc_env) m)
+ return $! isJust (lookupUFM (hsc_HPT hsc_env) m)
getBindings :: Session -> IO [TyThing]
getBindings s = withSession s (return . nameEnvElts . ic_type_env . hsc_IC)
@@ -1686,7 +1701,7 @@ getModuleInfo :: Session -> Module -> IO (Maybe ModuleInfo)
getModuleInfo s mdl = withSession s $ \hsc_env -> do
let mg = hsc_mod_graph hsc_env
if mdl `elem` map ms_mod mg
- then getHomeModuleInfo hsc_env mdl
+ then getHomeModuleInfo hsc_env (moduleName mdl)
else do
{- if isHomeModule (hsc_dflags hsc_env) mdl
then return Nothing
@@ -1713,7 +1728,7 @@ getPackageModuleInfo hsc_env mdl = do
return (Just (ModuleInfo {
minf_type_env = mkTypeEnv tys,
minf_exports = names,
- minf_rdr_env = Just $! nameSetToGlobalRdrEnv names mdl,
+ minf_rdr_env = Just $! nameSetToGlobalRdrEnv names (moduleName mdl),
minf_instances = error "getModuleInfo: instances for package module unimplemented"
}))
#else
@@ -1722,7 +1737,7 @@ getPackageModuleInfo hsc_env mdl = do
#endif
getHomeModuleInfo hsc_env mdl =
- case lookupModuleEnv (hsc_HPT hsc_env) mdl of
+ case lookupUFM (hsc_HPT hsc_env) mdl of
Nothing -> return Nothing
Just hmi -> do
let details = hm_details hmi
@@ -1753,7 +1768,7 @@ modInfoIsExportedName :: ModuleInfo -> Name -> Bool
modInfoIsExportedName minf name = elemNameSet name (minf_exports minf)
modInfoPrintUnqualified :: ModuleInfo -> Maybe PrintUnqualified
-modInfoPrintUnqualified minf = fmap unQualInScope (minf_rdr_env minf)
+modInfoPrintUnqualified minf = fmap mkPrintUnqualified (minf_rdr_env minf)
modInfoLookupName :: Session -> ModuleInfo -> Name -> IO (Maybe TyThing)
modInfoLookupName s minf name = withSession s $ \hsc_env -> do
@@ -1761,7 +1776,8 @@ modInfoLookupName s minf name = withSession s $ \hsc_env -> do
Just tyThing -> return (Just tyThing)
Nothing -> do
eps <- readIORef (hsc_EPS hsc_env)
- return $! lookupType (hsc_HPT hsc_env) (eps_PTE eps) name
+ return $! lookupType (hsc_dflags hsc_env)
+ (hsc_HPT hsc_env) (eps_PTE eps) name
isDictonaryId :: Id -> Bool
isDictonaryId id
@@ -1774,7 +1790,8 @@ isDictonaryId id
lookupGlobalName :: Session -> Name -> IO (Maybe TyThing)
lookupGlobalName s name = withSession s $ \hsc_env -> do
eps <- readIORef (hsc_EPS hsc_env)
- return $! lookupType (hsc_HPT hsc_env) (eps_PTE eps) name
+ return $! lookupType (hsc_dflags hsc_env)
+ (hsc_HPT hsc_env) (eps_PTE eps) name
-- -----------------------------------------------------------------------------
-- Misc exported utils
@@ -1811,6 +1828,29 @@ getTokenStream :: Session -> Module -> IO [Located Token]
-- -----------------------------------------------------------------------------
-- Interactive evaluation
+-- | Takes a 'ModuleName' and possibly a 'PackageId', and consults the
+-- filesystem and package database to find the corresponding 'Module',
+-- using the algorithm that is used for an @import@ declaration.
+findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module
+findModule s mod_name maybe_pkg = withSession s $ \hsc_env ->
+ findModule' hsc_env mod_name maybe_pkg
+
+findModule' hsc_env mod_name maybe_pkg =
+ let
+ dflags = hsc_dflags hsc_env
+ hpt = hsc_HPT hsc_env
+ this_pkg = thisPackage dflags
+ in
+ case lookupUFM hpt mod_name of
+ Just mod_info -> return (mi_module (hm_iface mod_info))
+ _not_a_home_module -> do
+ res <- findImportedModule hsc_env mod_name Nothing
+ case res of
+ Found _ m | modulePackageId m /= this_pkg -> return m
+ -- not allowed to be a home module
+ err -> let msg = cantFindError dflags mod_name err in
+ throwDyn (CmdLineError (showSDoc msg))
+
#ifdef GHCI
-- | Set the interactive evaluation context.
@@ -1822,17 +1862,16 @@ setContext :: Session
-> [Module] -- entire top level scope of these modules
-> [Module] -- exports only of these modules
-> IO ()
-setContext (Session ref) toplevs exports = do
+setContext (Session ref) toplev_mods export_mods = do
hsc_env <- readIORef ref
let old_ic = hsc_IC hsc_env
hpt = hsc_HPT hsc_env
-
- mapM_ (checkModuleExists hsc_env hpt) exports
- export_env <- mkExportEnv hsc_env exports
- toplev_envs <- mapM (mkTopLevEnv hpt) toplevs
+ --
+ export_env <- mkExportEnv hsc_env export_mods
+ toplev_envs <- mapM (mkTopLevEnv hpt) toplev_mods
let all_env = foldr plusGlobalRdrEnv export_env toplev_envs
- writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplevs,
- ic_exports = exports,
+ writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplev_mods,
+ ic_exports = export_mods,
ic_rn_gbl_env = all_env }}
@@ -1842,47 +1881,35 @@ mkExportEnv hsc_env mods = do
stuff <- mapM (getModuleExports hsc_env) mods
let
(_msgs, mb_name_sets) = unzip stuff
- gres = [ nameSetToGlobalRdrEnv name_set mod
+ gres = [ nameSetToGlobalRdrEnv name_set (moduleName mod)
| (Just name_set, mod) <- zip mb_name_sets mods ]
--
return $! foldr plusGlobalRdrEnv emptyGlobalRdrEnv gres
-nameSetToGlobalRdrEnv :: NameSet -> Module -> GlobalRdrEnv
+nameSetToGlobalRdrEnv :: NameSet -> ModuleName -> GlobalRdrEnv
nameSetToGlobalRdrEnv names mod =
mkGlobalRdrEnv [ GRE { gre_name = name, gre_prov = vanillaProv mod }
| name <- nameSetToList names ]
-vanillaProv :: Module -> Provenance
+vanillaProv :: ModuleName -> Provenance
-- We're building a GlobalRdrEnv as if the user imported
-- all the specified modules into the global interactive module
-vanillaProv mod = Imported [ImpSpec { is_decl = decl, is_item = ImpAll}]
+vanillaProv mod_name = Imported [ImpSpec { is_decl = decl, is_item = ImpAll}]
where
- decl = ImpDeclSpec { is_mod = mod, is_as = mod,
+ decl = ImpDeclSpec { is_mod = mod_name, is_as = mod_name,
is_qual = False,
is_dloc = srcLocSpan interactiveSrcLoc }
-checkModuleExists :: HscEnv -> HomePackageTable -> Module -> IO ()
-checkModuleExists hsc_env hpt mod =
- case lookupModuleEnv hpt mod of
- Just mod_info -> return ()
- _not_a_home_module -> do
- res <- findPackageModule hsc_env mod True
- case res of
- Found _ _ -> return ()
- err -> let msg = cantFindError (hsc_dflags hsc_env) mod err in
- throwDyn (CmdLineError (showSDoc msg))
-
mkTopLevEnv :: HomePackageTable -> Module -> IO GlobalRdrEnv
mkTopLevEnv hpt modl
- = case lookupModuleEnv hpt modl of
- Nothing ->
- throwDyn (ProgramError ("mkTopLevEnv: not a home module "
- ++ showSDoc (pprModule modl)))
+ = case lookupUFM hpt (moduleName modl) of
+ Nothing -> throwDyn (ProgramError ("mkTopLevEnv: not a home module " ++
+ showSDoc (ppr modl)))
Just details ->
case mi_globals (hm_iface details) of
Nothing ->
throwDyn (ProgramError ("mkTopLevEnv: not interpreted "
- ++ showSDoc (pprModule modl)))
+ ++ showSDoc (ppr modl)))
Just env -> return env
-- | Get the interactive evaluation context, consisting of a pair of the
@@ -1896,9 +1923,11 @@ getContext s = withSession s (\HscEnv{ hsc_IC=ic } ->
-- its full top-level scope available.
moduleIsInterpreted :: Session -> Module -> IO Bool
moduleIsInterpreted s modl = withSession s $ \h ->
- case lookupModuleEnv (hsc_HPT h) modl of
- Just details -> return (isJust (mi_globals (hm_iface details)))
- _not_a_home_module -> return False
+ if modulePackageId modl /= thisPackage (hsc_dflags h)
+ then return False
+ else case lookupUFM (hsc_HPT h) (moduleName modl) of
+ Just details -> return (isJust (mi_globals (hm_iface details)))
+ _not_a_home_module -> return False
-- | Looks up an identifier in the current interactive context (for :info)
getInfo :: Session -> Name -> IO (Maybe (TyThing,Fixity,[Instance]))
@@ -2076,7 +2105,7 @@ foreign import "rts_evalStableIO" {- safe -}
showModule :: Session -> ModSummary -> IO String
showModule s mod_summary = withSession s $ \hsc_env -> do
- case lookupModuleEnv (hsc_HPT hsc_env) (ms_mod mod_summary) of
+ case lookupUFM (hsc_HPT hsc_env) (ms_mod_name mod_summary) of
Nothing -> panic "missing linkable"
Just mod_info -> return (showModMsg (hscTarget (hsc_dflags hsc_env)) (not obj_linkable) mod_summary)
where
diff --git a/compiler/main/HeaderInfo.hs b/compiler/main/HeaderInfo.hs
index 913ac33a33..847d193c28 100644
--- a/compiler/main/HeaderInfo.hs
+++ b/compiler/main/HeaderInfo.hs
@@ -19,8 +19,8 @@ import Lexer ( P(..), ParseResult(..), mkPState, pragState
, lexer, Token(..), PState(..) )
import FastString
import HsSyn ( ImportDecl(..), HsModule(..) )
-import Module ( Module, mkModule )
-import PrelNames ( gHC_PRIM )
+import Module ( ModuleName, moduleName )
+import PrelNames ( gHC_PRIM, mAIN_NAME )
import StringBuffer ( StringBuffer(..), hGetStringBuffer, hGetStringBufferBlock
, appendStringBuffers )
import SrcLoc ( Located(..), mkSrcLoc, unLoc, noSrcSpan )
@@ -31,12 +31,10 @@ import Util
import Outputable
import Pretty ()
import Panic
-import Bag ( unitBag, emptyBag, listToBag )
+import Bag ( emptyBag, listToBag )
import Distribution.Compiler
-import TRACE
-
import EXCEPTION ( throwDyn )
import IO
import List
@@ -55,13 +53,13 @@ openBinaryFile fp mode = openFileEx fp (BinaryMode mode)
-- we can end up with a large number of open handles before the garbage
-- collector gets around to closing them.
getImportsFromFile :: DynFlags -> FilePath
- -> IO ([Located Module], [Located Module], Located Module)
+ -> IO ([Located ModuleName], [Located ModuleName], Located ModuleName)
getImportsFromFile dflags filename = do
buf <- hGetStringBuffer filename
getImports dflags buf filename
getImports :: DynFlags -> StringBuffer -> FilePath
- -> IO ([Located Module], [Located Module], Located Module)
+ -> IO ([Located ModuleName], [Located ModuleName], Located ModuleName)
getImports dflags buf filename = do
let loc = mkSrcLoc (mkFastString filename) 1 0
case unP parseHeader (mkPState buf loc dflags) of
@@ -71,10 +69,10 @@ getImports dflags buf filename = do
L _ (HsModule mod _ imps _ _) ->
let
mod_name | Just located_mod <- mod = located_mod
- | otherwise = L noSrcSpan (mkModule "Main")
+ | otherwise = L noSrcSpan mAIN_NAME
(src_idecls, ord_idecls) = partition isSourceIdecl (map unLoc imps)
source_imps = map getImpMod src_idecls
- ordinary_imps = filter ((/= gHC_PRIM) . unLoc)
+ ordinary_imps = filter ((/= moduleName gHC_PRIM) . unLoc)
(map getImpMod ord_idecls)
-- GHC.Prim doesn't exist physically, so don't go looking for it.
in
diff --git a/compiler/main/HscMain.lhs b/compiler/main/HscMain.lhs
index 182391034c..e5b7026eb5 100644
--- a/compiler/main/HscMain.lhs
+++ b/compiler/main/HscMain.lhs
@@ -68,7 +68,6 @@ import TidyPgm ( tidyProgram, mkBootModDetails )
import CorePrep ( corePrepPgm )
import CoreToStg ( coreToStg )
import TyCon ( isDataTyCon )
-import Packages ( mkHomeModules )
import Name ( Name, NamedThing(..) )
import SimplStg ( stg2stg )
import CodeGen ( codeGen )
@@ -87,7 +86,7 @@ import MkExternalCore ( emitExternalCore )
import ParserCore
import ParserCoreUtils
import FastString
-import Maybes ( expectJust )
+import UniqFM ( emptyUFM )
import Bag ( unitBag )
import Monad ( unless )
import IO
@@ -107,7 +106,8 @@ newHscEnv dflags
= do { eps_var <- newIORef initExternalPackageState
; us <- mkSplitUniqSupply 'r'
; nc_var <- newIORef (initNameCache us knownKeyNames)
- ; fc_var <- newIORef emptyModuleEnv
+ ; fc_var <- newIORef emptyUFM
+ ; mlc_var <- newIORef emptyModuleEnv
; return (HscEnv { hsc_dflags = dflags,
hsc_targets = [],
hsc_mod_graph = [],
@@ -116,6 +116,7 @@ newHscEnv dflags
hsc_EPS = eps_var,
hsc_NC = nc_var,
hsc_FC = fc_var,
+ hsc_MLC = mlc_var,
hsc_global_rdr_env = emptyGlobalRdrEnv,
hsc_global_type_env = emptyNameEnv } ) }
@@ -579,7 +580,6 @@ hscCompile cgguts
cg_tycons = tycons,
cg_dir_imps = dir_imps,
cg_foreign = foreign_stubs,
- cg_home_mods = home_mods,
cg_dep_pkgs = dependencies } = cgguts
dflags = hsc_dflags hsc_env
location = ms_location mod_summary
@@ -595,10 +595,10 @@ hscCompile cgguts
----------------- Convert to STG ------------------
(stg_binds, cost_centre_info)
<- {-# SCC "CoreToStg" #-}
- myCoreToStg dflags home_mods this_mod prepd_binds
+ myCoreToStg dflags this_mod prepd_binds
------------------ Code generation ------------------
abstractC <- {-# SCC "CodeGen" #-}
- codeGen dflags home_mods this_mod data_tycons
+ codeGen dflags this_mod data_tycons
foreign_stubs dir_imps cost_centre_info
stg_binds
------------------ Code output -----------------------
@@ -696,7 +696,7 @@ hscFileCheck hsc_env mod_summary = do {
hscCmmFile :: DynFlags -> FilePath -> IO Bool
hscCmmFile dflags filename = do
- maybe_cmm <- parseCmmFile dflags (mkHomeModules []) filename
+ maybe_cmm <- parseCmmFile dflags filename
case maybe_cmm of
Nothing -> return False
Just cmm -> do
@@ -739,13 +739,13 @@ myParseModule dflags src_filename maybe_src_buf
}}
-myCoreToStg dflags home_mods this_mod prepd_binds
+myCoreToStg dflags this_mod prepd_binds
= do
stg_binds <- {-# SCC "Core2Stg" #-}
- coreToStg home_mods prepd_binds
+ coreToStg (thisPackage dflags) prepd_binds
(stg_binds2, cost_centre_info) <- {-# SCC "Stg2Stg" #-}
- stg2stg dflags home_mods this_mod stg_binds
+ stg2stg dflags this_mod stg_binds
return (stg_binds2, cost_centre_info)
\end{code}
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index e67de3bd36..a200bf99ca 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -7,7 +7,7 @@
module HscTypes (
-- * Sessions and compilation state
Session(..), HscEnv(..), hscEPS,
- FinderCache, FinderCacheEntry,
+ FinderCache, FindResult(..), ModLocationCache,
Target(..), TargetId(..), pprTarget, pprTargetId,
ModuleGraph, emptyMG,
@@ -24,10 +24,10 @@ module HscTypes (
ExternalPackageState(..), EpsStats(..), addEpsInStats,
PackageTypeEnv, PackageIfaceTable, emptyPackageIfaceTable,
- lookupIface, lookupIfaceByModule, emptyModIface,
+ lookupIfaceByModule, emptyModIface,
InteractiveContext(..), emptyInteractiveContext,
- icPrintUnqual, unQualInScope,
+ icPrintUnqual, mkPrintUnqualified,
ModIface(..), mkIfaceDepCache, mkIfaceVerCache, mkIfaceFixCache,
emptyIfaceDepCache,
@@ -67,8 +67,9 @@ import ByteCodeAsm ( CompiledByteCode )
#endif
import RdrName ( GlobalRdrEnv, emptyGlobalRdrEnv,
- LocalRdrEnv, emptyLocalRdrEnv,
- GlobalRdrElt(..), mkRdrUnqual, lookupGRE_RdrName )
+ LocalRdrEnv, emptyLocalRdrEnv, GlobalRdrElt(..),
+ unQualOK, ImpDeclSpec(..), Provenance(..),
+ ImportSpec(..), lookupGlobalRdrEnv )
import Name ( Name, NamedThing, getName, nameOccName, nameModule )
import NameEnv
import NameSet
@@ -85,7 +86,7 @@ import Class ( Class, classSelIds, classTyCon )
import TyCon ( TyCon, tyConSelIds, tyConDataCons )
import DataCon ( dataConImplicitIds )
import PrelNames ( gHC_PRIM )
-import Packages ( PackageIdH, PackageId, PackageConfig, HomeModules )
+import Packages ( PackageId )
import DynFlags ( DynFlags(..), isOneShot, HscTarget (..) )
import DriverPhases ( HscSource(..), isHsBoot, hscSourceString, Phase )
import BasicTypes ( Version, initialVersion, IPName,
@@ -98,6 +99,7 @@ import CoreSyn ( CoreRule )
import Maybes ( orElse, expectJust )
import Outputable
import SrcLoc ( SrcSpan, Located )
+import UniqFM ( lookupUFM, eltsUFM, emptyUFM )
import UniqSupply ( UniqSupply )
import FastString ( FastString )
@@ -172,9 +174,11 @@ data HscEnv
-- sucking in interface files. They cache the state of
-- external interface files, in effect.
- hsc_FC :: {-# UNPACK #-} !(IORef FinderCache),
+ hsc_FC :: {-# UNPACK #-} !(IORef FinderCache),
+ hsc_MLC :: {-# UNPACK #-} !(IORef ModLocationCache),
-- The finder's cache. This caches the location of modules,
-- so we don't have to search the filesystem multiple times.
+
hsc_global_rdr_env :: GlobalRdrEnv,
hsc_global_type_env :: TypeEnv
}
@@ -191,7 +195,7 @@ hscEPS hsc_env = readIORef (hsc_EPS hsc_env)
data Target = Target TargetId (Maybe (StringBuffer,ClockTime))
data TargetId
- = TargetModule Module
+ = TargetModule ModuleName
-- ^ A module name: search for the file
| TargetFile FilePath (Maybe Phase)
-- ^ A filename: preprocess & parse it to find the module name.
@@ -206,16 +210,13 @@ pprTarget (Target id _) = pprTargetId id
pprTargetId (TargetModule m) = ppr m
pprTargetId (TargetFile f _) = text f
-type FinderCache = ModuleEnv FinderCacheEntry
-type FinderCacheEntry = (ModLocation, Maybe (PackageConfig,Bool))
- -- The finder's cache (see module Finder)
-
-type HomePackageTable = ModuleEnv HomeModInfo
+type HomePackageTable = ModuleNameEnv HomeModInfo
-- Domain = modules in the home package
+ -- "home" package name cached here for convenience
type PackageIfaceTable = ModuleEnv ModIface
-- Domain = modules in the imported packages
-emptyHomePackageTable = emptyModuleEnv
+emptyHomePackageTable = emptyUFM
emptyPackageIfaceTable = emptyModuleEnv
data HomeModInfo
@@ -232,40 +233,37 @@ data HomeModInfo
-- When re-linking a module (hscNoRecomp), we construct
-- the HomModInfo by building a new ModDetails from the
-- old ModIface (only).
-\end{code}
-Simple lookups in the symbol table.
-
-\begin{code}
-lookupIface :: HomePackageTable -> PackageIfaceTable -> Module -> Maybe ModIface
--- We often have two IfaceTables, and want to do a lookup
-lookupIface hpt pit mod
- = case lookupModuleEnv hpt mod of
- Just mod_info -> Just (hm_iface mod_info)
- Nothing -> lookupModuleEnv pit mod
-
-lookupIfaceByModule :: HomePackageTable -> PackageIfaceTable -> Module -> Maybe ModIface
--- We often have two IfaceTables, and want to do a lookup
-lookupIfaceByModule hpt pit mod
- = case lookupModuleEnv hpt mod of
- Just mod_info -> Just (hm_iface mod_info)
- Nothing -> lookupModuleEnv pit mod
+-- | Find the 'ModIface' for a 'Module'
+lookupIfaceByModule
+ :: DynFlags
+ -> HomePackageTable
+ -> PackageIfaceTable
+ -> Module
+ -> Maybe ModIface
+lookupIfaceByModule dflags hpt pit mod
+ -- in one-shot, we don't use the HPT
+ | not (isOneShot (ghcMode dflags)) && modulePackageId mod == this_pkg
+ = fmap hm_iface (lookupUFM hpt (moduleName mod))
+ | otherwise
+ = lookupModuleEnv pit mod
+ where this_pkg = thisPackage dflags
\end{code}
\begin{code}
-hptInstances :: HscEnv -> (Module -> Bool) -> [Instance]
+hptInstances :: HscEnv -> (ModuleName -> Bool) -> [Instance]
-- Find all the instance declarations that are in modules imported
-- by this one, directly or indirectly, and are in the Home Package Table
-- This ensures that we don't see instances from modules --make compiled
-- before this one, but which are not below this one
hptInstances hsc_env want_this_module
= [ ispec
- | mod_info <- moduleEnvElts (hsc_HPT hsc_env)
- , want_this_module (mi_module (hm_iface mod_info))
+ | mod_info <- eltsUFM (hsc_HPT hsc_env)
+ , want_this_module (moduleName (mi_module (hm_iface mod_info)))
, ispec <- md_insts (hm_details mod_info) ]
-hptRules :: HscEnv -> [(Module, IsBootInterface)] -> [CoreRule]
+hptRules :: HscEnv -> [(ModuleName, IsBootInterface)] -> [CoreRule]
-- Get rules from modules "below" this one (in the dependency sense)
-- C.f Inst.hptInstances
hptRules hsc_env deps
@@ -283,10 +281,10 @@ hptRules hsc_env deps
-- be in the HPT, because we never compile it; it's in the EPT
-- instead. ToDo: clean up, and remove this slightly bogus
-- filter:
- , mod /= gHC_PRIM
+ , mod /= moduleName gHC_PRIM
-- Look it up in the HPT
- , let mod_info = case lookupModuleEnv hpt mod of
+ , let mod_info = case lookupUFM hpt mod of
Nothing -> pprPanic "hptRules" (ppr mod <+> ppr deps)
Just x -> x
@@ -294,6 +292,47 @@ hptRules hsc_env deps
, rule <- md_rules (hm_details mod_info) ]
\end{code}
+%************************************************************************
+%* *
+\subsection{The Finder cache}
+%* *
+%************************************************************************
+
+\begin{code}
+-- | The 'FinderCache' maps home module names to the result of
+-- searching for that module. It records the results of searching for
+-- 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 = ModuleNameEnv FindResult
+
+-- | The result of searching for an imported module.
+data FindResult
+ = Found ModLocation Module
+ -- the module was found
+ | NoPackage PackageId
+ -- the requested package was not found
+ | FoundMultiple [PackageId]
+ -- *error*: both in multiple packages
+ | PackageHidden PackageId
+ -- for an explicit source import: the package containing the module is
+ -- not exposed.
+ | ModuleHidden PackageId
+ -- for an explicit source import: the package containing the module is
+ -- exposed, but the module itself is hidden.
+ | NotFound [FilePath]
+ -- the module was not found, the specified places were searched.
+ | NotFoundInPackage PackageId
+ -- the module was not found in this package
+
+-- | Cache that remembers where we found a particular module. Contains both
+-- home modules and package modules. On @:load@, only home modules are
+-- purged from this cache.
+type ModLocationCache = ModuleEnv ModLocation
+\end{code}
%************************************************************************
%* *
@@ -313,7 +352,6 @@ the declarations into a single indexed map in the @PersistentRenamerState@.
\begin{code}
data ModIface
= ModIface {
- mi_package :: !PackageIdH, -- Which package the module comes from
mi_module :: !Module,
mi_mod_vers :: !Version, -- Module version: changes when anything changes
@@ -408,7 +446,6 @@ data ModGuts
mg_boot :: IsBootInterface, -- Whether it's an hs-boot module
mg_exports :: !NameSet, -- What it exports
mg_deps :: !Dependencies, -- What is below it, directly or otherwise
- mg_home_mods :: !HomeModules, -- For calling isHomeModule etc.
mg_dir_imps :: ![Module], -- Directly-imported modules; used to
-- generate initialisation code
mg_usages :: ![Usage], -- Version info for what it needed
@@ -458,7 +495,6 @@ data CgGuts
-- initialisation code
cg_foreign :: !ForeignStubs,
- cg_home_mods :: !HomeModules, -- for calling isHomeModule etc.
cg_dep_pkgs :: ![PackageId] -- Used to generate #includes for C code gen
}
@@ -489,10 +525,9 @@ data ForeignStubs = NoStubs
\end{code}
\begin{code}
-emptyModIface :: PackageIdH -> Module -> ModIface
-emptyModIface pkg mod
- = ModIface { mi_package = pkg,
- mi_module = mod,
+emptyModIface :: Module -> ModIface
+emptyModIface mod
+ = ModIface { mi_module = mod,
mi_mod_vers = initialVersion,
mi_orphan = False,
mi_boot = False,
@@ -546,25 +581,32 @@ emptyInteractiveContext
ic_type_env = emptyTypeEnv }
icPrintUnqual :: InteractiveContext -> PrintUnqualified
-icPrintUnqual ictxt = unQualInScope (ic_rn_gbl_env ictxt)
+icPrintUnqual ictxt = mkPrintUnqualified (ic_rn_gbl_env ictxt)
\end{code}
-@unQualInScope@ returns a function that takes a @Name@ and tells whether
-its unqualified name is in scope. This is put as a boolean flag in
-the @Name@'s provenance to guide whether or not to print the name qualified
-in error messages.
+%************************************************************************
+%* *
+ Building a PrintUnqualified
+%* *
+%************************************************************************
\begin{code}
-unQualInScope :: GlobalRdrEnv -> PrintUnqualified
--- True if 'f' is in scope, and has only one binding,
--- and the thing it is bound to is the name we are looking for
--- (i.e. false if A.f and B.f are both in scope as unqualified 'f')
---
--- [Out of date] Also checks for built-in syntax, which is always 'in scope'
-unQualInScope env mod occ
- = case lookupGRE_RdrName (mkRdrUnqual occ) env of
- [gre] -> nameModule (gre_name gre) == mod
- other -> False
+mkPrintUnqualified :: GlobalRdrEnv -> PrintUnqualified
+mkPrintUnqualified env = (qual_name, qual_mod)
+ where
+ qual_name mod occ
+ | null gres = Just (moduleName mod)
+ -- it isn't in scope at all, this probably shouldn't happen,
+ -- but we'll qualify it by the original module anyway.
+ | any unQualOK gres = Nothing
+ | (Imported is : _) <- map gre_prov gres, (idecl : _) <- is
+ = Just (is_as (is_decl idecl))
+ | otherwise = panic "mkPrintUnqualified"
+ where
+ gres = [ gre | gre <- lookupGlobalRdrEnv env occ,
+ nameModule (gre_name gre) == mod ]
+
+ qual_mod mod = Nothing -- For now...
\end{code}
@@ -637,11 +679,21 @@ extendTypeEnvList env things = foldl extendTypeEnv env things
\end{code}
\begin{code}
-lookupType :: HomePackageTable -> PackageTypeEnv -> Name -> Maybe TyThing
-lookupType hpt pte name
- = case lookupModuleEnv hpt (nameModule name) of
- Just details -> lookupNameEnv (md_types (hm_details details)) name
- Nothing -> lookupNameEnv pte name
+lookupType :: DynFlags
+ -> HomePackageTable
+ -> PackageTypeEnv
+ -> Name
+ -> Maybe TyThing
+
+lookupType dflags hpt pte name
+ -- in one-shot, we don't use the HPT
+ | not (isOneShot (ghcMode dflags)) && modulePackageId mod == this_pkg
+ = do hm <- lookupUFM hpt (moduleName mod) -- Maybe monad
+ lookupNameEnv (md_types (hm_details hm)) name
+ | otherwise
+ = lookupNameEnv pte name
+ where mod = nameModule name
+ this_pkg = thisPackage dflags
\end{code}
@@ -809,7 +861,7 @@ type IsBootInterface = Bool
-- Invariant: the dependencies of a module M never includes M
-- Invariant: the lists are unordered, with no duplicates
data Dependencies
- = Deps { dep_mods :: [(Module,IsBootInterface)], -- Home-package module dependencies
+ = Deps { dep_mods :: [(ModuleName,IsBootInterface)], -- Home-package module dependencies
dep_pkgs :: [PackageId], -- External package dependencies
dep_orphs :: [Module] } -- Orphan modules (whether home or external pkg)
deriving( Eq )
@@ -819,7 +871,7 @@ noDependencies :: Dependencies
noDependencies = Deps [] [] []
data Usage
- = Usage { usg_name :: Module, -- Name of the module
+ = Usage { usg_name :: ModuleName, -- Name of the module
usg_mod :: Version, -- Module version
usg_entities :: [(OccName,Version)], -- Sorted by occurrence name
usg_exports :: Maybe Version, -- Export-list version, if we depend on it
@@ -859,14 +911,16 @@ type PackageInstEnv = InstEnv
data ExternalPackageState
= EPS {
- eps_is_boot :: !(ModuleEnv (Module, IsBootInterface)),
- -- In OneShot mode (only), home-package modules accumulate in the
- -- external package state, and are sucked in lazily.
- -- For these home-pkg modules (only) we need to record which are
- -- boot modules. We set this field after loading all the
- -- explicitly-imported interfaces, but before doing anything else
+ eps_is_boot :: !(ModuleNameEnv (ModuleName, IsBootInterface)),
+ -- In OneShot mode (only), home-package modules
+ -- accumulate in the external package state, and are
+ -- sucked in lazily. For these home-pkg modules
+ -- (only) we need to record which are boot modules.
+ -- We set this field after loading all the
+ -- explicitly-imported interfaces, but before doing
+ -- anything else
--
- -- The Module part is not necessary, but it's useful for
+ -- The ModuleName part is not necessary, but it's useful for
-- debug prints, and it's convenient because this field comes
-- direct from TcRnTypes.ImportAvails.imp_dep_mods
@@ -957,13 +1011,13 @@ emptyMG = []
data ModSummary
= ModSummary {
- ms_mod :: Module, -- Name of the module
+ ms_mod :: Module, -- Identity of the module
ms_hsc_src :: HscSource, -- Source is Haskell, hs-boot, external core
ms_location :: ModLocation, -- Location
ms_hs_date :: ClockTime, -- Timestamp of source file
ms_obj_date :: Maybe ClockTime, -- Timestamp of object, maybe
- ms_srcimps :: [Located Module], -- Source imports
- ms_imps :: [Located Module], -- Non-source imports
+ ms_srcimps :: [Located ModuleName], -- Source imports
+ ms_imps :: [Located ModuleName], -- Non-source imports
ms_hspp_file :: FilePath, -- Filename of preprocessed source.
ms_hspp_opts :: DynFlags, -- Cached flags from OPTIONS, INCLUDE
-- and LANGUAGE pragmas.
@@ -1011,7 +1065,7 @@ showModMsg target recomp mod_summary
char ')'])
where
mod = ms_mod mod_summary
- mod_str = moduleString mod ++ hscSourceString (ms_hsc_src mod_summary)
+ mod_str = showSDoc (ppr mod) ++ hscSourceString (ms_hsc_src mod_summary)
\end{code}
diff --git a/compiler/main/PackageConfig.hs b/compiler/main/PackageConfig.hs
index e19a10dbc5..bfd2f34496 100644
--- a/compiler/main/PackageConfig.hs
+++ b/compiler/main/PackageConfig.hs
@@ -6,14 +6,21 @@ module PackageConfig (
-- * PackageId
PackageId,
mkPackageId, stringToPackageId, packageIdString, packageConfigId,
- packageIdFS, fsToPackageId,
+ packageIdFS, fsToPackageId, unpackPackageId,
-- * The PackageConfig type: information about a package
PackageConfig,
InstalledPackageInfo(..), showPackageId,
Version(..),
PackageIdentifier(..),
- defaultPackageConfig
+ defaultPackageConfig,
+
+ -- * Wired-in PackageIds
+ basePackageId,
+ rtsPackageId,
+ haskell98PackageId,
+ thPackageId,
+ mainPackageId
) where
#include "HsVersions.h"
@@ -22,6 +29,7 @@ import Distribution.InstalledPackageInfo
import Distribution.Package
import Distribution.Version
import FastString
+import Text.ParserCombinators.ReadP ( readP_to_S )
-- -----------------------------------------------------------------------------
-- Our PackageConfig type is just InstalledPackageInfo from Cabal. Later we
@@ -66,4 +74,40 @@ mkPackageId = stringToPackageId . showPackageId
packageConfigId :: PackageConfig -> PackageId
packageConfigId = mkPackageId . package
+unpackPackageId :: PackageId -> Maybe PackageIdentifier
+unpackPackageId p
+ = case [ pid | (pid,"") <- readP_to_S parsePackageId str ] of
+ [] -> Nothing
+ (pid:_) -> Just pid
+ where str = packageIdString p
+
+-- -----------------------------------------------------------------------------
+-- Package Ids that are wired in
+
+-- Certain packages are "known" to the compiler, in that we know about certain
+-- entities that reside in these packages, and the compiler needs to
+-- declare static Modules and Names that refer to these packages. Hence
+-- the wired-in packages can't include version numbers, since we don't want
+-- to bake the version numbers of these packages into GHC.
+--
+-- So here's the plan. Wired-in packages are still versioned as
+-- normal in the packages database, and you can still have multiple
+-- versions of them installed. However, for each invocation of GHC,
+-- only a single instance of each wired-in package will be recognised
+-- (the desired one is selected via -package/-hide-package), and GHC
+-- will use the unversioned PackageId below when referring to it,
+-- including in .hi files and object file symbols. Unselected
+-- versions of wired-in packages will be ignored, as will any other
+-- package that depends directly or indirectly on it (much as if you
+-- had used -ignore-package).
+
+basePackageId = fsToPackageId FSLIT("base")
+rtsPackageId = fsToPackageId FSLIT("rts")
+haskell98PackageId = fsToPackageId FSLIT("haskell98")
+thPackageId = fsToPackageId FSLIT("template-haskell")
+
+-- This is the package Id for the program. It is the default package
+-- Id if you don't specify a package name. We don't add this prefix
+-- to symbol name, since there can be only one main package per program.
+mainPackageId = fsToPackageId FSLIT("main")
diff --git a/compiler/main/Packages.lhs b/compiler/main/Packages.lhs
index ae6b18863e..22494111fb 100644
--- a/compiler/main/Packages.lhs
+++ b/compiler/main/Packages.lhs
@@ -12,16 +12,11 @@ module Packages (
extendPackageConfigMap, dumpPackages,
-- * Reading the package config, and processing cmdline args
- PackageIdH(..), isHomePackage,
PackageState(..),
- mkPackageState,
initPackages,
getPackageDetails,
- checkForPackageConflicts,
lookupModuleInAllPackages,
- HomeModules, mkHomeModules, isHomeModule,
-
-- * Inspecting the set of packages in scope
getPackageIncludePath,
getPackageCIncludes,
@@ -48,7 +43,6 @@ import Config ( cProjectVersion )
import Name ( Name, nameModule_maybe )
import UniqFM
import Module
-import FiniteMap
import UniqSet
import Util
import Maybes ( expectJust, MaybeErr(..) )
@@ -67,6 +61,7 @@ import Distribution.Package
import Distribution.Version
import System.Directory ( doesFileExist, doesDirectoryExist,
getDirectoryContents )
+import Data.Maybe ( catMaybes )
import Control.Monad ( foldM )
import Data.List ( nub, partition, sortBy, isSuffixOf )
import FastString
@@ -91,9 +86,6 @@ import ErrUtils ( debugTraceMsg, putMsg, Message )
-- Let depExposedPackages be the transitive closure from exposedPackages of
-- their dependencies.
--
--- * It is an error for any two packages in depExposedPackages to provide the
--- same module.
---
-- * When searching for a module from an explicit import declaration,
-- only the exposed modules in exposedPackages are valid.
--
@@ -109,16 +101,6 @@ import ErrUtils ( debugTraceMsg, putMsg, Message )
-- contain any Haskell modules, and therefore won't be discovered
-- by the normal mechanism of dependency tracking.
-
--- One important thing that the package state provides is a way to
--- tell, for a given module, whether it is part of the current package
--- or not. We need to know this for two reasons:
---
--- * generating cross-DLL calls is different from intra-DLL calls
--- (see below).
--- * we don't record version information in interface files for entities
--- in a different package.
---
-- Notes on DLLs
-- ~~~~~~~~~~~~~
-- When compiling module A, which imports module B, we need to
@@ -143,29 +125,13 @@ data PackageState = PackageState {
-- The exposed flags are adjusted according to -package and
-- -hide-package flags, and -ignore-package removes packages.
- moduleToPkgConfAll :: ModuleEnv [(PackageConfig,Bool)],
+ moduleToPkgConfAll :: UniqFM [(PackageConfig,Bool)] -- ModuleEnv mapping
-- Derived from pkgIdMap.
-- Maps Module to (pkgconf,exposed), where pkgconf is the
-- PackageConfig for the package containing the module, and
-- exposed is True if the package exposes that module.
-
- -- The PackageIds of some known packages
- basePackageId :: PackageIdH,
- rtsPackageId :: PackageIdH,
- haskell98PackageId :: PackageIdH,
- thPackageId :: PackageIdH
}
-data PackageIdH
- = HomePackage -- The "home" package is the package curently
- -- being compiled
- | ExtPackage PackageId -- An "external" package is any other package
-
-
-isHomePackage :: PackageIdH -> Bool
-isHomePackage HomePackage = True
-isHomePackage (ExtPackage _) = False
-
-- A PackageConfigMap maps a PackageId to a PackageConfig
type PackageConfigMap = UniqFM PackageConfig
@@ -194,8 +160,7 @@ getPackageDetails dflags ps = expectJust "getPackageDetails" (lookupPackage (pkg
initPackages :: DynFlags -> IO DynFlags
initPackages dflags = do
pkg_map <- readPackageConfigs dflags;
- state <- mkPackageState dflags pkg_map
- return dflags{ pkgState = state }
+ mkPackageState dflags pkg_map
-- -----------------------------------------------------------------------------
-- Reading the package database(s)
@@ -297,7 +262,7 @@ mungePackagePaths top_dir ps = map munge_pkg ps
-- When all the command-line options are in, we can process our package
-- settings and populate the package state.
-mkPackageState :: DynFlags -> PackageConfigMap -> IO PackageState
+mkPackageState :: DynFlags -> PackageConfigMap -> IO DynFlags
mkPackageState dflags orig_pkg_db = do
--
-- Modify the package database according to the command-line flags
@@ -317,10 +282,9 @@ mkPackageState dflags orig_pkg_db = do
case pick str pkgs of
Nothing -> missingPackageErr str
Just (p,ps) -> procflags (p':ps') expl' flags
- where pkgid = packageConfigId p
- p' = p {exposed=True}
+ where p' = p {exposed=True}
ps' = hideAll (pkgName (package p)) ps
- expl' = addOneToUniqSet expl pkgid
+ expl' = package p : expl
procflags pkgs expl (HidePackage str : flags) = do
case partition (matches str) pkgs of
([],_) -> missingPackageErr str
@@ -355,7 +319,7 @@ mkPackageState dflags orig_pkg_db = do
where maybe_hide p | pkgName (package p) == name = p {exposed=False}
| otherwise = p
--
- (pkgs1,explicit) <- procflags (eltsUFM orig_pkg_db) emptyUniqSet flags
+ (pkgs1,explicit) <- procflags (eltsUFM orig_pkg_db) [] flags
--
-- hide all packages for which there is also a later version
-- that is already exposed. This just makes it non-fatal to have two
@@ -377,11 +341,74 @@ mkPackageState dflags orig_pkg_db = do
let pkg = package p,
pkgName pkg == myname,
pkgVersion pkg > myversion ]
- a_later_version_is_exposed
- = not (null later_versions)
pkgs2 <- mapM maybe_hide pkgs1
--
+ -- Now we must find our wired-in packages, and rename them to
+ -- their canonical names (eg. base-1.0 ==> base).
+ --
+ let
+ wired_in_pkgids = [ basePackageId,
+ rtsPackageId,
+ haskell98PackageId,
+ thPackageId ]
+
+ wired_in_names = map packageIdString wired_in_pkgids
+
+ -- find which package corresponds to each wired-in package
+ -- delete any other packages with the same name
+ -- update the package and any dependencies to point to the new
+ -- one.
+ findWiredInPackage :: [PackageConfig] -> String
+ -> IO (Maybe PackageIdentifier)
+ findWiredInPackage pkgs wired_pkg =
+ case [ p | p <- pkgs, pkgName (package p) == wired_pkg,
+ exposed p ] of
+ [] -> do
+ debugTraceMsg dflags 2 $
+ ptext SLIT("wired-in package ")
+ <> text wired_pkg
+ <> ptext SLIT(" not found.")
+ return Nothing
+ [one] -> do
+ debugTraceMsg dflags 2 $
+ ptext SLIT("wired-in package ")
+ <> text wired_pkg
+ <> ptext SLIT(" mapped to ")
+ <> text (showPackageId (package one))
+ return (Just (package one))
+ more -> do
+ throwDyn (CmdLineError (showSDoc $
+ ptext SLIT("there are multiple exposed packages that match wired-in package ") <> text wired_pkg))
+
+ mb_wired_in_ids <- mapM (findWiredInPackage pkgs2) wired_in_names
+ let
+ wired_in_ids = catMaybes mb_wired_in_ids
+
+ deleteHiddenWiredInPackages pkgs = filter ok pkgs
+ where ok p = pkgName (package p) `notElem` wired_in_names
+ || exposed p
+
+ updateWiredInDependencies pkgs = map upd_pkg pkgs
+ where upd_pkg p = p{ package = upd_pid (package p),
+ depends = map upd_pid (depends p) }
+
+ upd_pid pid = case filter (== pid) wired_in_ids of
+ [] -> pid
+ (x:_) -> x{ pkgVersion = Version [] [] }
+
+ pkgs3 = deleteHiddenWiredInPackages pkgs2
+
+ pkgs4 = updateWiredInDependencies pkgs3
+
+ explicit1 = map upd_pid explicit
+
+ -- we must return an updated thisPackage, just in case we
+ -- are actually compiling one of the wired-in packages
+ Just old_this_pkg = unpackPackageId (thisPackage dflags)
+ new_this_pkg = mkPackageId (upd_pid old_this_pkg)
+
+ --
-- Eliminate any packages which have dangling dependencies (perhaps
-- because the package was removed by -ignore-package).
--
@@ -403,41 +430,23 @@ mkPackageState dflags orig_pkg_db = do
where dangling pid = pid `notElem` all_pids
all_pids = map package pkgs
--
- pkgs <- elimDanglingDeps pkgs2
+ pkgs <- elimDanglingDeps pkgs4
let pkg_db = extendPackageConfigMap emptyPackageConfigMap pkgs
--
-- Find the transitive closure of dependencies of exposed
--
let exposed_pkgids = [ packageConfigId p | p <- pkgs, exposed p ]
dep_exposed <- closeDeps pkg_db exposed_pkgids
- --
- -- Look up some known PackageIds
- --
let
- lookupPackageByName :: FastString -> PackageIdH
- lookupPackageByName nm =
- case [ conf | p <- dep_exposed,
- Just conf <- [lookupPackage pkg_db p],
- nm == mkFastString (pkgName (package conf)) ] of
- [] -> HomePackage
- (p:ps) -> ExtPackage (mkPackageId (package p))
-
- -- Get the PackageIds for some known packages (we know the names,
- -- but we don't know the versions). Some of these packages might
- -- not exist in the database, so they are Maybes.
- basePackageId = lookupPackageByName basePackageName
- rtsPackageId = lookupPackageByName rtsPackageName
- haskell98PackageId = lookupPackageByName haskell98PackageName
- thPackageId = lookupPackageByName thPackageName
-
-- add base & rts to the explicit packages
- basicLinkedPackages = [basePackageId,rtsPackageId]
- explicit' = addListToUniqSet explicit
- [ p | ExtPackage p <- basicLinkedPackages ]
+ basicLinkedPackages = filter (flip elemUFM pkg_db)
+ [basePackageId,rtsPackageId]
+ explicit2 = addListToUniqSet (mkUniqSet (map mkPackageId explicit1))
+ basicLinkedPackages
--
-- Close the explicit packages with their dependencies
--
- dep_explicit <- closeDeps pkg_db (uniqSetToList explicit')
+ dep_explicit <- closeDeps pkg_db (uniqSetToList explicit2)
--
-- Build up a mapping from Module -> PackageConfig for all modules.
-- Discover any conflicts at the same time, and factor in the new exposed
@@ -445,107 +454,31 @@ mkPackageState dflags orig_pkg_db = do
--
let mod_map = mkModuleMap pkg_db dep_exposed
- return PackageState{ explicitPackages = dep_explicit,
- origPkgIdMap = orig_pkg_db,
- pkgIdMap = pkg_db,
- moduleToPkgConfAll = mod_map,
- basePackageId = basePackageId,
- rtsPackageId = rtsPackageId,
- haskell98PackageId = haskell98PackageId,
- thPackageId = thPackageId
- }
+ pstate = PackageState{ explicitPackages = dep_explicit,
+ origPkgIdMap = orig_pkg_db,
+ pkgIdMap = pkg_db,
+ moduleToPkgConfAll = mod_map
+ }
+
+ return dflags{ pkgState = pstate, thisPackage = new_this_pkg }
-- done!
-basePackageName = FSLIT("base")
-rtsPackageName = FSLIT("rts")
-haskell98PackageName = FSLIT("haskell98")
-thPackageName = FSLIT("template-haskell")
- -- Template Haskell libraries in here
mkModuleMap
:: PackageConfigMap
-> [PackageId]
- -> ModuleEnv [(PackageConfig, Bool)]
+ -> UniqFM [(PackageConfig, Bool)]
mkModuleMap pkg_db pkgs = foldr extend_modmap emptyUFM pkgs
where
- extend_modmap pkgname modmap =
+ extend_modmap pkgid modmap =
addListToUFM_C (++) modmap
[(m, [(pkg, m `elem` exposed_mods)]) | m <- all_mods]
where
- pkg = expectJust "mkModuleMap" (lookupPackage pkg_db pkgname)
- exposed_mods = map mkModule (exposedModules pkg)
- hidden_mods = map mkModule (hiddenModules pkg)
- all_mods = exposed_mods ++ hidden_mods
-
--- -----------------------------------------------------------------------------
--- Check for conflicts in the program.
-
--- | A conflict arises if the program contains two modules with the same
--- name, which can arise if the program depends on multiple packages that
--- expose the same module, or if the program depends on a package that
--- contains a module also present in the program (the "home package").
---
-checkForPackageConflicts
- :: DynFlags
- -> [Module] -- modules in the home package
- -> [PackageId] -- packages on which the program depends
- -> MaybeErr Message ()
-
-checkForPackageConflicts dflags mods pkgs = do
- let
- state = pkgState dflags
- pkg_db = pkgIdMap state
- --
- dep_pkgs <- closeDepsErr pkg_db pkgs
-
- let
- extend_modmap pkgname modmap =
- addListToFM_C (++) modmap
- [(m, [(pkg, m `elem` exposed_mods)]) | m <- all_mods]
- where
- pkg = expectJust "checkForPackageConflicts"
- (lookupPackage pkg_db pkgname)
- exposed_mods = map mkModule (exposedModules pkg)
- hidden_mods = map mkModule (hiddenModules pkg)
+ pkg = expectJust "mkModuleMap" (lookupPackage pkg_db pkgid)
+ exposed_mods = map mkModuleName (exposedModules pkg)
+ hidden_mods = map mkModuleName (hiddenModules pkg)
all_mods = exposed_mods ++ hidden_mods
- mod_map = foldr extend_modmap emptyFM pkgs
- mod_map_list :: [(Module,[(PackageConfig,Bool)])]
- mod_map_list = fmToList mod_map
-
- overlaps = [ (m, map fst ps) | (m,ps@(_:_:_)) <- mod_map_list ]
- --
- if not (null overlaps)
- then Failed (pkgOverlapError overlaps)
- else do
-
- let
- overlap_mods = [ (mod,pkg)
- | mod <- mods,
- Just ((pkg,_):_) <- [lookupFM mod_map mod] ]
- -- will be only one package here
- if not (null overlap_mods)
- then Failed (modOverlapError overlap_mods)
- else do
-
- return ()
-
-pkgOverlapError overlaps = vcat (map msg overlaps)
- where
- msg (mod,pkgs) =
- text "conflict: module" <+> quotes (ppr mod)
- <+> ptext SLIT("is present in multiple packages:")
- <+> hsep (punctuate comma (map pprPkg pkgs))
-
-modOverlapError overlaps = vcat (map msg overlaps)
- where
- msg (mod,pkg) = fsep [
- text "conflict: module",
- quotes (ppr mod),
- ptext SLIT("belongs to the current program/library"),
- ptext SLIT("and also to package"),
- pprPkg pkg ]
-
pprPkg :: PackageConfig -> SDoc
pprPkg p = text (showPackageId (package p))
@@ -625,9 +558,9 @@ getPackageFrameworks dflags pkgs = do
-- | Takes a Module, and if the module is in a package returns
-- @(pkgconf,exposed)@ where pkgconf is the PackageConfig for that package,
-- and exposed is True if the package exposes the module.
-lookupModuleInAllPackages :: DynFlags -> Module -> [(PackageConfig,Bool)]
+lookupModuleInAllPackages :: DynFlags -> ModuleName -> [(PackageConfig,Bool)]
lookupModuleInAllPackages dflags m =
- case lookupModuleEnv (moduleToPkgConfAll (pkgState dflags)) m of
+ case lookupUFM (moduleToPkgConfAll (pkgState dflags)) m of
Nothing -> []
Just ps -> ps
@@ -673,24 +606,11 @@ missingPackageErr p = throwDyn (CmdLineError (showSDoc (missingPackageMsg p)))
missingPackageMsg p = ptext SLIT("unknown package:") <+> text p
-- -----------------------------------------------------------------------------
--- The home module set
-
-newtype HomeModules = HomeModules ModuleSet
-
-mkHomeModules :: [Module] -> HomeModules
-mkHomeModules = HomeModules . mkModuleSet
-
-isHomeModule :: HomeModules -> Module -> Bool
-isHomeModule (HomeModules set) mod = elemModuleSet mod set
-
--- Determining whether a Name refers to something in another package or not.
--- Cross-package references need to be handled differently when dynamically-
--- linked libraries are involved.
-isDllName :: HomeModules -> Name -> Bool
-isDllName pdeps name
+isDllName :: PackageId -> Name -> Bool
+isDllName this_pkg name
| opt_Static = False
- | Just mod <- nameModule_maybe name = not (isHomeModule pdeps mod)
+ | Just mod <- nameModule_maybe name = modulePackageId mod /= this_pkg
| otherwise = False -- no, it is not even an external name
-- -----------------------------------------------------------------------------
diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs
index 370e5326d0..c0d19df90a 100644
--- a/compiler/main/TidyPgm.lhs
+++ b/compiler/main/TidyPgm.lhs
@@ -8,8 +8,7 @@ module TidyPgm( mkBootModDetails, tidyProgram ) where
#include "HsVersions.h"
-import DynFlags ( DynFlag(..), dopt )
-import Packages ( HomeModules )
+import DynFlags ( DynFlag(..), DynFlags(..), dopt )
import CoreSyn
import CoreUnfold ( noUnfolding, mkTopUnfolding )
import CoreFVs ( ruleLhsFreeIds, exprSomeFreeVars )
@@ -50,6 +49,7 @@ import HscTypes ( HscEnv(..), NameCache( nsUniqs ), CgGuts(..),
)
import Maybes ( orElse, mapCatMaybes )
import ErrUtils ( showPass, dumpIfSet_core )
+import PackageConfig ( PackageId )
import UniqSupply ( splitUniqSupply, uniqFromSupply )
import List ( partition )
import Maybe ( isJust )
@@ -238,7 +238,6 @@ tidyProgram hsc_env
mg_binds = binds,
mg_rules = imp_rules,
mg_dir_imps = dir_imps, mg_deps = deps,
- mg_home_mods = home_mods,
mg_foreign = foreign_stubs })
= do { let dflags = hsc_dflags hsc_env
@@ -257,7 +256,7 @@ tidyProgram hsc_env
-- (It's a sort of mutual recursion.)
}
- ; (tidy_env, tidy_binds) <- tidyTopBinds hsc_env home_mods mod type_env ext_ids binds
+ ; (tidy_env, tidy_binds) <- tidyTopBinds hsc_env mod type_env ext_ids binds
; let { tidy_type_env = tidyTypeEnv omit_prags exports type_env tidy_binds
; tidy_ispecs = tidyInstances (lookup_dfun tidy_type_env) insts_tc
@@ -285,7 +284,6 @@ tidyProgram hsc_env
cg_binds = all_tidy_binds,
cg_dir_imps = dir_imps,
cg_foreign = foreign_stubs,
- cg_home_mods = home_mods,
cg_dep_pkgs = dep_pkgs deps },
ModDetails { md_types = tidy_type_env,
@@ -535,7 +533,6 @@ findExternalRules binds non_local_rules ext_ids
-- * subst_env: A Var->Var mapping that substitutes the new Var for the old
tidyTopBinds :: HscEnv
- -> HomeModules
-> Module
-> TypeEnv
-> IdEnv Bool -- Domain = Ids that should be external
@@ -543,7 +540,7 @@ tidyTopBinds :: HscEnv
-> [CoreBind]
-> IO (TidyEnv, [CoreBind])
-tidyTopBinds hsc_env hmods mod type_env ext_ids binds
+tidyTopBinds hsc_env mod type_env ext_ids binds
= tidy init_env binds
where
nc_var = hsc_NC hsc_env
@@ -567,13 +564,15 @@ tidyTopBinds hsc_env hmods mod type_env ext_ids binds
-- since their names are "taken".
-- The type environment is a convenient source of such things.
+ this_pkg = thisPackage (hsc_dflags hsc_env)
+
tidy env [] = return (env, [])
- tidy env (b:bs) = do { (env1, b') <- tidyTopBind hmods mod nc_var ext_ids env b
+ tidy env (b:bs) = do { (env1, b') <- tidyTopBind this_pkg mod nc_var ext_ids env b
; (env2, bs') <- tidy env1 bs
; return (env2, b':bs') }
------------------------
-tidyTopBind :: HomeModules
+tidyTopBind :: PackageId
-> Module
-> IORef NameCache -- For allocating new unique names
-> IdEnv Bool -- Domain = Ids that should be external
@@ -581,16 +580,16 @@ tidyTopBind :: HomeModules
-> TidyEnv -> CoreBind
-> IO (TidyEnv, CoreBind)
-tidyTopBind hmods mod nc_var ext_ids tidy_env1@(occ_env1,subst1) (NonRec bndr rhs)
+tidyTopBind this_pkg mod nc_var ext_ids tidy_env1@(occ_env1,subst1) (NonRec bndr rhs)
= do { (occ_env2, name') <- tidyTopName mod nc_var ext_ids occ_env1 bndr
; let { (bndr', rhs') = tidyTopPair ext_ids tidy_env2 caf_info name' (bndr, rhs)
; subst2 = extendVarEnv subst1 bndr bndr'
; tidy_env2 = (occ_env2, subst2) }
; return (tidy_env2, NonRec bndr' rhs') }
where
- caf_info = hasCafRefs hmods subst1 (idArity bndr) rhs
+ caf_info = hasCafRefs this_pkg subst1 (idArity bndr) rhs
-tidyTopBind hmods mod nc_var ext_ids tidy_env1@(occ_env1,subst1) (Rec prs)
+tidyTopBind this_pkg mod nc_var ext_ids tidy_env1@(occ_env1,subst1) (Rec prs)
= do { (occ_env2, names') <- tidyTopNames mod nc_var ext_ids occ_env1 bndrs
; let { prs' = zipWith (tidyTopPair ext_ids tidy_env2 caf_info)
names' prs
@@ -603,7 +602,7 @@ tidyTopBind hmods mod nc_var ext_ids tidy_env1@(occ_env1,subst1) (Rec prs)
-- the CafInfo for a recursive group says whether *any* rhs in
-- the group may refer indirectly to a CAF (because then, they all do).
caf_info
- | or [ mayHaveCafRefs (hasCafRefs hmods subst1 (idArity bndr) rhs)
+ | or [ mayHaveCafRefs (hasCafRefs this_pkg subst1 (idArity bndr) rhs)
| (bndr,rhs) <- prs ] = MayHaveCafRefs
| otherwise = NoCafRefs
@@ -779,13 +778,13 @@ it as a CAF. In these cases however, we would need to use an additional
CAF list to keep track of non-collectable CAFs.
\begin{code}
-hasCafRefs :: HomeModules -> VarEnv Var -> Arity -> CoreExpr -> CafInfo
-hasCafRefs hmods p arity expr
+hasCafRefs :: PackageId -> VarEnv Var -> Arity -> CoreExpr -> CafInfo
+hasCafRefs this_pkg p arity expr
| is_caf || mentions_cafs = MayHaveCafRefs
| otherwise = NoCafRefs
where
mentions_cafs = isFastTrue (cafRefs p expr)
- is_caf = not (arity > 0 || rhsIsStatic hmods expr)
+ is_caf = not (arity > 0 || rhsIsStatic this_pkg expr)
-- NB. we pass in the arity of the expression, which is expected
-- to be calculated by exprArity. This is because exprArity
-- knows how much eta expansion is going to be done by