import LoadIface ( readIface, loadInterface )
import BasicTypes ( Version, initialVersion, bumpVersion )
import TcRnMonad
-import TcRnTypes ( mkModDeps )
import HscTypes ( ModIface(..), ModDetails(..),
ModGuts(..), IfaceExport,
HscEnv(..), hscEPS, Dependencies(..), FixItem(..),
\begin{code}
mkUsageInfo :: HscEnv
-> HomeModules
- -> ModuleEnv (Module, Maybe Bool, SrcSpan)
+ -> ModuleEnv (Module, Bool, SrcSpan)
-> [(Module, IsBootInterface)]
-> NameSet -> IO [Usage]
mkUsageInfo hsc_env hmods dir_imp_mods dep_mods used_names
mod = nameModule name
add_item occs _ = occ:occs
- import_all mod = case lookupModuleEnv dir_imp_mods mod of
- Just (_,imp_all,_) -> isNothing imp_all
- Nothing -> False
+ depend_on_exports mod = case lookupModuleEnv dir_imp_mods mod of
+ Just (_,no_imp,_) -> not no_imp
+ Nothing -> True
-- We want to create a Usage for a home module if
-- a) we used something from; has something in used_names
| isNothing maybe_iface -- We can't depend on it if we didn't
|| not (isHomeModule hmods mod) -- even open the interface!
|| (null used_occs
- && not all_imported
+ && isNothing export_vers
&& not orphan_mod)
= Nothing -- Record no usage info
version_env = mi_ver_fn iface
mod_vers = mi_mod_vers iface
rules_vers = mi_rule_vers iface
- all_imported = import_all mod
- export_vers | all_imported = Just (mi_exp_vers iface)
- | otherwise = Nothing
+ export_vers | depend_on_exports mod = Just (mi_exp_vers iface)
+ | otherwise = Nothing
-- The sort is to put them into canonical order
used_occs = lookupModuleEnv ent_map mod `orElse` []
-- time round, but if someone has added a new rule you might need it this time
-- The export list field is (Just v) if we depend on the export list:
- -- i.e. we imported the module without saying exactly what we imported
- -- We need to recompile if the module exports changes, because we might
- -- now have a name clash in the importing module.
+ -- i.e. we imported the module directly, whether or not we
+ -- enumerated the things we imported, or just imported everything
+ -- We need to recompile if M's exports change, because
+ -- if the import was import M, we might now have a name clash in the
+ -- importing module.
+ -- if the import was import M(x) M might no longer export x
+ -- The only way we don't depend on the export list is if we have
+ -- import M()
+ -- And of course, for modules that aren't imported directly we don't
+ -- depend on their export lists
\end{code}
ASSERT2( not (pkg `elem` dep_pkgs deps), ppr pkg <+> ppr (dep_pkgs deps) )
([], pkg : dep_pkgs deps)
+ -- True <=> import M ()
import_all = case imp_details of
- Just (is_hiding, ls) -- Imports are spec'd explicitly
- | not is_hiding -> Just (not (null ls))
- _ -> Nothing -- Everything is imported,
- -- (or almost everything [hiding])
+ Just (is_hiding, ls) -> not is_hiding && null ls
+ other -> False
-- unqual_avails is the Avails that are visible in *unqualified* form
-- We need to know this so we know what to export when we see
imports = tcg_imports gbl_env
- direct_import_mods :: [(Module, Maybe Bool, SrcSpan)]
+ direct_import_mods :: [(Module, Bool, SrcSpan)]
-- See the type of the imp_mods for this triple
direct_import_mods = moduleEnvElts (imp_mods imports)
--
-- BUG WARNING: does not deal correctly with multiple imports of the same module
-- becuase direct_import_mods has only one entry per module
- unused_imp_mods = [(mod,loc) | (mod,imp,loc) <- direct_import_mods,
+ unused_imp_mods = [(mod,loc) | (mod,no_imp,loc) <- direct_import_mods,
not (mod `elemFM` minimal_imports1),
mod /= pRELUDE,
- imp /= Just False]
- -- The Just False part is not to complain about
+ not no_imp]
+ -- The not no_imp part is not to complain about
-- import M (), which is an idiom for importing
-- instance declarations
-- So the starting point is all things that are in scope as 'M.x',
-- which is what this field tells us.
- imp_mods :: ModuleEnv (Module, Maybe Bool, SrcSpan),
+ imp_mods :: ModuleEnv (Module, Bool, SrcSpan),
-- Domain is all directly-imported modules
- -- Maybe value answers the question "is the import restricted?"
- -- Nothing => unrestricted import (e.g., "import Foo")
- -- Just True => restricted import, at least one entity (e.g., "import Foo(x)")
- -- Just False => fully restricted import (e.g., "import Foo ()")
- --
- -- A distinction is made between the first and the third in order
- -- to more precisely emit warnings about unused imports.
+ -- Bool means:
+ -- True => import was "import Foo ()"
+ -- False => import was some other form
--
-- We need the Module in the range because we can't get
-- the keys of a ModuleEnv
-- Used
-- (a) to help construct the usage information in
- -- the interface file; if we import everything we
- -- need to recompile if the module version changes
+ -- the interface file; if we import somethign we
+ -- need to recompile if the export version changes
-- (b) to specify what child modules to initialise
imp_dep_mods :: ModuleEnv (Module, IsBootInterface),