[project @ 2002-11-06 12:49:47 by simonpj]
[ghc-hetmet.git] / ghc / compiler / main / HscTypes.lhs
index 58268d5..4214c69 100644 (file)
@@ -32,8 +32,8 @@ module HscTypes (
        extendTypeEnvList, extendTypeEnvWithIds,
        typeEnvElts, typeEnvClasses, typeEnvTyCons, typeEnvIds,
 
-       ImportedModuleInfo, WhetherHasOrphans, ImportVersion, WhatsImported(..),
-       IsBootInterface, DeclsMap,
+       WhetherHasOrphans, IsBootInterface, DeclsMap, Usage(..), 
+       Dependencies(..), noDependencies,
        IfaceInsts, IfaceRules, GatedDecl, GatedDecls, GateFn, 
        NameCache(..), OrigNameCache, OrigIParamCache,
        Avails, availsToNameSet, availName, availNames,
@@ -81,15 +81,17 @@ import CoreSyn              ( CoreBind )
 import Id              ( Id )
 import Class           ( Class, classSelIds )
 import TyCon           ( TyCon, isNewTyCon, tyConGenIds, tyConSelIds, tyConDataCons_maybe )
+import Type            ( TyThing(..), isTyClThing )
 import DataCon         ( dataConWorkId, dataConWrapId )
-import Packages                ( PackageName, preludePackage )
+import Packages                ( PackageName, basePackage )
 import CmdLineOpts     ( DynFlags )
 
 import BasicTypes      ( Version, initialVersion, IPName,
                          Fixity, FixitySig(..), defaultFixity )
 
-import HsSyn           ( DeprecTxt, TyClDecl, InstDecl, RuleDecl, 
-                         tyClDeclName, ifaceRuleDeclName, tyClDeclNames )
+import HsSyn           ( DeprecTxt, TyClDecl, InstDecl, RuleDecl,
+                         tyClDeclName, ifaceRuleDeclName, tyClDeclNames,
+                         instDeclDFun )
 import RnHsSyn         ( RenamedTyClDecl, RenamedRuleDecl, RenamedInstDecl )
 
 import CoreSyn         ( IdCoreRule )
@@ -145,14 +147,12 @@ data HomeModInfo = HomeModInfo { hm_iface    :: ModIface,
 Simple lookups in the symbol table.
 
 \begin{code}
-lookupIface :: HomePackageTable -> PackageIfaceTable -> Name -> Maybe ModIface
+lookupIface :: HomePackageTable -> PackageIfaceTable -> Module -> Maybe ModIface
 -- We often have two IfaceTables, and want to do a lookup
-lookupIface hpt pit name
+lookupIface hpt pit mod
   = case lookupModuleEnv hpt mod of
        Just mod_info -> Just (hm_iface mod_info)
        Nothing       -> lookupModuleEnv pit mod
-  where
-    mod = nameModule name
 
 lookupIfaceByModName :: HomePackageTable -> PackageIfaceTable -> ModuleName -> Maybe ModIface
 -- We often have two IfaceTables, and want to do a lookup
@@ -192,15 +192,20 @@ data ModIface
    = ModIface {
         mi_module   :: !Module,
        mi_package  :: !PackageName,        -- Which package the module comes from
-        mi_version  :: !VersionInfo,       -- Module version number
+        mi_version  :: !VersionInfo,       -- Version info for everything in this module
         mi_orphan   :: !WhetherHasOrphans,  -- Whether this module has orphans
        mi_boot     :: !IsBootInterface,    -- Read from an hi-boot file?
 
-        mi_usages   :: [ImportVersion Name],
+       mi_deps     :: Dependencies,
+               -- This is consulted for directly-imported modules, but
+               -- not for anything else
+
+        mi_usages   :: [Usage Name],
                -- Usages; kept sorted so that it's easy to decide
                -- whether to write a new iface file (changing usages
                -- doesn't affect the version of this module)
                -- NOT STRICT!  we read this field lazily from the interface file
+               -- It is *only* consulted by the recompilation checker
 
         mi_exports  :: ![ExportItem],
                -- What it exports Kept sorted by (mod,occ), to make
@@ -228,8 +233,6 @@ data ModDetails
         md_rules    :: ![IdCoreRule]   -- Domain may include Ids from other modules
      }
 
-
-
 -- A ModGuts is carried through the compiler, accumulating stuff as it goes
 -- There is only one ModGuts at any time, the one for the module
 -- being compiled right now.  Once it is compiled, a ModIface and 
@@ -238,10 +241,11 @@ data ModDetails
 data ModGuts
   = ModGuts {
         mg_module   :: !Module,
-       mg_exports  :: !Avails,                 -- What it exports
-       mg_usages   :: ![ImportVersion Name],   -- What it imports, directly or otherwise
-                                               -- ...exactly as in ModIface
-       mg_dir_imps :: ![Module],               -- Directly imported modules
+       mg_exports  :: !Avails,         -- What it exports
+       mg_deps     :: !Dependencies,   -- What is below it, directly or otherwise
+       mg_dir_imps :: ![Module],       -- Directly-imported modules; used to
+                                       --      generate initialisation code
+       mg_usages   :: ![Usage Name],   -- Version info for what it needed
 
         mg_rdr_env  :: !GlobalRdrEnv,  -- Top-level lexical environment
        mg_fix_env  :: !FixityEnv,      -- Fixity env, for things declared in this module
@@ -305,22 +309,25 @@ data IfaceDecls = IfaceDecls { dcl_tycl  :: [RenamedTyClDecl],    -- Sorted
                               dcl_insts :: [RenamedInstDecl] } -- Unsorted
 
 mkIfaceDecls :: [RenamedTyClDecl] -> [RenamedRuleDecl] -> [RenamedInstDecl] -> IfaceDecls
+-- Sort to put them in canonical order for version comparison
 mkIfaceDecls tycls rules insts
   = IfaceDecls { dcl_tycl  = sortLt lt_tycl tycls,
                 dcl_rules = sortLt lt_rule rules,
-                dcl_insts = insts }
+                dcl_insts = sortLt lt_inst insts }
   where
     d1 `lt_tycl` d2 = tyClDeclName      d1 < tyClDeclName      d2
     r1 `lt_rule` r2 = ifaceRuleDeclName r1 < ifaceRuleDeclName r2
+    i1 `lt_inst` i2 = instDeclDFun      i1 < instDeclDFun      i2
 \end{code}
 
 \begin{code}
 emptyModIface :: Module -> ModIface
 emptyModIface mod
   = ModIface { mi_module   = mod,
-              mi_package  = preludePackage, -- XXX fully bogus
+              mi_package  = basePackage, -- XXX fully bogus
               mi_version  = initialVersionInfo,
               mi_usages   = [],
+              mi_deps     = noDependencies,
               mi_orphan   = False,
               mi_boot     = False,
               mi_exports  = [],
@@ -352,7 +359,8 @@ data ParsedIface
       pi_pkg       :: PackageName,
       pi_vers     :: Version,                          -- Module version number
       pi_orphan    :: WhetherHasOrphans,               -- Whether this module has orphans
-      pi_usages           :: [ImportVersion OccName],          -- Usages
+      pi_deps      :: Dependencies,                    -- What it depends on
+      pi_usages           :: [Usage OccName],                  -- Usages
       pi_exports   :: (Version, [RdrExportItem]),      -- Exports
       pi_decls    :: [(Version, TyClDecl RdrName)],    -- Local definitions
       pi_fixity           :: [FixitySig RdrName],              -- Local fixity declarations,
@@ -406,26 +414,6 @@ icPrintUnqual ictxt = unQualInScope (ic_rn_gbl_env ictxt)
 %************************************************************************
 
 \begin{code}
-data TyThing = AnId   Id
-            | ATyCon TyCon
-            | AClass Class
-
-isTyClThing :: TyThing -> Bool
-isTyClThing (ATyCon _) = True
-isTyClThing (AClass _) = True
-isTyClThing (AnId   _) = False
-
-instance NamedThing TyThing where
-  getName (AnId id)   = getName id
-  getName (ATyCon tc) = getName tc
-  getName (AClass cl) = getName cl
-
-instance Outputable TyThing where
-  ppr (AnId   id) = ptext SLIT("AnId")   <+> ppr id
-  ppr (ATyCon tc) = ptext SLIT("ATyCon") <+> ppr tc
-  ppr (AClass cl) = ptext SLIT("AClass") <+> ppr cl
-
-
 typeEnvElts    :: TypeEnv -> [TyThing]
 typeEnvClasses :: TypeEnv -> [Class]
 typeEnvTyCons  :: TypeEnv -> [TyCon]
@@ -623,33 +611,35 @@ type WhetherHasOrphans   = Bool
        --      * a transformation rule in a module other than the one defining
        --              the function in the head of the rule.
 
-type IsBootInterface     = Bool
-
-type ImportVersion name  = (ModuleName, WhetherHasOrphans, IsBootInterface, WhatsImported name)
+type IsBootInterface = Bool
 
-data WhatsImported name  = NothingAtAll                        -- The module is below us in the
-                                                       -- hierarchy, but we import nothing
-                                                       -- Used for orphan modules, so they appear
-                                                       -- in the usage list
-
-                        | Everything Version           -- Used for modules from other packages;
-                                                       -- we record only the module's version number
-
-                        | Specifically 
-                               Version                 -- Module version
-                               (Maybe Version)         -- Export-list version, if we depend on it
-                               [(name,Version)]        -- List guaranteed non-empty
-                               Version                 -- Rules version
-
-                        deriving( Eq )
-       -- 'Specifically' doesn't let you say "I imported f but none of the rules in
+-- Dependency info about modules and packages below this one
+-- in the import hierarchy.  See TcRnTypes.ImportAvails for details.
+--
+-- Invariant: the dependencies of a module M never includes M
+data Dependencies
+  = Deps { dep_mods  :: [(ModuleName,IsBootInterface)],        -- Home-package module dependencies
+          dep_pkgs  :: [PackageName],                  -- External package dependencies
+          dep_orphs :: [ModuleName] }                  -- Orphan modules (whether home or external pkg)
+
+noDependencies :: Dependencies
+noDependencies = Deps [] [] []
+         
+data Usage name 
+  = Usage { usg_name     :: ModuleName,                -- Name of the module
+           usg_mod      :: Version,            -- Module version
+           usg_exports  :: Maybe Version,      -- Export-list version, if we depend on it
+           usg_entities :: [(name,Version)],   -- Sorted by occurrence name
+           usg_rules    :: Version             -- Rules version
+    }      deriving( Eq )
+       -- This type doesn't let you say "I imported f but none of the rules in
        -- the module". If you use anything in the module you get its rule version
        -- So if the rules change, you'll recompile, even if you don't use them.
        -- This is easy to implement, and it's safer: you might not have used the rules last
        -- 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:
-       --      we imported the module without saying exactly what we imported
+       --      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.
 \end{code}
@@ -693,11 +683,6 @@ data ExternalPackageState
                --      * Fixities
                --      * Deprecations
 
-       eps_imp_mods :: !ImportedModuleInfo,
-               -- Modules that we know something about, because they are mentioned
-               -- in interface files, BUT which we have not loaded yet.  
-               -- No module is both in here and in the PIT
-
        eps_PTE :: !PackageTypeEnv,             -- Domain = external-package modules
 
        eps_inst_env :: !PackageInstEnv,        -- The total InstEnv accumulated from
@@ -749,20 +734,14 @@ data NameCache
                -- Ensures that one implicit parameter name gets one unique
    }
 
-type OrigNameCache   = FiniteMap (ModuleName,OccName) Name
-type OrigIParamCache = FiniteMap (IPName RdrName) (IPName Name)
-\end{code}
-
-@ImportedModuleInfo@ contains info ONLY about modules that have not yet 
-been loaded into the iPIT.  These modules are mentioned in interfaces we've
-already read, so we know a tiny bit about them, but we havn't yet looked
-at the interface file for the module itself.  It needs to persist across 
-invocations of the renamer, at least from Rename.checkOldIface to Rename.renameSource.
-And there's no harm in it persisting across multiple compilations.
+type OrigNameCache = ModuleEnv (Module, OccNameCache)
+       -- Maps a module *name* to a Module, 
+       -- plus the OccNameEnv fot that module
+type OccNameCache = FiniteMap OccName Name
+       -- Maps the OccName to a Name
+       -- A FiniteMap because OccNames have a Namespace/Faststring pair
 
-\begin{code}
-type ImportedModuleInfo 
-    = FiniteMap ModuleName (WhetherHasOrphans, IsBootInterface)
+type OrigIParamCache = FiniteMap (IPName RdrName) (IPName Name)
 \end{code}
 
 A DeclsMap contains a binding for each Name in the declaration
@@ -993,6 +972,6 @@ pprNameProvenance (GRE {gre_name = name, gre_prov = prov})
 ppr_reason ImplicitImport        = ptext SLIT("implicitly imported")
 ppr_reason (UserImport mod loc _) = ptext SLIT("imported from") <+> ppr mod <+> ptext SLIT("at") <+> ppr loc
 
-ppr_defn loc | isGoodSrcLoc loc = parens (ptext SLIT("at") <+> ppr loc)
+ppr_defn loc | isGoodSrcLoc loc = parens (ptext SLIT("defined at") <+> ppr loc)
             | otherwise        = empty
 \end{code}