[project @ 2002-10-24 14:17:46 by simonpj]
authorsimonpj <unknown>
Thu, 24 Oct 2002 14:17:53 +0000 (14:17 +0000)
committersimonpj <unknown>
Thu, 24 Oct 2002 14:17:53 +0000 (14:17 +0000)
------------------------------------------
1. New try and module and package dependencies
2. OrigNameCache always contains final info
------------------------------------------

These things nearly complete sorting out the incremental
linking problem that started us off!

1. This commit separates two kinds of information:

  (a) HscTypes.Dependencies:
What (i)  home-package modules, and
     (ii) other packages
      this module depends on, transitively.

      That is, to link the module, it should be enough
      to link the dependent modules and packages (plus
      any C stubs etc).

      Along with this info we record whether the dependent module
      is (a) a boot interface or (b) an orphan module.  So in
      fact (i) can contain non-home-package modules, namely the
      orphan ones in other packages (sigh).

  (b) HscTypes.Usage:
      What version of imported things were used to
      actually compile the module.  This info is used for
      recompilation control only.

2. The Finder now returns a correct Module (incl package indicator)
first time, so we can install the absolutely final Name in the
OrigNameCache when we first come across an occurrence of that name,
even if it's only an occurrence in an unfolding in some other interface
file.  This is much tidier.

As a result Module.lhs is much cleaner
No DunnoYet
No mkVanillaModule
ALl very joyful stuff.

24 files changed:
ghc/compiler/basicTypes/Module.lhs
ghc/compiler/basicTypes/Name.lhs
ghc/compiler/deSugar/Desugar.lhs
ghc/compiler/deSugar/DsMeta.hs
ghc/compiler/hsSyn/HsDecls.lhs
ghc/compiler/ilxGen/IlxGen.lhs
ghc/compiler/main/BinIface.hs
ghc/compiler/main/DriverPipeline.hs
ghc/compiler/main/DriverState.hs
ghc/compiler/main/HscMain.lhs
ghc/compiler/main/HscTypes.lhs
ghc/compiler/main/MkIface.lhs
ghc/compiler/main/Packages.lhs
ghc/compiler/main/TidyPgm.lhs
ghc/compiler/parser/Parser.y
ghc/compiler/prelude/PrelNames.lhs
ghc/compiler/prelude/TysWiredIn.lhs
ghc/compiler/rename/RnEnv.lhs
ghc/compiler/rename/RnHiFiles.lhs
ghc/compiler/rename/RnIfaces.lhs
ghc/compiler/rename/RnNames.lhs
ghc/compiler/typecheck/TcRnDriver.lhs
ghc/compiler/typecheck/TcRnMonad.lhs
ghc/compiler/typecheck/TcRnTypes.lhs

index d7d90f6..c00b8ee 100644 (file)
@@ -56,9 +56,8 @@ module Module
     , moduleString             -- :: Module -> EncodedString
     , moduleUserString         -- :: Module -> UserString
 
-    , mkVanillaModule          -- :: ModuleName -> Module
-    , isVanillaModule          -- :: Module -> Bool
-    , mkPrelModule             -- :: UserString -> Module
+    , mkBasePkgModule          -- :: UserString -> Module
+    , mkThPkgModule            -- :: UserString -> Module
     , mkHomeModule             -- :: ModuleName -> Module
     , isHomeModule             -- :: Module -> Bool
     , mkPackageModule          -- :: ModuleName -> Module
@@ -84,7 +83,7 @@ module Module
 #include "HsVersions.h"
 import OccName
 import Outputable
-import Packages                ( PackageName, preludePackage )
+import Packages                ( PackageName, basePackage, thPackage )
 import CmdLineOpts     ( opt_InPackage )
 import FastString      ( FastString )
 import Unique          ( Uniquable(..) )
@@ -118,24 +117,13 @@ renamer href here.)
 \begin{code}
 data Module = Module ModuleName !PackageInfo
 
-instance Binary Module where
-   put_ bh (Module m p) = put_ bh m
-   get bh = do m <- get bh; return (Module m DunnoYet)
-
 data PackageInfo
   = ThisPackage                                -- A module from the same package 
                                        -- as the one being compiled
   | AnotherPackage                     -- A module from a different package
 
-  | DunnoYet   -- This is used when we don't yet know
-               -- Main case: we've come across Foo.x in an interface file
-               -- but we havn't yet opened Foo.hi.  We need a Name for Foo.x
-               -- Later on (in RnEnv.newTopBinder) we'll update the cache
-               -- to have the right PackageName
-
 packageInfoPackage :: PackageInfo -> PackageName
 packageInfoPackage ThisPackage        = opt_InPackage
-packageInfoPackage DunnoYet          = FSLIT("<?>")
 packageInfoPackage AnotherPackage     = FSLIT("<pkg>")
 
 instance Outputable PackageInfo where
@@ -274,13 +262,21 @@ pprModule (Module mod p) = getPprStyle $ \ sty ->
 
 
 \begin{code}
-mkPrelModule :: ModuleName -> Module
-mkPrelModule mod_nm
+mkBasePkgModule :: ModuleName -> Module
+mkBasePkgModule mod_nm
+  = Module mod_nm pack_info
+  where
+    pack_info
+      | opt_InPackage == basePackage = ThisPackage
+      | otherwise                   = AnotherPackage
+
+mkThPkgModule :: ModuleName -> Module
+mkThPkgModule mod_nm
   = Module mod_nm pack_info
   where
     pack_info
-      | opt_InPackage == preludePackage = ThisPackage
-      | otherwise                      = AnotherPackage
+      | opt_InPackage == thPackage = ThisPackage
+      | otherwise                 = AnotherPackage
 
 mkHomeModule :: ModuleName -> Module
 mkHomeModule mod_nm = Module mod_nm ThisPackage
@@ -292,16 +288,6 @@ isHomeModule _                       = False
 mkPackageModule :: ModuleName -> Module
 mkPackageModule mod_nm = Module mod_nm AnotherPackage
 
--- Used temporarily when we first come across Foo.x in an interface
--- file, but before we've opened Foo.hi.
--- (Until we've opened Foo.hi we don't know what the Package is.)
-mkVanillaModule :: ModuleName -> Module
-mkVanillaModule name = Module name DunnoYet
-
-isVanillaModule :: Module -> Bool
-isVanillaModule (Module nm DunnoYet) = True
-isVanillaModule _                       = False
-
 moduleString :: Module -> EncodedString
 moduleString (Module (ModuleName fs) _) = unpackFS fs
 
index a8117fb..07aaad0 100644 (file)
@@ -34,7 +34,7 @@ module Name (
 #include "HsVersions.h"
 
 import OccName         -- All of it
-import Module          ( Module, ModuleName, moduleName, mkVanillaModule, isHomeModule )
+import Module          ( Module, ModuleName, moduleName, isHomeModule )
 import CmdLineOpts     ( opt_Static )
 import SrcLoc          ( noSrcLoc, isWiredInLoc, wiredInSrcLoc, SrcLoc )
 import Unique          ( Unique, Uniquable(..), getKey, pprUnique )
@@ -177,11 +177,11 @@ mkInternalName uniq occ loc = Name { n_uniq = uniq, n_sort = Internal, n_occ = o
 
 mkExternalName :: Unique -> Module -> OccName -> SrcLoc -> Name
 mkExternalName uniq mod occ loc = Name { n_uniq = uniq, n_sort = External mod,
-                                      n_occ = occ, n_loc = loc }
+                                        n_occ = occ, n_loc = loc }
 
-mkKnownKeyExternalName :: ModuleName -> OccName -> Unique -> Name
+mkKnownKeyExternalName :: Module -> OccName -> Unique -> Name
 mkKnownKeyExternalName mod occ uniq
-  = mkExternalName uniq (mkVanillaModule mod) occ noSrcLoc
+  = mkExternalName uniq mod occ noSrcLoc
 
 mkWiredInName :: Module -> OccName -> Unique -> Name
 mkWiredInName mod occ uniq = mkExternalName uniq mod occ wiredInSrcLoc
index efb2cd4..a918590 100644 (file)
@@ -15,7 +15,7 @@ import HscTypes               ( ModGuts(..), ModGuts, HscEnv(..), ExternalPackageState(..),
 import HsSyn           ( MonoBinds, RuleDecl(..), RuleBndr(..), 
                          HsExpr(..), HsBinds(..), MonoBinds(..) )
 import TcHsSyn         ( TypecheckedRuleDecl, TypecheckedHsExpr )
-import TcRnTypes       ( TcGblEnv(..), ImportAvails(imp_mods) )
+import TcRnTypes       ( TcGblEnv(..), ImportAvails(..) )
 import MkIface         ( mkUsageInfo )
 import Id              ( Id )
 import CoreSyn
@@ -89,9 +89,11 @@ deSugar hsc_env pcs
                  (printDump (ppr_ds_rules ds_rules))
 
        ; let 
+            deps = (moduleEnvElts (dep_mods imports), dep_pkgs imports)
             mod_guts = ModGuts {       
                mg_module   = mod,
                mg_exports  = exports,
+               mg_deps     = deps,
                mg_usages   = mkUsageInfo hsc_env eps imports usages,
                mg_dir_imps = [m | (m,_) <- moduleEnvElts (imp_mods imports)],
                mg_rdr_env  = rdr_env,
index d138a62..caea804 100644 (file)
@@ -42,10 +42,16 @@ import HsSyn          ( Pat(..), HsExpr(..), Stmt(..), HsLit(..), HsOverLit(..),
                    toHsType
                  )
 
-import PrelNames  ( mETA_META_Name, varQual, tcQual )
+import PrelNames  ( mETA_META_Name )
 import MkIface   ( ifaceTyThing )
 import Name       ( Name, nameOccName, nameModule )
 import OccName   ( isDataOcc, isTvOcc, occNameUserString )
+-- To avoid clashes with DsMeta.varName we must make a local alias for OccName.varName
+-- we do this by removing varName from the import of OccName above, making
+-- a qualified instance of OccName and using OccNameAlias.varName where varName
+-- ws previously used in this file.
+import qualified OccName( varName, tcName )
+
 import Module    ( moduleUserString )
 import Id         ( Id, idType )
 import NameEnv
@@ -963,90 +969,99 @@ templateHaskellNames
                decTyConName, typTyConName ]
 
 
-
-intLName       = varQual mETA_META_Name FSLIT("intL")          intLIdKey
-charLName      = varQual mETA_META_Name FSLIT("charL")         charLIdKey
-plitName       = varQual mETA_META_Name FSLIT("plit")          plitIdKey
-pvarName       = varQual mETA_META_Name FSLIT("pvar")          pvarIdKey
-ptupName       = varQual mETA_META_Name FSLIT("ptup")          ptupIdKey
-pconName       = varQual mETA_META_Name FSLIT("pcon")          pconIdKey
-ptildeName     = varQual mETA_META_Name FSLIT("ptilde")        ptildeIdKey
-paspatName     = varQual mETA_META_Name FSLIT("paspat")        paspatIdKey
-pwildName      = varQual mETA_META_Name FSLIT("pwild")         pwildIdKey
-varName        = varQual mETA_META_Name FSLIT("var")           varIdKey
-conName        = varQual mETA_META_Name FSLIT("con")           conIdKey
-litName        = varQual mETA_META_Name FSLIT("lit")           litIdKey
-appName        = varQual mETA_META_Name FSLIT("app")           appIdKey
-infixEName     = varQual mETA_META_Name FSLIT("infixE")        infixEIdKey
-lamName        = varQual mETA_META_Name FSLIT("lam")           lamIdKey
-tupName        = varQual mETA_META_Name FSLIT("tup")           tupIdKey
-doEName        = varQual mETA_META_Name FSLIT("doE")           doEIdKey
-compName       = varQual mETA_META_Name FSLIT("comp")          compIdKey
-listExpName    = varQual mETA_META_Name FSLIT("listExp")       listExpIdKey
-condName       = varQual mETA_META_Name FSLIT("cond")          condIdKey
-letEName       = varQual mETA_META_Name FSLIT("letE")          letEIdKey
-caseEName      = varQual mETA_META_Name FSLIT("caseE")         caseEIdKey
-infixAppName   = varQual mETA_META_Name FSLIT("infixApp")      infixAppIdKey
-sectionLName   = varQual mETA_META_Name FSLIT("sectionL")      sectionLIdKey
-sectionRName   = varQual mETA_META_Name FSLIT("sectionR")      sectionRIdKey
-guardedName    = varQual mETA_META_Name FSLIT("guarded")       guardedIdKey
-normalName     = varQual mETA_META_Name FSLIT("normal")        normalIdKey
-bindStName     = varQual mETA_META_Name FSLIT("bindSt")        bindStIdKey
-letStName      = varQual mETA_META_Name FSLIT("letSt")         letStIdKey
-noBindStName   = varQual mETA_META_Name FSLIT("noBindSt")      noBindStIdKey
-parStName      = varQual mETA_META_Name FSLIT("parSt")         parStIdKey
-fromName       = varQual mETA_META_Name FSLIT("from")          fromIdKey
-fromThenName   = varQual mETA_META_Name FSLIT("fromThen")      fromThenIdKey
-fromToName     = varQual mETA_META_Name FSLIT("fromTo")        fromToIdKey
-fromThenToName = varQual mETA_META_Name FSLIT("fromThenTo")    fromThenToIdKey
-liftName       = varQual mETA_META_Name FSLIT("lift")          liftIdKey
-gensymName     = varQual mETA_META_Name FSLIT("gensym")        gensymIdKey
-returnQName    = varQual mETA_META_Name FSLIT("returnQ")       returnQIdKey
-bindQName      = varQual mETA_META_Name FSLIT("bindQ")         bindQIdKey
+varQual  = mk_known_key_name OccName.varName
+tcQual   = mk_known_key_name OccName.tcName
+
+thModule :: Module
+-- NB: the THSyntax module comes from the "haskell-src" package
+thModule = mkThPkgModule mETA_META_Name
+
+mk_known_key_name space mod str uniq 
+  = mkKnownKeyExternalName thModule (mkOccFS space str) uniq 
+
+intLName       = varQual FSLIT("intL")          intLIdKey
+charLName      = varQual FSLIT("charL")         charLIdKey
+plitName       = varQual FSLIT("plit")          plitIdKey
+pvarName       = varQual FSLIT("pvar")          pvarIdKey
+ptupName       = varQual FSLIT("ptup")          ptupIdKey
+pconName       = varQual FSLIT("pcon")          pconIdKey
+ptildeName     = varQual FSLIT("ptilde")        ptildeIdKey
+paspatName     = varQual FSLIT("paspat")        paspatIdKey
+pwildName      = varQual FSLIT("pwild")         pwildIdKey
+varName        = varQual FSLIT("var")           varIdKey
+conName        = varQual FSLIT("con")           conIdKey
+litName        = varQual FSLIT("lit")           litIdKey
+appName        = varQual FSLIT("app")           appIdKey
+infixEName     = varQual FSLIT("infixE")        infixEIdKey
+lamName        = varQual FSLIT("lam")           lamIdKey
+tupName        = varQual FSLIT("tup")           tupIdKey
+doEName        = varQual FSLIT("doE")           doEIdKey
+compName       = varQual FSLIT("comp")          compIdKey
+listExpName    = varQual FSLIT("listExp")       listExpIdKey
+condName       = varQual FSLIT("cond")          condIdKey
+letEName       = varQual FSLIT("letE")          letEIdKey
+caseEName      = varQual FSLIT("caseE")         caseEIdKey
+infixAppName   = varQual FSLIT("infixApp")      infixAppIdKey
+sectionLName   = varQual FSLIT("sectionL")      sectionLIdKey
+sectionRName   = varQual FSLIT("sectionR")      sectionRIdKey
+guardedName    = varQual FSLIT("guarded")       guardedIdKey
+normalName     = varQual FSLIT("normal")        normalIdKey
+bindStName     = varQual FSLIT("bindSt")        bindStIdKey
+letStName      = varQual FSLIT("letSt")         letStIdKey
+noBindStName   = varQual FSLIT("noBindSt")      noBindStIdKey
+parStName      = varQual FSLIT("parSt")         parStIdKey
+fromName       = varQual FSLIT("from")          fromIdKey
+fromThenName   = varQual FSLIT("fromThen")      fromThenIdKey
+fromToName     = varQual FSLIT("fromTo")        fromToIdKey
+fromThenToName = varQual FSLIT("fromThenTo")    fromThenToIdKey
+liftName       = varQual FSLIT("lift")          liftIdKey
+gensymName     = varQual FSLIT("gensym")        gensymIdKey
+returnQName    = varQual FSLIT("returnQ")       returnQIdKey
+bindQName      = varQual FSLIT("bindQ")         bindQIdKey
 
 -- type Mat = ...
-matchName      = varQual mETA_META_Name FSLIT("match")         matchIdKey
-
--- type Cls = ...
-clauseName     = varQual mETA_META_Name FSLIT("clause")        clauseIdKey
-
--- data Dec = ...
-funName        = varQual mETA_META_Name FSLIT("fun")           funIdKey
-valName        = varQual mETA_META_Name FSLIT("val")           valIdKey
-dataDName      = varQual mETA_META_Name FSLIT("dataD")         dataDIdKey
-classDName     = varQual mETA_META_Name FSLIT("classD")        classDIdKey
-instName       = varQual mETA_META_Name FSLIT("inst")          instIdKey
-protoName      = varQual mETA_META_Name FSLIT("proto")         protoIdKey
-
--- data Typ = ...
-tvarName       = varQual mETA_META_Name FSLIT("tvar")          tvarIdKey
-tconName       = varQual mETA_META_Name FSLIT("tcon")          tconIdKey
-tappName       = varQual mETA_META_Name FSLIT("tapp")          tappIdKey
-
--- data Tag = ...
-arrowTyConName = varQual mETA_META_Name FSLIT("arrowTyCon")   arrowIdKey
-tupleTyConName = varQual mETA_META_Name FSLIT("tupleTyCon")   tupleIdKey
-listTyConName  = varQual mETA_META_Name FSLIT("listTyCon")    listIdKey
-namedTyConName = varQual mETA_META_Name FSLIT("namedTyCon")   namedTyConIdKey
-
--- data Con = ...
-constrName     = varQual mETA_META_Name FSLIT("constr")        constrIdKey
-
-exprTyConName  = tcQual  mETA_META_Name FSLIT("Expr")                 exprTyConKey
-declTyConName  = tcQual  mETA_META_Name FSLIT("Decl")                 declTyConKey
-pattTyConName  = tcQual  mETA_META_Name FSLIT("Patt")                 pattTyConKey
-mtchTyConName  = tcQual  mETA_META_Name FSLIT("Mtch")                 mtchTyConKey
-clseTyConName  = tcQual  mETA_META_Name FSLIT("Clse")                 clseTyConKey
-stmtTyConName  = tcQual  mETA_META_Name FSLIT("Stmt")         stmtTyConKey
-consTyConName  = tcQual  mETA_META_Name FSLIT("Cons")                 consTyConKey
-typeTyConName  = tcQual  mETA_META_Name FSLIT("Type")                 typeTyConKey
-
-qTyConName     = tcQual  mETA_META_Name FSLIT("Q")            qTyConKey
-expTyConName   = tcQual  mETA_META_Name FSLIT("Exp")          expTyConKey
-decTyConName   = tcQual  mETA_META_Name FSLIT("Dec")          decTyConKey
-typTyConName   = tcQual  mETA_META_Name FSLIT("Typ")          typTyConKey
-matTyConName   = tcQual  mETA_META_Name FSLIT("Mat")          matTyConKey
-clsTyConName   = tcQual  mETA_META_Name FSLIT("Cls")          clsTyConKey
+matchName      = varQual FSLIT("match")         matchIdKey
+                        
+-- type Cls = ...       
+clauseName     = varQual FSLIT("clause")        clauseIdKey
+                        
+-- data Dec = ...       
+funName        = varQual FSLIT("fun")           funIdKey
+valName        = varQual FSLIT("val")           valIdKey
+dataDName      = varQual FSLIT("dataD")         dataDIdKey
+classDName     = varQual FSLIT("classD")        classDIdKey
+instName       = varQual FSLIT("inst")          instIdKey
+protoName      = varQual FSLIT("proto")         protoIdKey
+                        
+-- data Typ = ...       
+tvarName       = varQual FSLIT("tvar")          tvarIdKey
+tconName       = varQual FSLIT("tcon")          tconIdKey
+tappName       = varQual FSLIT("tapp")          tappIdKey
+                        
+-- data Tag = ...       
+arrowTyConName = varQual FSLIT("arrowTyCon")   arrowIdKey
+tupleTyConName = varQual FSLIT("tupleTyCon")   tupleIdKey
+listTyConName  = varQual FSLIT("listTyCon")    listIdKey
+namedTyConName = varQual FSLIT("namedTyCon")   namedTyConIdKey
+                        
+-- data Con = ...       
+constrName     = varQual FSLIT("constr")        constrIdKey
+                        
+exprTyConName  = tcQual  FSLIT("Expr")                exprTyConKey
+declTyConName  = tcQual  FSLIT("Decl")                declTyConKey
+pattTyConName  = tcQual  FSLIT("Patt")                pattTyConKey
+mtchTyConName  = tcQual  FSLIT("Mtch")                mtchTyConKey
+clseTyConName  = tcQual  FSLIT("Clse")                clseTyConKey
+stmtTyConName  = tcQual  FSLIT("Stmt")                stmtTyConKey
+consTyConName  = tcQual  FSLIT("Cons")                consTyConKey
+typeTyConName  = tcQual  FSLIT("Type")                typeTyConKey
+                        
+qTyConName     = tcQual  FSLIT("Q")           qTyConKey
+expTyConName   = tcQual  FSLIT("Exp")                 expTyConKey
+decTyConName   = tcQual  FSLIT("Dec")                 decTyConKey
+typTyConName   = tcQual  FSLIT("Typ")                 typTyConKey
+matTyConName   = tcQual  FSLIT("Mat")                 matTyConKey
+clsTyConName   = tcQual  FSLIT("Cls")                 clsTyConKey
 
 --     TyConUniques available: 100-119
 --     Check in PrelNames if you want to change this
index 5c806a6..ca0e324 100644 (file)
@@ -18,7 +18,7 @@ module HsDecls (
        tyClDeclName, tyClDeclNames, tyClDeclTyVars,
        isClassDecl, isSynDecl, isDataDecl, isIfaceSigDecl, 
        isTypeOrClassDecl, countTyClDecls,
-       isSourceInstDecl, ifaceRuleDeclName,
+       isSourceInstDecl, instDeclDFun, ifaceRuleDeclName,
        conDetailsTys,
        collectRuleBndrSigTys, isSrcRule
     ) where
@@ -649,6 +649,9 @@ data InstDecl name
 
 isSourceInstDecl :: InstDecl name -> Bool
 isSourceInstDecl (InstDecl _ _ _ maybe_dfun _) = isNothing maybe_dfun
+
+instDeclDFun :: InstDecl name -> Maybe name
+instDeclDFun (InstDecl _ _ _ df _) = df        -- A Maybe, but that's ok
 \end{code}
 
 \begin{code}
index b2c424c..9c71ab1 100644 (file)
@@ -31,7 +31,7 @@ import Name           ( nameModule, nameOccName, isExternalName, isInternalName, NamedThi
 import Subst                   ( substTyWith )
 
 import Module          ( Module, PackageName, ModuleName, moduleName, 
-                          modulePackage, preludePackage,
+                          modulePackage, basePackage,
                          isHomeModule, isVanillaModule,
                           pprModuleName, mkHomeModule, mkModuleName
                        )
@@ -168,7 +168,7 @@ importsName env n
 
 
 importsPrelude | inPrelude = addModuleImpInfo (mkModuleName "PrelGHC")
-              | otherwise = addPackageImpInfo preludePackage
+              | otherwise = addPackageImpInfo basePackage
 
 
 importsType :: IlxEnv -> Type -> ImportsInfo -> ImportsInfo
@@ -1465,7 +1465,7 @@ nameReference env n
 -- gets things working for the scenario "standard library linked as one
 -- assembly with multiple modules + a one module program running on top of this"
 -- Same applies to all other mentions of Vailla modules in this file
-  | isVanillaModule (nameModule n)  && not inPrelude =  preludePackageReference
+  | isVanillaModule (nameModule n)  && not inPrelude =  basePackageReference
   | isVanillaModule (nameModule n)  && inPrelude =   moduleNameReference (moduleName (nameModule n))
 -- end hack
   | otherwise = packageReference (modulePackage (nameModule n))
@@ -1477,13 +1477,13 @@ moduleReference env m
   | ilxEnvModule env   == m = text ""
   | isHomeModule m = moduleNameReference (moduleName m)
   -- See hack above
-  | isVanillaModule m && not inPrelude =  preludePackageReference
+  | isVanillaModule m && not inPrelude =  basePackageReference
   | isVanillaModule m && inPrelude =  moduleNameReference (moduleName m)
   -- end hack
   | otherwise  =  packageReference (modulePackage m)
 
-preludePackageReference = packageReference preludePackage
-inPrelude = preludePackage == opt_InPackage
+basePackageReference = packageReference basePackage
+inPrelude = basePackage == opt_InPackage
 
 ------------------------------------------------
 -- This code is copied from absCSyn/CString.lhs,
@@ -1693,13 +1693,13 @@ prelGHCReference :: IlxTyFrag
 prelGHCReference env =
    if ilxEnvModule env == mkHomeModule (mkModuleName "PrelGHC") then empty
    else if inPrelude then moduleNameReference (mkModuleName "PrelGHC")
-   else preludePackageReference
+   else basePackageReference
 
 prelBaseReference :: IlxTyFrag
 prelBaseReference env =
    if ilxEnvModule env == mkHomeModule (mkModuleName "PrelBase") then empty
    else if inPrelude then moduleNameReference (mkModuleName "PrelBase")
-   else preludePackageReference
+   else basePackageReference
 
 repThread = ilxType "class [mscorlib]System.Threading.Thread /* ThreadId# */ "
 repByteArray = ilxType "unsigned int8[] /* ByteArr# */ "
index 8e461ca..c993257 100644 (file)
@@ -269,12 +269,13 @@ instance Binary ModIface where
   put_ bh iface =  do
        build_tag <- readIORef v_Build_tag
        put_ bh (show opt_HiVersion ++ build_tag)
-       p <- put_ bh (mi_module iface)
+       p <- put_ bh (moduleName (mi_module iface))
        put_ bh (mi_package iface)
        put_ bh (vers_module (mi_version iface))
        put_ bh (mi_orphan iface)
        -- no: mi_boot
-       lazyPut bh (map importVersionNameToOccName (mi_usages iface))
+       lazyPut bh (mi_deps iface)
+       lazyPut bh (map usageToOccName (mi_usages iface))
        put_ bh (vers_exports (mi_version iface),
                 map exportItemToRdrExportItem (mi_exports iface))
        put_ bh (declsToVersionedDecls (dcl_tycl (mi_decls iface))
@@ -309,14 +310,9 @@ deprecsToIfaceDeprecs (DeprecSome env) = Just (Right (nameEnvElts env))
 {-! for WhatsImported derive: Binary !-}
 
 -- For binary interfaces we need to convert the ImportVersion Names to OccNames
-importVersionNameToOccName :: ImportVersion Name -> ImportVersion OccName
-importVersionNameToOccName (mod, orphans, boot, what)
-  = (mod, orphans, boot, fiddle_with what)
-  where fiddle_with NothingAtAll = NothingAtAll
-       fiddle_with (Everything v) = Everything v
-       fiddle_with (Specifically v ev ns rv) = Specifically v ev ns' rv
-         where ns' = [ (nameOccName n, v) | (n,v) <- ns ]
-
+usageToOccName :: Usage Name -> Usage OccName
+usageToOccName usg
+  = usg { usg_entities = [ (nameOccName n, v) | (n,v) <- usg_entities usg ] }
 
 exportItemToRdrExportItem (mn, avails) 
   = (mn, map availInfoToRdrAvailInfo avails)
@@ -370,6 +366,7 @@ instance Binary ParsedIface where
        pkg_name    <- get bh
        module_ver  <- get bh
        orphan      <- get bh
+       deps        <- lazyGet bh
        usages      <- {-# SCC "bin_usages" #-} lazyGet bh
        exports     <- {-# SCC "bin_exports" #-} get bh
         tycl_decls  <- {-# SCC "bin_tycldecls" #-} get bh
@@ -382,6 +379,7 @@ instance Binary ParsedIface where
                 pi_pkg = pkg_name,
                 pi_vers = module_ver,
                 pi_orphan = orphan,
+                pi_deps = deps,
                 pi_usages = usages,
                 pi_exports = exports,
                 pi_decls = tycl_decls,
@@ -412,29 +410,23 @@ instance (Binary name) => Binary (GenAvailInfo name) where
                      ac <- get bh
                      return (AvailTC ab ac)
 
-instance (Binary name) => Binary (WhatsImported name) where
-    put_ bh NothingAtAll = do
-           putByte bh 0
-    put_ bh (Everything aa) = do
-           putByte bh 1
-           put_ bh aa
-    put_ bh (Specifically ab ac ad ae) = do
-           putByte bh 2
-           put_ bh ab
-           put_ bh ac
-           put_ bh ad
-           put_ bh ae
+instance (Binary name) => Binary (Usage name) where
+    put_ bh usg        = do 
+       put_ bh (usg_name     usg)
+       put_ bh (usg_mod      usg)
+       put_ bh (usg_exports  usg)
+       put_ bh (usg_entities usg)
+       put_ bh (usg_rules    usg)
+
     get bh = do
-           h <- getByte bh
-           case h of
-             0 -> do return NothingAtAll
-             1 -> do aa <- get bh
-                     return (Everything aa)
-             _ -> do ab <- get bh
-                     ac <- get bh
-                     ad <- get bh
-                     ae <- get bh
-                     return (Specifically ab ac ad ae)
+       nm    <- get bh
+       mod   <- get bh
+       exps  <- get bh
+       ents  <- get bh
+       rules <- get bh
+       return (Usage { usg_name = nm, usg_mod = mod,
+                       usg_exports = exps, usg_entities = ents,
+                       usg_rules = rules })
 
 instance Binary Activation where
     put_ bh NeverActive = do
index 53013fe..da6acd2 100644 (file)
@@ -1176,7 +1176,7 @@ staticLink o_files = do
        -- opts from -optl-<blah>
     extra_ld_opts <- getStaticOpts v_Opt_l
 
-    [rts_pkg, std_pkg] <- getPackageDetails [rtsPackage, preludePackage]
+    [rts_pkg, std_pkg] <- getPackageDetails [rtsPackage, basePackage]
 
     let extra_os = if static || no_hs_main
                    then []
@@ -1252,7 +1252,7 @@ doMkDLL o_files = do
        -- opts from -optdll-<blah>
     extra_ld_opts <- getStaticOpts v_Opt_dll
 
-    [rts_pkg, std_pkg] <- getPackageDetails [rtsPackage, preludePackage]
+    [rts_pkg, std_pkg] <- getPackageDetails [rtsPackage, basePackage]
 
     let extra_os = if static || no_hs_main
                    then []
index 1322915..c66fe89 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: DriverState.hs,v 1.83 2002/10/17 14:26:18 simonmar Exp $
+-- $Id: DriverState.hs,v 1.84 2002/10/24 14:17:49 simonpj Exp $
 --
 -- Settings for the driver
 --
@@ -18,7 +18,7 @@ import Packages               ( PackageConfig(..), PackageConfigMap,
                          PackageName, mkPackageName, packageNameString,
                          packageDependents,
                          mungePackagePaths, emptyPkgMap, extendPkgMap, lookupPkg,
-                         preludePackage, rtsPackage, haskell98Package  )
+                         basePackage, rtsPackage, haskell98Package  )
 import CmdLineOpts
 import DriverPhases
 import DriverUtil
@@ -489,7 +489,7 @@ getPackages :: IO [PackageName]
 getPackages = readIORef v_Packages
 
 initPackageList = [haskell98Package,
-                  preludePackage,
+                  basePackage,
                   rtsPackage]
 
 addPackage :: String -> IO ()
index 9ca6819..1f2cf06 100644 (file)
@@ -40,6 +40,7 @@ import Parser
 import Lex             ( ParseResult(..), ExtFlags(..), mkPState )
 import SrcLoc          ( mkSrcLoc )
 import TcRnDriver      ( checkOldIface, tcRnModule, tcRnExtCore, tcRnIface )
+import RnEnv           ( extendOrigNameCache )
 import Rules           ( emptyRuleBase )
 import PrelInfo                ( wiredInThingEnv, wiredInThings, knownKeyNames )
 import PrelRules       ( builtinRules )
@@ -57,7 +58,7 @@ import SimplStg               ( stg2stg )
 import CodeGen         ( codeGen )
 import CodeOutput      ( codeOutput )
 
-import Module          ( ModuleName, moduleName )
+import Module          ( ModuleName, moduleName, emptyModuleEnv )
 import CmdLineOpts
 import DriverPhases     ( isExtCore_file )
 import ErrUtils                ( dumpIfSet_dyn, showPass, printError )
@@ -692,7 +693,6 @@ initExternalPackageState
       eps_insts      = (emptyBag, 0),
       eps_inst_gates = emptyNameSet,
       eps_rules      = foldr add_rule (emptyBag, 0) builtinRules,
-      eps_imp_mods   = emptyFM,
 
       eps_PIT       = emptyPackageIfaceTable,
       eps_PTE       = wiredInThingEnv,
@@ -708,11 +708,11 @@ initExternalPackageState
           rdr_name   = nameRdrName name
           gate_fn vis_fn = vis_fn name -- Load the rule whenever name is visible
 
-initOrigNames :: FiniteMap (ModuleName,OccName) Name
+initOrigNames :: OrigNameCache
 initOrigNames 
-   = grab knownKeyNames `plusFM` grab (map getName wiredInThings)
-     where
-        grab names = foldl add emptyFM names
-        add env name 
-           = addToFM env (moduleName (nameModule name), nameOccName name) name
+   = insert knownKeyNames $
+     insert (map getName wiredInThings) $
+     emptyModuleEnv
+  where
+     insert names env = foldl extendOrigNameCache env names
 \end{code}
index 10b390d..586a4bd 100644 (file)
@@ -32,8 +32,7 @@ module HscTypes (
        extendTypeEnvList, extendTypeEnvWithIds,
        typeEnvElts, typeEnvClasses, typeEnvTyCons, typeEnvIds,
 
-       ImportedModuleInfo, WhetherHasOrphans, ImportVersion, WhatsImported(..),
-       IsBootInterface, DeclsMap,
+       WhetherHasOrphans, IsBootInterface, DeclsMap, Usage(..), Dependencies, 
        IfaceInsts, IfaceRules, GatedDecl, GatedDecls, GateFn, 
        NameCache(..), OrigNameCache, OrigIParamCache,
        Avails, availsToNameSet, availName, availNames,
@@ -83,14 +82,15 @@ 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 )
@@ -193,15 +193,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
@@ -229,8 +234,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 
@@ -239,10 +242,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
@@ -306,22 +310,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     = ([], []),
               mi_orphan   = False,
               mi_boot     = False,
               mi_exports  = [],
@@ -353,7 +360,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,
@@ -604,33 +612,30 @@ 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)
-
-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
+type IsBootInterface = Bool
 
-                        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
+type Dependencies
+  = ([(ModuleName, WhetherHasOrphans, IsBootInterface)], [PackageName])
+
+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}
@@ -674,11 +679,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
@@ -730,20 +730,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}
+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
 
-@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.
-
-\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
index c5ad766..9388e34 100644 (file)
@@ -7,7 +7,7 @@
 \begin{code}
 module MkIface ( 
        showIface, mkIface, mkUsageInfo,
-       pprIface, pprUsage, pprUsages, pprExports,
+       pprIface, 
        ifaceTyThing,
   ) where
 
@@ -22,17 +22,18 @@ import BasicTypes   ( NewOrData(..), Activation(..), FixitySig(..),
                        )
 import NewDemand       ( isTopSig )
 import TcRnMonad
+import TcRnTypes       ( ImportAvails(..) )
 import RnHsSyn         ( RenamedInstDecl, RenamedTyClDecl )
 import HscTypes                ( VersionInfo(..), ModIface(..), HomeModInfo(..),
                          ModGuts(..), ModGuts, 
                          GhciMode(..), HscEnv(..),
                          FixityEnv, lookupFixity, collectFixities,
                          IfaceDecls, mkIfaceDecls, dcl_tycl, dcl_rules, dcl_insts,
-                         TyThing(..), DFunId, 
+                         TyThing(..), DFunId, Dependencies,
                          Avails, AvailInfo, GenAvailInfo(..), availName, 
                          ExternalPackageState(..),
-                         WhatsImported(..), ParsedIface(..),
-                         ImportVersion, Deprecations(..), initialVersionInfo,
+                         ParsedIface(..), Usage(..),
+                         Deprecations(..), initialVersionInfo,
                          lookupVersion
                        )
 
@@ -59,7 +60,7 @@ import SrcLoc         ( noSrcLoc )
 import Module          ( Module, ModuleName, moduleNameFS, moduleName, isHomeModule,
                          ModLocation(..), mkSysModuleNameFS,
                          ModuleEnv, emptyModuleEnv, foldModuleEnv, lookupModuleEnv,
-                         extendModuleEnv_C, elemModuleSet, moduleEnvElts
+                         extendModuleEnv_C, elemModuleSet, moduleEnvElts, elemModuleEnv
                        )
 import Outputable
 import Util            ( sortLt, dropList, seqList )
@@ -70,7 +71,8 @@ import FiniteMap
 import FastString
 
 import Monad           ( when )
-import Maybe           ( catMaybes, isJust )
+import Maybe           ( catMaybes, isJust, isNothing )
+import Maybes          ( orElse )
 import IO              ( putStrLn )
 \end{code}
 
@@ -87,6 +89,7 @@ showIface filename = do
    parsed_iface <- Binary.getBinFileWithDict filename
    let ParsedIface{
       pi_mod=pi_mod, pi_pkg=pi_pkg, pi_vers=pi_vers,
+      pi_deps=pi_deps,
       pi_orphan=pi_orphan, pi_usages=pi_usages,
       pi_exports=pi_exports, pi_decls=pi_decls,
       pi_fixity=pi_fixity, pi_insts=pi_insts,
@@ -98,6 +101,7 @@ showIface filename = do
           <+> ptext SLIT("where"),
        -- no instance Outputable (WhatsImported):
        pprExports id (snd pi_exports),
+       pprDeps pi_deps,
        pprUsages  id pi_usages,
        hsep (map ppr_fix pi_fixity) <> semi,
        vcat (map ppr_inst pi_insts),
@@ -131,6 +135,7 @@ mkIface :: HscEnv
 mkIface hsc_env location maybe_old_iface 
        impl@ModGuts{ mg_module = this_mod,
                      mg_usages = usages,
+                     mg_deps   = deps,
                      mg_exports = exports,
                      mg_rdr_env = rdr_env,
                      mg_fix_env = fix_env,
@@ -144,6 +149,7 @@ mkIface hsc_env location maybe_old_iface
                iface_w_decls = ModIface { mi_module   = this_mod,
                                           mi_package  = opt_InPackage,
                                           mi_version  = initialVersionInfo,
+                                          mi_deps     = deps,
                                           mi_usages   = usages,
                                           mi_exports  = my_exports,
                                           mi_decls    = new_decls,
@@ -465,118 +471,77 @@ compiled with -O.  I think this is the case.]
 
 \begin{code}
 mkUsageInfo :: HscEnv -> ExternalPackageState
-           -> ImportAvails -> Usages 
-           -> [ImportVersion Name]
+           -> ImportAvails -> EntityUsage
+           -> [Usage Name]
 
 mkUsageInfo hsc_env eps
-           (ImportAvails { imp_mods = dir_imp_mods })
-           (Usages { usg_ext  = pkg_mods, 
-                     usg_home = home_names })
-  = let
-       hpt = hsc_HPT hsc_env
-       pit = eps_PIT eps
-
-       import_all_mods = [moduleName m | (m,True) <- moduleEnvElts dir_imp_mods]
-
-       -- mv_map groups together all the things imported and used
-       -- from a particular module in this package
-       -- We use a finite map because we want the domain
-       mv_map :: ModuleEnv [Name]
-       mv_map  = foldNameSet add_mv emptyModuleEnv home_names
-        add_mv name mv_map = extendModuleEnv_C add_item mv_map mod [name]
-                          where
-                            mod = nameModule name
-                            add_item names _ = name:names
-
-       -- In our usage list we record
-       --
-       --      a) Specifically: Detailed version info for imports
-       --         from modules in this package Gotten from iVSlurp plus
-       --         import_all_mods
-       --
-       --      b) Everything: Just the module version for imports
-       --         from modules in other packages Gotten from iVSlurp plus
-       --         import_all_mods
-       --
-       --      c) NothingAtAll: The name only of modules, Baz, in
-       --         this package that are 'below' us, but which we didn't need
-       --         at all (this is needed only to decide whether to open Baz.hi
-       --         or Baz.hi-boot higher up the tree).  This happens when a
-       --         module, Foo, that we explicitly imported has 'import Baz' in
-       --         its interface file, recording that Baz is below Foo in the
-       --         module dependency hierarchy.  We want to propagate this
-       --         info.  These modules are in a combination of HIT/PIT and
-       --         iImpModInfo
-       --
-       --      d) NothingAtAll: The name only of all orphan modules
-       --         we know of (this is needed so that anyone who imports us can
-       --         find the orphan modules) These modules are in a combination
-       --         of HIT/PIT and iImpModInfo
-
-       import_info0 = foldModuleEnv mk_imp_info              []           pit
-       import_info1 = foldModuleEnv (mk_imp_info . hm_iface) import_info0 hpt
-       import_info  = not_even_opened_imports ++ import_info1
-
-               -- Recall that iImpModInfo describes modules that have
-               -- been mentioned in the import lists of interfaces we
-               -- have seen mentioned, but which we have not even opened when
-               -- compiling this module
-       not_even_opened_imports =
-         [ (mod_name, orphans, is_boot, NothingAtAll) 
-         | (mod_name, (orphans, is_boot)) <- fmToList (eps_imp_mods eps)]
-
-       
-       mk_imp_info :: ModIface -> [ImportVersion Name] -> [ImportVersion Name]
-       mk_imp_info iface so_far
-
-         | Just ns <- lookupModuleEnv mv_map mod       -- Case (a)
-         = go_for_it (Specifically mod_vers maybe_export_vers 
-                                   (mk_import_items ns) rules_vers)
-
-         | mod `elemModuleSet` pkg_mods                -- Case (b)
-         = go_for_it (Everything mod_vers)
-
-         | import_all_mod                              -- Case (a) and (b); the import-all part
-         = if is_home_pkg_mod then
-               go_for_it (Specifically mod_vers (Just export_vers) [] rules_vers)
-               -- Since the module isn't in the mv_map, presumably we
-               -- didn't actually import anything at all from it
-           else
-               go_for_it (Everything mod_vers)
-               
-         | is_home_pkg_mod || has_orphans              -- Case (c) or (d)
-         = go_for_it NothingAtAll
-
-         | otherwise = so_far
-         where
-           go_for_it exports = (mod_name, has_orphans, mi_boot iface, exports) : so_far
-
-           mod             = mi_module iface
-           mod_name        = moduleName mod
-           is_home_pkg_mod = isHomeModule mod
-           version_info    = mi_version iface
-           version_env     = vers_decls   version_info
-           mod_vers        = vers_module  version_info
-           rules_vers      = vers_rules   version_info
-           export_vers     = vers_exports version_info
-           import_all_mod  = mod_name `elem` import_all_mods
-           has_orphans     = mi_orphan iface
-           
-               -- The sort is to put them into canonical order
-           mk_import_items ns = [(n,v) | n <- sortLt lt_occ ns, 
-                                         let v = lookupVersion version_env n
-                                ]
-                        where
-                          lt_occ n1 n2 = nameOccName n1 < nameOccName n2
-
-           maybe_export_vers | import_all_mod = Just (vers_exports version_info)
-                             | otherwise      = Nothing
-    in
-
-    -- seq the list of ImportVersions returned: occasionally these
+           (ImportAvails { imp_mods = dir_imp_mods,
+                           dep_mods = dep_mods })
+           used_names
+  = -- seq the list of Usages returned: occasionally these
     -- don't get evaluated for a while and we can end up hanging on to
     -- the entire collection of Ifaces.
-    import_info `seqList` import_info
+    usages `seqList` usages
+  where
+    usages = catMaybes (map mkUsage (moduleEnvElts hpt))
+    hpt    = hsc_HPT hsc_env
+    
+    import_all mod = case lookupModuleEnv dir_imp_mods mod of
+                       Just (_,imp_all) -> imp_all
+                       Nothing          -> False
+    
+       -- Find out whether this module is an
+    is_orphan_mod mod = case lookupModuleEnv dep_mods mod of
+                            Just (_, orph, _) -> orph
+                            Nothing           -> False
+    
+    -- ent_map groups together all the things imported and used
+    -- from a particular module in this package
+    ent_map :: ModuleEnv [Name]
+    ent_map  = foldNameSet add_mv emptyModuleEnv used_names
+    add_mv name mv_map = extendModuleEnv_C add_item mv_map mod [name]
+                  where
+                    mod = nameModule name
+                    add_item names _ = name:names
+    
+    -- We want to create a Usage for a home module if 
+    -- a) we used something from; has something in used_names
+    -- b) we imported all of it, even if we used nothing from it
+    --         (need to recompile if its export list changes: export_vers)
+    -- c) is a home-package orphan module (need to recompile if its
+    --         instance decls change: rules_vers)
+    mkUsage :: HomeModInfo -> Maybe (Usage Name)
+    mkUsage mod_info
+      |  null used_names
+      && not all_imported
+      && not orphan_mod
+      = Nothing
+    
+      | otherwise      
+      = Just (Usage { usg_name     = moduleName mod,
+                     usg_mod      = mod_vers,
+                     usg_exports  = export_vers,
+                     usg_entities = ent_vers,
+                     usg_rules    = rules_vers })
+      where
+        iface       = hm_iface mod_info
+        mod         = mi_module iface
+        version_info = mi_version iface
+       orphan_mod   = mod `elemModuleEnv` dep_mods && mi_orphan iface
+                       -- Only bother if the module is below 
+                       -- us in the import graph
+        version_env  = vers_decls   version_info
+        mod_vers     = vers_module  version_info
+        rules_vers   = vers_rules   version_info
+        all_imported = import_all mod 
+        export_vers | all_imported = Just (vers_exports version_info)
+                   | otherwise    = Nothing
+    
+       -- The sort is to put them into canonical order
+        used_names = lookupModuleEnv ent_map mod `orElse` []
+        ent_vers = [(n, lookupVersion version_env n) 
+                  | n <- sortLt lt_occ used_names ]
+        lt_occ n1 n2 = nameOccName n1 < nameOccName n2
 \end{code}
 
 \begin{code}
@@ -669,6 +634,7 @@ addVersionInfo (Just old_iface@(ModIface { mi_version  = old_version,
 
     no_export_change = mi_exports old_iface == mi_exports new_iface            -- Kept sorted
     no_rule_change   = dcl_rules old_decls  == dcl_rules  new_decls            -- Ditto
+                    && dcl_insts old_decls == dcl_insts  new_decls
     no_deprec_change = old_deprecs         == new_deprecs
 
        -- Fill in the version number on the new declarations by looking at the old declarations.
@@ -747,6 +713,7 @@ pprIface iface
                <+> ptext SLIT("where")
 
        , pprExports nameOccName (mi_exports iface)
+       , pprDeps    (mi_deps iface)
        , pprUsages  nameOccName (mi_usages iface)
 
        , pprFixities (mi_fixities iface) (dcl_tycl decls)
@@ -793,30 +760,36 @@ pprOcc n = pprOccName (nameOccName n)
 
 
 \begin{code}
-pprUsages :: (a -> OccName) -> [ImportVersion a] -> SDoc
+pprUsages :: (a -> OccName) -> [Usage a] -> SDoc
 pprUsages getOcc usages = vcat (map (pprUsage getOcc) usages)
 
-pprUsage :: (a -> OccName) -> ImportVersion a -> SDoc
-pprUsage getOcc (m, has_orphans, is_boot, whats_imported)
-  = hsep [ptext SLIT("import"), ppr m, 
-         pp_orphan, pp_boot,
-         pp_versions whats_imported
+pprUsage :: (a -> OccName) -> Usage a -> SDoc
+pprUsage getOcc usage
+  = hsep [ptext SLIT("import"), ppr (usg_name usage), 
+         int (usg_mod usage), 
+         pp_export_version (usg_exports usage),
+         int (usg_rules usage),
+         pp_versions (usg_entities usage)
     ] <> semi
   where
-    pp_orphan | has_orphans = char '!'
-             | otherwise   = empty
-    pp_boot   | is_boot     = char '@'
-              | otherwise   = empty
-
-       -- Importing the whole module is indicated by an empty list
-    pp_versions NothingAtAll                       = empty
-    pp_versions (Everything v)                     = dcolon <+> int v
-    pp_versions (Specifically vm ve nvs vr) = 
-       dcolon <+> int vm <+> pp_export_version ve <+> int vr 
-       <+> hsep [ ppr (getOcc n) <+> int v | (n,v) <- nvs ]
+    pp_versions nvs = hsep [ ppr (getOcc n) <+> int v | (n,v) <- nvs ]
 
     pp_export_version Nothing  = empty
     pp_export_version (Just v) = int v
+
+
+pprDeps :: Dependencies -> SDoc
+pprDeps (mods, pkgs)
+  = vcat [ptext SLIT("module dependencies:") <+> fsep (map ppr_mod mods),
+         ptext SLIT("package dependencies:") <+> fsep (map ppr pkgs)]
+  where
+    ppr_mod (mod_name, orph, boot)
+      = ppr mod_name <+> ppr_orphan orph <+> ppr_boot boot
+   
+    ppr_orphan True  = char '!'
+    ppr_orphan False = empty
+    ppr_boot   True  = char '@'
+    ppr_boot   False = empty
 \end{code}
 
 \begin{code}
index 8822590..08e86f4 100644 (file)
@@ -12,7 +12,7 @@ module Packages (
 
        PackageName,            -- Instance of Outputable
        mkPackageName, packageNameString,
-       preludePackage, rtsPackage, haskell98Package,   -- :: PackageName
+       basePackage, rtsPackage, haskell98Package, thPackage,   -- :: PackageName
 
        PackageConfigMap, emptyPkgMap, extendPkgMap, lookupPkg
     )
@@ -60,10 +60,11 @@ mkPackageName = mkFastString
 packageNameString :: PackageName -> String
 packageNameString = unpackFS
 
-rtsPackage, preludePackage, haskell98Package :: PackageName
-preludePackage   = FSLIT("base")
+rtsPackage, basePackage, haskell98Package, thPackage :: PackageName
+basePackage      = FSLIT("base")
 rtsPackage      = FSLIT("rts")
 haskell98Package = FSLIT("haskell98")
+thPackage        = FSLIT("haskell-src")        -- Template Haskell libraries in here
 
 packageDependents :: PackageConfig -> [PackageName]
 -- Impedence matcher, because PackageConfig has Strings 
index ce48739..943e32e 100644 (file)
@@ -29,6 +29,7 @@ import BasicTypes     ( isNeverActive )
 import Name            ( getOccName, nameOccName, mkInternalName, mkExternalName, 
                          localiseName, isExternalName, nameSrcLoc
                        )
+import RnEnv           ( lookupOrigNameCache, newExternalName )
 import NameEnv         ( filterNameEnv )
 import OccName         ( TidyOccEnv, initTidyOccEnv, tidyOccName )
 import Type            ( tidyTopType )
@@ -541,7 +542,7 @@ tidyTopName mod ns occ_env external name
        -- Similarly, we must make sure it has a system-wide Unique, because
        -- the byte-code generator builds a system-wide Name->BCO symbol table
 
-  | local  && external = case lookupFM ns_names key of
+  | local  && external = case lookupOrigNameCache ns_names mod occ' of
                           Just orig -> (ns,          occ_env', orig)
                           Nothing   -> (ns_w_global, occ_env', new_external_name)
        -- If we want to externalise a currently-local name, check
@@ -554,20 +555,17 @@ tidyTopName mod ns occ_env external name
     global          = isExternalName name
     local           = not global
     internal        = not external
+    loc                     = nameSrcLoc name
 
     (occ_env', occ') = tidyOccName occ_env (nameOccName name)
-    key                     = (moduleName mod, occ')
+
     ns_names        = nsNames ns
-    ns_uniqs        = nsUniqs ns
-    (us1, us2)      = splitUniqSupply ns_uniqs
+    (us1, us2)      = splitUniqSupply (nsUniqs ns)
     uniq            = uniqFromSupply us1
-    loc                     = nameSrcLoc name
-
-    new_local_name     = mkInternalName  uniq     occ' loc
-    new_external_name  = mkExternalName uniq mod occ' loc  
-
+    new_local_name   = mkInternalName uniq occ' loc
     ns_w_local      = ns { nsUniqs = us2 }
-    ns_w_global             = ns { nsUniqs = us2, nsNames = addToFM ns_names key new_external_name }
+
+    (ns_w_global, new_external_name) = newExternalName ns mod occ' loc
 
 
 ------------  Worker  --------------
index c5c6173..d434747 100644 (file)
@@ -1,6 +1,6 @@
 {-                                                             -*-haskell-*-
 -----------------------------------------------------------------------------
-$Id: Parser.y,v 1.111 2002/10/23 14:30:01 simonpj Exp $
+$Id: Parser.y,v 1.112 2002/10/24 14:17:50 simonpj Exp $
 
 Haskell grammar.
 
@@ -295,6 +295,7 @@ iface   :: { ParsedIface }
                        pi_vers    = 1,                 -- Module version
                        pi_orphan  = False,
                        pi_exports = (1,[($2,mkIfaceExports $4)]),
+                       pi_deps    = ([],[]),
                        pi_usages  = [],
                        pi_fixity  = [],
                        pi_insts   = [],
index 4932258..6524f27 100644 (file)
@@ -4,8 +4,7 @@
 \section[PrelNames]{Definitions of prelude modules and names}
 
 
-The strings identify built-in prelude modules.  They are
-defined here so as to avod 
+Nota Bene: all Names defined in here should come from the base package
 
 * ModuleNames for prelude modules, 
        e.g.    pREL_BASE_Name :: ModuleName
@@ -62,17 +61,10 @@ module PrelNames (
 
 #include "HsVersions.h"
 
-import Module    ( ModuleName, mkPrelModule, mkHomeModule, mkModuleName,mkVanillaModule )
-import OccName   ( UserFS, dataName, tcName, clsName, 
+import Module    ( ModuleName, mkBasePkgModule, mkHomeModule, mkModuleName )
+import OccName   ( UserFS, dataName, tcName, clsName, varName,
                    mkKindOccFS, mkOccFS
                  )
-
--- to avoid clashes with Meta.var we must make a local alias for OccName.varName
--- we do this by removing varName from the import of OccName above, making
--- a qualified instance of OccName and using OccNameAlias.varName where varName
--- ws previously used in this file.
-import qualified OccName as OccNameAlias 
-
                  
 import RdrName   ( RdrName, nameRdrName, mkOrig, rdrNameOcc )
 import Unique    ( Unique, Uniquable(..), hasKey,
@@ -100,7 +92,7 @@ import FastString
 This *local* name is used by the interactive stuff
 
 \begin{code}
-itName uniq = mkInternalName uniq (mkOccFS OccNameAlias.varName FSLIT("it")) noSrcLoc
+itName uniq = mkInternalName uniq (mkOccFS varName FSLIT("it")) noSrcLoc
 \end{code}
 
 \begin{code}
@@ -285,18 +277,18 @@ aDDR_Name   = mkModuleName "Addr"
 
 gLA_EXTS_Name   = mkModuleName "GHC.Exts"
 
-gHC_PRIM       = mkPrelModule gHC_PRIM_Name
-pREL_BASE      = mkPrelModule pREL_BASE_Name
-pREL_ADDR      = mkPrelModule pREL_ADDR_Name
-pREL_PTR       = mkPrelModule pREL_PTR_Name
-pREL_STABLE    = mkPrelModule pREL_STABLE_Name
-pREL_IO_BASE   = mkPrelModule pREL_IO_BASE_Name
-pREL_PACK      = mkPrelModule pREL_PACK_Name
-pREL_ERR       = mkPrelModule pREL_ERR_Name
-pREL_NUM       = mkPrelModule pREL_NUM_Name
-pREL_REAL      = mkPrelModule pREL_REAL_Name
-pREL_FLOAT     = mkPrelModule pREL_FLOAT_Name
-pRELUDE                = mkPrelModule pRELUDE_Name
+gHC_PRIM       = mkBasePkgModule gHC_PRIM_Name
+pREL_BASE      = mkBasePkgModule pREL_BASE_Name
+pREL_ADDR      = mkBasePkgModule pREL_ADDR_Name
+pREL_PTR       = mkBasePkgModule pREL_PTR_Name
+pREL_STABLE    = mkBasePkgModule pREL_STABLE_Name
+pREL_IO_BASE   = mkBasePkgModule pREL_IO_BASE_Name
+pREL_PACK      = mkBasePkgModule pREL_PACK_Name
+pREL_ERR       = mkBasePkgModule pREL_ERR_Name
+pREL_NUM       = mkBasePkgModule pREL_NUM_Name
+pREL_REAL      = mkBasePkgModule pREL_REAL_Name
+pREL_FLOAT     = mkBasePkgModule pREL_FLOAT_Name
+pRELUDE                = mkBasePkgModule pRELUDE_Name
 
 
 iNTERACTIVE     = mkHomeModule (mkModuleName "$Interactive")
@@ -708,24 +700,24 @@ mfixName     = varQual mONAD_FIX_Name FSLIT("mfix") mfixIdKey
 All these are original names; hence mkOrig
 
 \begin{code}
-varQual  = mk_known_key_name OccNameAlias.varName      -- Note use of local alias vName
+varQual  = mk_known_key_name varName
 dataQual = mk_known_key_name dataName
 tcQual   = mk_known_key_name tcName
 clsQual  = mk_known_key_name clsName
 
-wVarQual  = mk_wired_in_name OccNameAlias.varName      -- The wired-in analogues
+wVarQual  = mk_wired_in_name varName   -- The wired-in analogues
 wDataQual = mk_wired_in_name dataName          
 wTcQual   = mk_wired_in_name tcName
 
-varQual_RDR  mod str = mkOrig mod (mkOccFS OccNameAlias.varName str)   -- note use of local alias vName
+varQual_RDR  mod str = mkOrig mod (mkOccFS varName str)   -- note use of local alias vName
 tcQual_RDR   mod str = mkOrig mod (mkOccFS tcName str)
 clsQual_RDR  mod str = mkOrig mod (mkOccFS clsName str)
 dataQual_RDR mod str = mkOrig mod (mkOccFS dataName str)
 
 mk_known_key_name space mod str uniq 
-  = mkKnownKeyExternalName mod (mkOccFS space str) uniq 
+  = mkKnownKeyExternalName (mkBasePkgModule mod) (mkOccFS space str) uniq 
 mk_wired_in_name space mod str uniq 
-  = mkWiredInName (mkVanillaModule mod) (mkOccFS space str) uniq
+  = mkWiredInName (mkBasePkgModule mod) (mkOccFS space str) uniq
 
 kindQual str uq = mkInternalName uq (mkKindOccFS tcName str) noSrcLoc
        -- Kinds are not z-encoded in interface file, hence mkKindOccFS
index 08c9e19..5b6754e 100644 (file)
@@ -87,7 +87,7 @@ import TysPrim
 
 -- others:
 import Constants       ( mAX_TUPLE_SIZE )
-import Module          ( mkPrelModule )
+import Module          ( mkBasePkgModule )
 import Name            ( Name, nameUnique, nameOccName, 
                          nameModule, mkWiredInName )
 import OccName         ( mkOccFS, tcName, dataName, mkWorkerOcc, mkGenOcc1, mkGenOcc2 )
@@ -255,7 +255,7 @@ mk_tuple boxity arity = (tycon, tuple_con)
        name      = mkWiredInName mod (mkOccFS dataName name_str) dc_uniq
        tc_uniq   = mkTupleTyConUnique   boxity arity
        dc_uniq   = mkTupleDataConUnique boxity arity
-       mod       = mkPrelModule mod_name
+       mod       = mkBasePkgModule mod_name
        gen_info  = mk_tc_gen_info mod tc_uniq tc_name tycon
 
 unitTyCon     = tupleTyCon Boxed 0
@@ -611,7 +611,7 @@ mkPArrFakeCon arity  = pcDataCon name [tyvar] [] tyvarTys parrTyCon
         nameStr   = mkFastString ("MkPArr" ++ show arity)
        name      = mkWiredInName mod (mkOccFS dataName nameStr) uniq
        uniq      = mkPArrDataConUnique arity
-       mod       = mkPrelModule pREL_PARR_Name
+       mod       = mkBasePkgModule pREL_PARR_Name
 
 -- checks whether a data constructor is a fake constructor for parallel arrays
 --
index fa8e8e3..f5f3eab 100644 (file)
@@ -23,18 +23,19 @@ import HsTypes              ( hsTyVarName, replaceTyVarName )
 import HscTypes                ( Provenance(..), pprNameProvenance, hasBetterProv,
                          ImportReason(..), GlobalRdrEnv, GlobalRdrElt(..), 
                          GenAvailInfo(..), AvailInfo, Avails, 
-                         ModIface(..), NameCache(..),
+                         ModIface(..), NameCache(..), OrigNameCache,
                          Deprecations(..), lookupDeprec, isLocalGRE,
                          extendLocalRdrEnv, availName, availNames,
                          lookupFixity
                        )
 import TcRnMonad
 import Name            ( Name, getName, getSrcLoc, nameIsLocalOrFrom, isWiredInName,
-                         mkInternalName, mkExternalName, mkIPName, 
+                         mkInternalName, mkExternalName, mkIPName, nameSrcLoc,
                          nameOccName, setNameModuleAndLoc, nameModule  )
 import NameSet
 import OccName         ( OccName, tcName, isDataOcc, occNameUserString, occNameFlavour )
-import Module          ( Module, ModuleName, moduleName, mkVanillaModule )
+import Module          ( Module, ModuleName, moduleName, mkHomeModule,
+                         lookupModuleEnv, lookupModuleEnvByName, extendModuleEnv_C )
 import PrelNames       ( mkUnboundName, intTyConName, 
                          boolTyConName, funTyConName,
                          unpackCStringName, unpackCStringFoldrName, unpackCStringUtf8Name,
@@ -45,9 +46,10 @@ import PrelNames     ( mkUnboundName, intTyConName,
 import DsMeta          ( templateHaskellNames, qTyConName )
 #endif
 import TysWiredIn      ( unitTyCon )   -- A little odd
+import Finder          ( findModule )
 import FiniteMap
 import UniqSupply
-import SrcLoc          ( SrcLoc, noSrcLoc )
+import SrcLoc          ( SrcLoc, noSrcLoc, importedSrcLoc )
 import Outputable
 import ListSetOps      ( removeDups, equivClasses )
 import BasicTypes      ( mapIPName, FixitySig(..) )
@@ -76,89 +78,82 @@ newTopBinder mod rdr_name loc
   = returnM name
 
   | otherwise
+  = newGlobalName mod (rdrNameOcc rdr_name) loc
+
+newGlobalName :: Module -> OccName -> SrcLoc -> TcRn m Name
+newGlobalName mod occ loc
   =    -- First check the cache
     getNameCache               `thenM` \ name_supply -> 
-    let 
-       occ = rdrNameOcc rdr_name
-       key = (moduleName mod, occ)
-       cache = nsNames name_supply
-    in
-    case lookupFM cache key of
-
-       -- A hit in the cache!  We are at the binding site of the name, and
-       -- this is the moment when we know all about 
-       --      a) the Name's host Module (in particular, which
-       --         package it comes from)
-       --      b) its defining SrcLoc
-       -- So we update this info
-
-       Just name 
-         | isWiredInName name -> returnM name
-               -- Don't mess with wired-in names.  Apart from anything
-               -- else, their wired-in-ness is in the SrcLoca
-         | otherwise 
-         -> let 
-               new_name  = setNameModuleAndLoc name mod loc
-               new_cache = addToFM cache key new_name
-            in
-            setNameCache (name_supply {nsNames = new_cache})   `thenM_`
-            returnM new_name
+    case lookupOrigNameCache (nsNames name_supply) mod occ of
+
+       -- A hit in the cache!  We are at the binding site of the name.
+       -- This is the moment when we know the defining SrcLoc
+       -- of the Name.  However, since we must have encountered an 
+       -- occurrence before the binding site, this must be an 
+       -- implicitly-imported name and we can't give a useful SrcLoc to
+       -- it.  So we just leave it alone.
+       --
+       -- IMPORTANT: don't mess with wired-in names.  
+       -- Their wired-in-ness is in the SrcLoc
+
+       Just name -> returnM name
                     
        -- Miss in the cache!
        -- Build a completely new Name, and put it in the cache
-       -- Even for locally-defined names we use implicitImportProvenance; 
-       -- updateProvenances will set it to rights
-       Nothing -> addNewName name_supply key mod occ loc
-
-newGlobalName :: ModuleName -> OccName -> TcRn m Name
-  -- Used for *occurrences*.  We make a place-holder Name, really just
-  -- to agree on its unique, which gets overwritten when we read in
-  -- the binding occurence later (newTopBinder)
-  -- The place-holder Name doesn't have the right SrcLoc, and its
-  -- Module won't have the right Package either.
-  --
-  -- (We have to pass a ModuleName, not a Module, because we may be
-  -- simply looking at an occurrence M.x in an interface file.)
-  --
-  -- This means that a renamed program may have incorrect info
-  -- on implicitly-imported occurrences, but the correct info on the 
-  -- *binding* declaration. It's the type checker that propagates the 
-  -- correct information to all the occurrences.
-  -- Since implicitly-imported names never occur in error messages,
-  -- it doesn't matter that we get the correct info in place till later,
-  -- (but since it affects DLL-ery it does matter that we get it right
-  --  in the end).
-newGlobalName mod_name occ
-  = getNameCache               `thenM` \ name_supply ->
-    let
-       key = (mod_name, occ)
-       cache = nsNames name_supply
-    in
-    case lookupFM cache key of
-       Just name -> -- traceRn (text "newGlobalName: hit" <+> ppr name) `thenM_`
-                    returnM name
-
-       Nothing   -> -- traceRn (text "newGlobalName: new" <+> ppr name)  `thenM_`
-                    addNewName name_supply key (mkVanillaModule mod_name) occ noSrcLoc
+       Nothing -> addNewName name_supply mod occ loc
 
 -- Look up a "system name" in the name cache.
 -- This is done by the type checker... 
--- For *source* declarations, this will put the thing into the name cache
--- For *interface* declarations, RnHiFiles.getSysBinders will already have
--- put it into the cache.
 lookupSysName :: Name                  -- Base name
              -> (OccName -> OccName)   -- Occurrence name modifier
              -> TcRn m Name            -- System name
 lookupSysName base_name mk_sys_occ
+  = newGlobalName (nameModule base_name)
+                 (mk_sys_occ (nameOccName base_name))
+                 (nameSrcLoc base_name)    
+
+
+newGlobalNameFromRdrName rdr_name              -- Qualified original name
+ = newGlobalName2 (rdrNameModule rdr_name) (rdrNameOcc rdr_name)
+
+newGlobalName2 :: ModuleName -> OccName -> TcRn m Name
+  -- This one starts with a ModuleName, not a Module, because 
+  -- we may be simply looking at an occurrence M.x in an interface file.
+  --
+  -- Used for *occurrences*.  Even if we get a miss in the
+  -- original-name cache, we make a new External Name.
+  -- We get its Module either from the OrigNameCache, or (if this
+  -- is the first Name from that module) from the Finder
+  --
+  -- In the case of a miss, we have to make up the SrcLoc, but that's
+  -- OK: it must be an implicitly-imported Name, and that never occurs
+  -- in an error message.
+
+newGlobalName2 mod_name occ
   = getNameCache               `thenM` \ name_supply ->
     let
-       mod = nameModule base_name
-       occ = mk_sys_occ (nameOccName base_name)
-       key = (moduleName mod, occ)
+       new_name mod = addNewName name_supply mod occ importedSrcLoc
     in
-    case lookupFM (nsNames name_supply) key of
-       Just name -> returnM name
-       Nothing   -> addNewName name_supply key mod occ noSrcLoc
+    case lookupModuleEnvByName (nsNames name_supply) mod_name of
+      Just (mod, occ_env) ->   
+       -- There are some names from this module already
+       -- Next, look up in the OccNameEnv
+       case lookupFM occ_env occ of
+            Just name -> returnM name
+            Nothing   -> new_name mod
+
+      Nothing   ->     -- No names from this module yet
+       ioToTcRn (findModule mod_name)          `thenM` \ mb_loc ->
+       case mb_loc of
+           Just (mod, _) -> new_name mod
+           Nothing       -> addErr (noModule mod_name) `thenM_`
+                               -- Things have really gone wrong at this point,
+                               -- so having the wrong package info in the 
+                               -- Module is the least of our worries.
+                            new_name (mkHomeModule mod_name)
+  where
+    noModule mod_name = ptext SLIT("Can't find interface for module") <+> ppr mod_name
+
 
 newIPName rdr_name_ip
   = getNameCache               `thenM` \ name_supply ->
@@ -179,20 +174,42 @@ newIPName rdr_name_ip
     where 
        key = rdr_name_ip       -- Ensures that ?x and %x get distinct Names
 
-addNewName :: NameCache -> (ModuleName,OccName) 
-          -> Module -> OccName -> SrcLoc -> TcRn m Name
--- Internal function: extend the name cache, dump it back into
---                   the monad, and return the new name
--- (internal, hence the rather redundant interface)
-addNewName name_supply key mod occ loc
+-- A local helper function
+addNewName name_supply mod occ loc
   = setNameCache new_name_supply       `thenM_`
     returnM name
   where
-     (us', us1) = splitUniqSupply (nsUniqs name_supply)
-     uniq      = uniqFromSupply us1
-     name       = mkExternalName uniq mod occ loc
-     new_cache  = addToFM (nsNames name_supply) key name
+    (new_name_supply, name) = newExternalName name_supply mod occ loc
+
+
+newExternalName :: NameCache -> Module -> OccName -> SrcLoc 
+                 -> (NameCache,Name)
+-- Allocate a new unique, manufacture a new External Name,
+-- put it in the cache, and return the two
+newExternalName name_supply mod occ loc
+  = (new_name_supply, name)
+  where
+     (us', us1)      = splitUniqSupply (nsUniqs name_supply)
+     uniq           = uniqFromSupply us1
+     name            = mkExternalName uniq mod occ loc
+     new_cache       = extend_name_cache (nsNames name_supply) mod occ name
      new_name_supply = name_supply {nsUniqs = us', nsNames = new_cache}
+
+lookupOrigNameCache :: OrigNameCache -> Module -> OccName -> Maybe Name
+lookupOrigNameCache nc mod occ
+  = case lookupModuleEnv nc mod of
+       Nothing           -> Nothing
+       Just (_, occ_env) -> lookupFM occ_env occ
+
+extendOrigNameCache :: OrigNameCache -> Name -> OrigNameCache
+extendOrigNameCache nc name 
+  = extend_name_cache nc (nameModule name) (nameOccName name) name
+
+extend_name_cache :: OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
+extend_name_cache nc mod occ name
+  = extendModuleEnv_C combine nc mod (mod, unitFM occ name)
+  where
+    combine (mod, occ_env) _ = (mod, addToFM occ_env occ name)
 \end{code}
 
 %*********************************************************
@@ -416,8 +433,7 @@ lookupSrcName_maybe rdr_name
   = returnM (Just name)
 
   | isOrig rdr_name                    -- An original name
-  = newGlobalName (rdrNameModule rdr_name) 
-                 (rdrNameOcc rdr_name) `thenM` \ name ->
+  = newGlobalNameFromRdrName rdr_name  `thenM` \ name ->
     returnM (Just name)
 
   | otherwise
@@ -443,7 +459,7 @@ lookupIfaceName :: Module -> RdrName -> TcRn m Name
        -- unqualified names for locally-defined things, such as
        -- constructors of a data type.
 lookupIfaceName mod rdr_name
-  | isUnqual rdr_name = newGlobalName (moduleName mod) (rdrNameOcc rdr_name)
+  | isUnqual rdr_name = newGlobalName mod (rdrNameOcc rdr_name) importedSrcLoc
   | otherwise        = lookupOrigName rdr_name
 
 lookupOrigName :: RdrName -> TcRn m Name
@@ -456,7 +472,7 @@ lookupOrigName rdr_name
 
   | otherwise  -- Usually Orig, but can be a Qual when 
                -- we are reading a .hi-boot file
-  = newGlobalName (rdrNameModule rdr_name) (rdrNameOcc rdr_name)
+  = newGlobalNameFromRdrName rdr_name
 
 
 dataTcOccs :: RdrName -> [RdrName]
index 33d5630..bdab40a 100644 (file)
@@ -19,9 +19,9 @@ import CmdLineOpts    ( opt_IgnoreIfacePragmas )
 import Parser          ( parseIface )
 import HscTypes                ( ModIface(..), emptyModIface,
                          ExternalPackageState(..), 
-                         VersionInfo(..), ImportedModuleInfo,
-                         lookupIfaceByModName, RdrExportItem, WhatsImported(..),
-                         ImportVersion, WhetherHasOrphans, IsBootInterface,
+                         VersionInfo(..), Usage(..),
+                         lookupIfaceByModName, RdrExportItem, 
+                         WhetherHasOrphans, IsBootInterface,
                          DeclsMap, GatedDecl, IfaceInsts, IfaceRules, mkIfaceDecls,
                          AvailInfo, GenAvailInfo(..), ParsedIface(..), IfaceDeprecs,
                          Avails, availNames, availName, Deprecations(..)
@@ -46,10 +46,10 @@ import NameEnv
 import NameSet
 import Id              ( idName )
 import MkId            ( seqId )
-import Packages                ( preludePackage )
+import Packages                ( basePackage )
 import Module          ( Module, ModuleName, ModLocation(ml_hi_file),
-                         moduleName, isHomeModule, mkVanillaModule,
-                         extendModuleEnv
+                         moduleName, isHomeModule, mkPackageModule,
+                         extendModuleEnv, lookupModuleEnvByName
                        )
 import RdrName         ( RdrName, mkRdrUnqual, rdrNameOcc, nameRdrName )
 import OccName         ( OccName, mkWorkerOcc, mkClassTyConOcc, mkClassDataConOcc,
@@ -116,12 +116,11 @@ loadInterface :: SDoc -> ModuleName -> WhereFrom -> TcRn m ModIface
   -- But it's OK to fail; perhaps the module has changed, and that interface 
   -- is no longer used.
   
-  -- tryLoadInterface guarantees to return with eps_mod_info m --> (..., True)
-  -- (If the load fails, we plug in a vanilla placeholder)
 loadInterface doc_str mod_name from
- = getHpt      `thenM` \ hpt ->
-   getModule   `thenM` \ this_mod ->
-   getEps      `thenM` \ eps@(EPS { eps_PIT = pit }) ->
+ = getHpt              `thenM` \ hpt ->
+   getModule           `thenM` \ this_mod ->
+   getImports          `thenM` \ import_avails ->
+   getEps              `thenM` \ eps@(EPS { eps_PIT = pit }) ->
 
        -- CHECK WHETHER WE HAVE IT ALREADY
    case lookupIfaceByModName hpt pit mod_name of {
@@ -136,16 +135,18 @@ loadInterface doc_str mod_name from
                        -- before we got to real imports.  
        other       -> 
 
+   traceRn (vcat [text "loadInterface" <+> brackets doc_str,
+                 ppr (dep_mods import_avails)])        `thenM_`
    let
-       mod_map  = eps_imp_mods eps
-       mod_info = lookupFM mod_map mod_name
+       mod_map  = dep_mods import_avails
+       mod_info = lookupModuleEnvByName mod_map mod_name
 
        hi_boot_file 
          = case (from, mod_info) of
-               (ImportByUser   is_boot, _)         -> is_boot
-               (ImportForUsage is_boot, _)         -> is_boot
-               (ImportBySystem, Just (_, is_boot)) -> is_boot
-               (ImportBySystem, Nothing)           -> False
+               (ImportByUser   is_boot, _)            -> is_boot
+               (ImportForUsage is_boot, _)            -> is_boot
+               (ImportBySystem, Just (_, _, is_boot)) -> is_boot
+               (ImportBySystem, Nothing)              -> False
                        -- We're importing a module we know absolutely
                        -- nothing about, so we assume it's from
                        -- another package, where we aren't doing 
@@ -153,8 +154,8 @@ loadInterface doc_str mod_name from
 
        redundant_source_import 
          = case (from, mod_info) of 
-               (ImportByUser True, Just (_,False)) -> True
-               other                               -> False
+               (ImportByUser True, Just (_, _, False)) -> True
+               other                                   -> False
    in
 
        -- Issue a warning for a redundant {- SOURCE -} import
@@ -181,7 +182,7 @@ loadInterface doc_str mod_name from
          |  otherwise  
          -> let        -- Not found, so add an empty export env to 
                        -- the EPS map so that we don't look again
-               fake_mod   = mkVanillaModule mod_name
+               fake_mod   = mkPackageModule mod_name
                fake_iface = emptyModIface fake_mod
                new_eps    = eps { eps_PIT = extendModuleEnv pit fake_mod fake_iface }
             in
@@ -226,21 +227,6 @@ loadInterface doc_str mod_name from
                                vers_rules = rule_vers,
                                vers_decls = decls_vers }
 
-       -- Add to mod_map info about the things the imported module 
-       -- depends on, extracted from its usage info
-       -- No point for system imports, for reasons that escape me...
-       usages   = pi_usages iface
-       mod_map1 = case from of
-                       ImportBySystem -> mod_map
-                       other          -> addModDeps mod is_loaded usages mod_map
-       -- Delete the module itself, which is now in the PIT
-       mod_map2 = delFromFM mod_map1 mod_name
-
-       -- mod_deps is a pruned version of usages that records only what 
-       -- module imported, but nothing about versions.
-       -- This info is used when demand-linking the dependencies
-       mod_deps = [ (mod,orph,boot,NothingAtAll) | (mod,orph,boot,_) <- usages]
-
        this_mod_name = moduleName this_mod
        is_loaded m   =  m == this_mod_name 
                      || maybeToBool (lookupIfaceByModName hpt pit m)
@@ -257,8 +243,8 @@ loadInterface doc_str mod_name from
                               mi_orphan = has_orphans, mi_boot = hi_boot_file,
                               mi_exports = avails, 
                               mi_fixities = fix_env, mi_deprecs = deprec_env,
-                              mi_usages   = mod_deps,  -- Used for demand-loading,
-                                                       -- not for version info
+                              mi_deps     = pi_deps iface,
+                              mi_usages   = panic "No mi_usages in PIT",
                               mi_decls    = panic "No mi_decls in PIT",
                               mi_globals  = Nothing
                    }
@@ -266,47 +252,13 @@ loadInterface doc_str mod_name from
        new_eps = eps { eps_PIT      = new_pit,
                        eps_decls    = new_decls,
                        eps_insts    = new_insts,
-                       eps_rules    = new_rules,
-                       eps_imp_mods = mod_map2  }
+                       eps_rules    = new_rules }
     in
     setEps new_eps             `thenM_`
     returnM mod_iface
     }}
 
 -----------------------------------------------------
---     Adding module dependencies from the 
---     import decls in the interface file
------------------------------------------------------
-
-addModDeps :: Module 
-          -> (ModuleName -> Bool)      -- True for modules that are already loaded
-          -> [ImportVersion a] 
-          -> ImportedModuleInfo -> ImportedModuleInfo
--- (addModDeps M ivs deps)
--- We are importing module M, and M.hi contains 'import' decls given by ivs
-addModDeps mod is_loaded new_deps mod_deps
-  = foldr add mod_deps filtered_new_deps
-  where
-       -- Don't record dependencies when importing a module from another package
-       -- Except for its descendents which contain orphans,
-       -- and in that case, forget about the boot indicator
-    filtered_new_deps :: [(ModuleName, (WhetherHasOrphans, IsBootInterface))]
-    filtered_new_deps
-       | isHomeModule mod  = [ (imp_mod, (has_orphans, is_boot))
-                             | (imp_mod, has_orphans, is_boot, _) <- new_deps,
-                               not (is_loaded imp_mod)
-                             ]                       
-       | otherwise         = [ (imp_mod, (True, False))
-                             | (imp_mod, has_orphans, _, _) <- new_deps,
-                               not (is_loaded imp_mod) && has_orphans
-                             ]
-    add (imp_mod, dep) deps = addToFM_C combine deps imp_mod dep
-
-    combine old@(old_has_orphans, old_is_boot) new@(new_has_orphans, new_is_boot)
-       | old_is_boot = new     -- Record the best is_boot info
-       | otherwise   = old
-
------------------------------------------------------
 --     Loading the export list
 -----------------------------------------------------
 
@@ -322,11 +274,11 @@ loadExport (mod, entities)
     returnM (mod, avails)
   where
     load_entity mod (Avail occ)
-      =        newGlobalName mod occ   `thenM` \ name ->
+      =        newGlobalName2 mod occ  `thenM` \ name ->
        returnM (Avail name)
     load_entity mod (AvailTC occ occs)
-      =        newGlobalName mod occ           `thenM` \ name ->
-        mappM (newGlobalName mod) occs `thenM` \ names ->
+      =        newGlobalName2 mod occ          `thenM` \ name ->
+        mappM (newGlobalName2 mod) occs        `thenM` \ names ->
         returnM (AvailTC name names)
 
 
@@ -550,7 +502,7 @@ loadOldIface iface
        decls = mkIfaceDecls new_decls new_rules new_insts
 
        mod_iface = ModIface { mi_module = mod, mi_package = pi_pkg iface,
-                              mi_version = version,
+                              mi_version = version, mi_deps = pi_deps iface,
                               mi_exports = avails, mi_usages = usages,
                               mi_boot = False, mi_orphan = pi_orphan iface, 
                               mi_fixities = fix_env, mi_deprecs = deprec_env,
@@ -586,17 +538,13 @@ loadHomeInsts :: [RdrNameInstDecl]
 loadHomeInsts insts = mappM rnInstDecl insts
 
 ------------------
-loadHomeUsage :: ImportVersion OccName
-             -> TcRn m (ImportVersion Name)
-loadHomeUsage (mod_name, orphans, is_boot, whats_imported)
-  = rn_imps whats_imported     `thenM` \ whats_imported' ->
-    returnM (mod_name, orphans, is_boot, whats_imported')
+loadHomeUsage :: Usage OccName -> TcRn m (Usage Name)
+loadHomeUsage usage
+  = mappM rn_imp (usg_entities usage)  `thenM` \ entities' ->
+    returnM (usage { usg_entities = entities' })
   where
-    rn_imps NothingAtAll                 = returnM NothingAtAll
-    rn_imps (Everything v)               = returnM (Everything v)
-    rn_imps (Specifically mv ev items rv) = mappM rn_imp items         `thenM` \ items' ->
-                                           returnM (Specifically mv ev items' rv)
-    rn_imp (occ,vers) = newGlobalName mod_name occ     `thenM` \ name ->
+    mod_name = usg_name usage 
+    rn_imp (occ,vers) = newGlobalName2 mod_name occ    `thenM` \ name ->
                        returnM (name,vers)
 \end{code}
 
@@ -736,7 +684,8 @@ read_iface mod file_path is_hi_boot_file
 ghcPrimIface :: ParsedIface
 ghcPrimIface = ParsedIface {
       pi_mod    = gHC_PRIM_Name,
-      pi_pkg     = preludePackage,
+      pi_pkg     = basePackage,
+      pi_deps    = ([],[]),
       pi_vers    = 1,
       pi_orphan  = False,
       pi_usages  = [],
index 739bb73..260981a 100644 (file)
@@ -23,6 +23,7 @@ import RnHsSyn                ( RenamedHsDecl, RenamedTyClDecl,
                          tyClDeclFVs, ruleDeclFVs, impDeclFVs
                        )
 import RnHiFiles       ( loadInterface, loadHomeInterface, loadOrphanModules )
+import RnNames         ( mkModDeps )
 import RnSource                ( rnTyClDecl, rnInstDecl, rnIfaceRuleDecl )
 import TcEnv           ( getInGlobalScope, tcLookupGlobal_maybe )
 import TcRnMonad
@@ -37,7 +38,7 @@ import Name           ( Name {-instance NamedThing-}, isWiredInName, isInternalName, name
                         )
 import NameEnv                 ( delFromNameEnv, lookupNameEnv )
 import NameSet
-import Module          ( Module, isHomeModule, extendModuleSet )
+import Module          ( Module, isHomeModule, extendModuleSet, moduleEnvElts )
 import PrelNames       ( hasKey, fractionalClassKey, numClassKey, 
                          integerTyConName, doubleTyConName )
 import FiniteMap
@@ -206,8 +207,8 @@ recordUsage :: Name -> TcRn m ()
 recordUsage name = updUsages (upd_usg name)
 
 upd_usg name usages
-  | isHomeModule mod = usages { usg_home = addOneToNameSet (usg_home usages) name }
-  | otherwise        = usages { usg_ext  = extendModuleSet (usg_ext usages)  mod }
+  | isHomeModule mod = addOneToNameSet usages name
+  | otherwise        = usages
   where
     mod = nameModule name
 \end{code}
@@ -491,12 +492,13 @@ getImportedInstDecls :: NameSet -> TcRn m ([(Module,RdrNameInstDecl)], NameSet)
 getImportedInstDecls gates
   =            -- First, load any orphan-instance modules that aren't aready loaded
        -- Orphan-instance modules are recorded in the module dependecnies
-    getEps                                     `thenM` \ eps ->
+    getImports                 `thenM` \ imports ->
+    getEps                     `thenM` \ eps ->
     let
        old_gates = eps_inst_gates eps
        new_gates = gates `minusNameSet` old_gates
        all_gates = new_gates `unionNameSets` old_gates
-       orphan_mods = [mod | (mod, (True, _)) <- fmToList (eps_imp_mods eps)]
+       orphan_mods = [mod | (mod, True, _) <- moduleEnvElts (dep_mods imports)]
     in
     loadOrphanModules orphan_mods                      `thenM_` 
 
@@ -593,10 +595,21 @@ checkVersions source_unchanged iface
   = returnM outOfDate
   | otherwise
   = traceHiDiffs (text "Considering whether compilation is required for" <+> 
-                       ppr (mi_module iface) <> colon) `thenM_`
+                 ppr (mi_module iface) <> colon)       `thenM_`
 
        -- Source code unchanged and no errors yet... carry on 
-    checkList [checkModUsage u | u <- mi_usages iface]
+       -- First put the dependent-module info in the envt, just temporarily,
+       -- so that when we look for interfaces we look for the right one.
+       -- It's just temporary because either the usage check will succeed 
+       -- (in which case we are done with this module) or it'll fail (in which
+       -- case we'll compile the module from scratch anyhow).
+    updGblEnv (\ gbl -> gbl { tcg_imports = mod_deps }) (
+       checkList [checkModUsage u | u <- mi_usages iface]
+    )
+
+  where
+       -- This is a bit of a hack really
+    mod_deps = emptyImportAvails { dep_mods = mkModDeps (fst (mi_deps iface)) }
 
 checkList :: [TcRn m RecompileRequired] -> TcRn m RecompileRequired
 checkList []            = returnM upToDate
@@ -608,30 +621,22 @@ checkList (check:checks) = check  `thenM` \ recompile ->
 \end{code}
        
 \begin{code}
-checkModUsage :: ImportVersion Name -> TcRn m RecompileRequired
+checkModUsage :: Usage Name -> TcRn m RecompileRequired
 -- Given the usage information extracted from the old
 -- M.hi file for the module being compiled, figure out
 -- whether M needs to be recompiled.
 
-checkModUsage (mod_name, _, _, NothingAtAll)
-       -- If CurrentModule.hi contains 
-       --      import Foo :: ;
-       -- then that simply records that Foo lies below CurrentModule in the
-       -- hierarchy, but CurrentModule doesn't depend in any way on Foo.
-       -- In this case we don't even want to open Foo's interface.
-  = up_to_date (ptext SLIT("Nothing used from:") <+> ppr mod_name)
-
-checkModUsage (mod_name, _, is_boot, whats_imported)
+checkModUsage (Usage { usg_name = mod_name, usg_mod = old_mod_vers,
+                      usg_rules = old_rule_vers,
+                      usg_exports = maybe_old_export_vers, 
+                      usg_entities = old_decl_vers })
   =    -- Load the imported interface is possible
-       -- We use tryLoadInterface, because failure is not an error
-       -- (might just be that the old .hi file for this module is out of date)
     let
        doc_str = sep [ptext SLIT("need version info for"), ppr mod_name]
-       from    = ImportForUsage is_boot
     in
     traceHiDiffs (text "Checking usages for module" <+> ppr mod_name) `thenM_`
 
-    tryM (loadInterface doc_str mod_name from) `thenM` \ mb_iface ->
+    tryM (loadInterface doc_str mod_name ImportBySystem)       `thenM` \ mb_iface ->
 
     case mb_iface of {
        Left exn ->  (out_of_date (sep [ptext SLIT("Can't find version number for module"), 
@@ -648,16 +653,6 @@ checkModUsage (mod_name, _, is_boot, whats_imported)
        new_export_vers = vers_exports new_vers
        new_rule_vers   = vers_rules   new_vers
     in
-    case whats_imported of {   -- NothingAtAll dealt with earlier
-
-      Everything old_mod_vers -> checkModuleVersion old_mod_vers new_mod_vers  `thenM` \ recompile ->
-                                if recompile then
-                                       out_of_date (ptext SLIT("...and I needed the whole module"))
-                                else
-                                       returnM upToDate ;
-
-      Specifically old_mod_vers maybe_old_export_vers old_decl_vers old_rule_vers ->
-
        -- CHECK MODULE
     checkModuleVersion old_mod_vers new_mod_vers       `thenM` \ recompile ->
     if not recompile then
@@ -684,7 +679,7 @@ checkModUsage (mod_name, _, is_boot, whats_imported)
     else
        up_to_date (ptext SLIT("  Great!  The bits I use are up to date"))
 
-    }}
+    }
 
 ------------------------
 checkModuleVersion old_mod_vers new_mod_vers
index 8f0b48c..5a1a743 100644 (file)
@@ -6,7 +6,7 @@
 \begin{code}
 module RnNames (
        rnImports, importsFromLocalDecls, exportsFromAvail,
-       reportUnusedNames 
+       reportUnusedNames, mkModDeps
     ) where
 
 #include "HsVersions.h"
@@ -25,16 +25,17 @@ import TcRnMonad
 
 import FiniteMap
 import PrelNames       ( pRELUDE_Name, mAIN_Name, isBuiltInSyntaxName )
-import Module          ( Module, ModuleName, moduleName, 
-                         moduleNameUserString, 
-                         unitModuleEnvByName, lookupModuleEnvByName,
-                         moduleEnvElts )
+import Module          ( Module, ModuleName, ModuleEnv, moduleName, 
+                         moduleNameUserString, isHomeModule,
+                         emptyModuleEnv, unitModuleEnvByName, unitModuleEnv, 
+                         lookupModuleEnvByName, extendModuleEnvByName, moduleEnvElts )
 import Name            ( Name, nameSrcLoc, nameOccName, nameModule, isExternalName )
 import NameSet
 import NameEnv
 import OccName         ( OccName, dataName, isTcOcc )
 import HscTypes                ( Provenance(..), ImportReason(..), GlobalRdrEnv,
-                         GenAvailInfo(..), AvailInfo, Avails, IsBootInterface,
+                         GenAvailInfo(..), AvailInfo, Avails, 
+                         IsBootInterface, WhetherHasOrphans,
                          availName, availNames, availsToNameSet, 
                          Deprecations(..), ModIface(..), 
                          GlobalRdrElt(..), unQualInScope, isLocalGRE
@@ -45,7 +46,7 @@ import Outputable
 import Maybes          ( maybeToBool, catMaybes )
 import ListSetOps      ( removeDups )
 import Util            ( sortLt, notNull )
-import List            ( partition )
+import List            ( partition, insert )
 import IO              ( openFile, IOMode(..) )
 \end{code}
 
@@ -73,7 +74,7 @@ rnImports imports
          (source, ordinary) = partition is_source_import all_imports
          is_source_import (ImportDecl _ is_boot _ _ _ _) = is_boot
 
-         get_imports = importsFromImportDecl (moduleName this_mod)
+         get_imports = importsFromImportDecl this_mod
        in
        mappM get_imports ordinary      `thenM` \ stuff1 ->
        mappM get_imports source        `thenM` \ stuff2 ->
@@ -115,15 +116,15 @@ preludeImportDecl loc
 \end{code}
        
 \begin{code}
-importsFromImportDecl :: ModuleName
+importsFromImportDecl :: Module
                      -> RdrNameImportDecl
                      -> TcRn m (GlobalRdrEnv, ImportAvails)
 
-importsFromImportDecl this_mod_name 
-       (ImportDecl imp_mod_name is_boot qual_only as_mod import_spec iloc)
+importsFromImportDecl this_mod
+       (ImportDecl imp_mod_name is_boot qual_only as_mod imp_spec iloc)
   = addSrcLoc iloc $
     let
-       doc     = ppr imp_mod_name <+> ptext SLIT("is directly imported")
+       doc = ppr imp_mod_name <+> ptext SLIT("is directly imported")
     in
 
        -- If there's an error in loadInterface, (e.g. interface
@@ -135,15 +136,16 @@ importsFromImportDecl this_mod_name
        Right iface ->    
 
     let
-       imp_mod          = mi_module iface
+       imp_mod          = mi_module iface
        avails_by_module = mi_exports iface
-       deprecs          = mi_deprecs iface
-       dir_imp          = unitModuleEnvByName imp_mod_name (imp_mod, import_all import_spec)
+       deprecs          = mi_deprecs iface
+       is_orph          = mi_orphan iface 
 
        avails :: Avails
        avails = [ avail | (mod_name, avails) <- avails_by_module,
                           mod_name /= this_mod_name,
                           avail <- avails ]
+       this_mod_name = moduleName this_mod
        -- If the module exports anything defined in this module, just ignore it.
        -- Reason: otherwise it looks as if there are two local definition sites
        -- for the thing, and an error gets reported.  Easiest thing is just to
@@ -162,6 +164,63 @@ importsFromImportDecl this_mod_name
        -- then you'll get a 'B does not export AType' message.  Oh well.
 
     in
+       -- Filter the imports according to the import list
+    filterImports imp_mod is_boot imp_spec avails    `thenM` \ (filtered_avails, explicits) ->
+
+    let
+       (sub_dep_mods, sub_dep_pkgs) = mi_deps iface
+
+       -- Compute new transitive dependencies: take the ones in 
+       -- the interface and add 
+       (dependent_mods, dependent_pkgs) 
+          | isHomeModule imp_mod 
+          =    -- Imported module is from the home package
+               -- Take its dependent modules and
+               --      (a) remove this_mod (might be there as a hi-boot)
+               --      (b) add imp_mod itself
+               -- Take its dependent packages unchanged
+            ((imp_mod_name, is_orph, is_boot) : filter not_self sub_dep_mods, 
+             sub_dep_pkgs)
+          | otherwise  
+          =    -- Imported module is from another package
+               -- Take only the orphan modules from its dependent modules
+               --      (sigh!  it would be better to dump them entirely)
+               -- Add the package imp_mod comes from to the dependent packages
+               -- from imp_mod
+            (filter sub_is_orph sub_dep_mods, 
+             insert (mi_package iface) sub_dep_pkgs)
+
+       not_self    (m, _, _)    = m /= this_mod_name
+       sub_is_orph (_, orph, _) = orph
+
+       import_all = case imp_spec of
+                       (Just (False, _)) -> False      -- Imports are spec'd explicitly
+                       other             -> True       -- Everything is imported, 
+                                                       -- (or almost everything [hiding])
+
+       qual_mod_name = case as_mod of
+                         Nothing           -> imp_mod_name
+                         Just another_name -> another_name
+
+       -- 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
+       --      module M ( module P ) where ...
+       -- Then we must export whatever came from P unqualified.
+       avail_env = mkAvailEnv filtered_avails
+        unqual_avails | qual_only = emptyAvailEnv      -- Qualified import
+                     | otherwise = avail_env           -- Unqualified import
+
+       mk_prov name = NonLocalDef (UserImport imp_mod iloc (name `elemNameSet` explicits)) 
+       gbl_env      = mkGlobalRdrEnv qual_mod_name (not qual_only) 
+                                     mk_prov filtered_avails deprecs
+       imports      = ImportAvails { 
+                       imp_unqual = unitModuleEnvByName qual_mod_name unqual_avails,
+                       imp_env    = avail_env,
+                       imp_mods   = unitModuleEnv imp_mod (imp_mod, import_all),
+                       dep_mods   = mkModDeps dependent_mods,
+                       dep_pkgs   = dependent_pkgs }
+
+    in
        -- Complain if we import a deprecated module
     ifOptM Opt_WarnDeprecations        (
        case deprecs of 
@@ -169,24 +228,14 @@ importsFromImportDecl this_mod_name
          other         -> returnM ()
     )                                                  `thenM_`
 
-       -- Filter the imports according to the import list
-    filterImports imp_mod_name is_boot import_spec avails      `thenM` \ (filtered_avails, explicits) ->
-
-    let
-       unqual_imp = not qual_only      -- Maybe want unqualified names
-       qual_mod   = case as_mod of
-                       Nothing           -> imp_mod_name
-                       Just another_name -> another_name
-
-       mk_prov name = NonLocalDef (UserImport imp_mod iloc (name `elemNameSet` explicits)) 
-       gbl_env      = mkGlobalRdrEnv qual_mod unqual_imp mk_prov filtered_avails deprecs
-       imports      = mkImportAvails qual_mod unqual_imp filtered_avails
-    in
-    returnM (gbl_env, imports { imp_mods = dir_imp})
+    returnM (gbl_env, imports)
     }
 
-import_all (Just (False, _)) = False   -- Imports are spec'd explicitly
-import_all other            = True     -- Everything is imported
+mkModDeps :: [(ModuleName, WhetherHasOrphans, IsBootInterface)]
+         -> ModuleEnv (ModuleName, WhetherHasOrphans, IsBootInterface)
+mkModDeps deps = foldl add emptyModuleEnv deps
+              where
+                add env elt@(m,_,_) = extendModuleEnvByName env m elt
 \end{code}
 
 
@@ -226,9 +275,9 @@ importsFromLocalDecls group
     doptM Opt_NoImplicitPrelude                `thenM` \ implicit_prelude ->
     let
        mod_name   = moduleName this_mod
-       unqual_imp = True       -- Want unqualified names
        mk_prov n  = LocalDef   -- Provenance is local
 
+       unqual_imp = True       -- Want unqualified names in scope
        gbl_env = mkGlobalRdrEnv mod_name unqual_imp mk_prov avails NoDeprecs
            -- NoDeprecs: don't complain about locally defined names
            -- For a start, we may be exporting a deprecated thing
@@ -255,13 +304,19 @@ importsFromLocalDecls group
            -- but that stops them being Exact, so they get looked up.  Sigh.
            -- It doesn't matter because it only affects the Data.Tuple really.
            -- The important thing is to trim down the exports.
-       imports = mkImportAvails mod_name unqual_imp avails'
+
        avails' | implicit_prelude = filter not_built_in_syntax avails
                | otherwise        = avails
        not_built_in_syntax a = not (all isBuiltInSyntaxName (availNames a))
                -- Only filter it if all the names of the avail are built-in
                -- In particular, lists have (:) which is not built in syntax
                -- so we don't filter it out.
+
+       avail_env = mkAvailEnv avails'
+       imports   = emptyImportAvails {
+                       imp_unqual = unitModuleEnv this_mod avail_env,
+                       imp_env    = avail_env
+                   }
     in
     returnM (gbl_env, imports)
 \end{code}
@@ -314,7 +369,7 @@ getLocalDeclBinders mod (HsGroup {hs_valds = val_decls,
 available, and filters it through the import spec (if any).
 
 \begin{code}
-filterImports :: ModuleName                    -- The module being imported
+filterImports :: Module                                -- The module being imported
              -> IsBootInterface                -- Tells whether it's a {-# SOURCE #-} import
              -> Maybe (Bool, [RdrNameIE])      -- Import spec; True => hiding
              -> [AvailInfo]                    -- What's available
index badd84d..1210d3c 100644 (file)
@@ -88,7 +88,7 @@ import ErrUtils               ( mkDumpDoc, showPass )
 import Id              ( Id, mkLocalId, isLocalId, idName, idType, idUnfolding, setIdLocalExported )
 import IdInfo          ( GlobalIdDetails(..) )
 import Var             ( Var, setGlobalIdDetails )
-import Module           ( Module, moduleName, moduleUserString )
+import Module           ( Module, moduleName, moduleUserString, moduleEnvElts )
 import Name            ( Name, isExternalName, getSrcLoc, nameOccName )
 import NameEnv         ( delListFromNameEnv )
 import NameSet
@@ -147,7 +147,7 @@ tcRnModule hsc_env pcs
        updGblEnv ( \ gbl -> gbl { tcg_rdr_env = rdr_env,
                                   tcg_imports = tcg_imports gbl `plusImportAvails` imports }) 
                     $ do {
-       traceRn (text "rn1") ;
+       traceRn (text "rn1" <+> ppr (dep_mods imports)) ;
                -- Fail if there are any errors so far
                -- The error printing (if needed) takes advantage 
                -- of the tcg_env we have now set
@@ -172,7 +172,6 @@ tcRnModule hsc_env pcs
        updGblEnv (\gbl -> gbl { tcg_deprecs = tcg_deprecs gbl `plusDeprecs` mod_deprecs })
                  $ do {
 
-       traceRn (text "Rn4:" <+> ppr (imp_unqual (tcg_imports tcg_env))) ;
                -- Process the export list
        export_avails <- exportsFromAvail exports ;
        updGblEnv (\gbl -> gbl { tcg_exports = export_avails })
@@ -557,6 +556,7 @@ tcRnExtCore hsc_env pcs
        mod_guts = ModGuts {    mg_module   = this_mod,
                                mg_usages   = [],       -- ToDo: compute usage
                                mg_dir_imps = [],       -- ??
+                               mg_deps     = ([],[]),  -- ??
                                mg_exports  = my_exports,
                                mg_types    = final_type_env,
                                mg_insts    = tcg_insts tcg_env,
@@ -1166,11 +1166,14 @@ tcCoreDump mod_guts
 pprTcGblEnv :: TcGblEnv -> SDoc
 pprTcGblEnv (TcGblEnv { tcg_type_env = type_env, 
                        tcg_insts    = dfun_ids, 
-                       tcg_rules    = rules })
+                       tcg_rules    = rules,
+                       tcg_imports  = imports })
   = vcat [ ppr_types dfun_ids type_env
         , ppr_insts dfun_ids
         , vcat (map ppr rules)
-        , ppr_gen_tycons (typeEnvTyCons type_env)]
+        , ppr_gen_tycons (typeEnvTyCons type_env)
+        , ppr (moduleEnvElts (dep_mods imports))
+        , ppr (dep_pkgs imports)]
 
 pprModGuts :: ModGuts -> SDoc
 pprModGuts (ModGuts { mg_types = type_env,
index 07dbe12..22eae1b 100644 (file)
@@ -14,7 +14,7 @@ import HscTypes               ( HscEnv(..), PersistentCompilerState(..),
                          GlobalRdrEnv, LocalRdrEnv, NameCache, FixityEnv,
                          GhciMode, lookupType, unQualInScope )
 import TcRnTypes
-import Module          ( Module, moduleName, foldModuleEnv )
+import Module          ( Module, moduleName, unitModuleEnv, foldModuleEnv )
 import Name            ( Name, isInternalName )
 import Type            ( Type )
 import NameEnv         ( extendNameEnvList )
@@ -177,13 +177,12 @@ initTc  (HscEnv { hsc_mode   = ghci_mode,
   where
     eps = pcs_EPS pcs
 
-    init_imports = mkImportAvails (moduleName mod) True []
+    init_imports = emptyImportAvails { imp_unqual = unitModuleEnv mod emptyAvailEnv }
        -- Initialise tcg_imports with an empty set of bindings for
        -- this module, so that if we see 'module M' in the export
        -- list, and there are no bindings in M, we don't bleat 
        -- "unknown module M".
 
-
 defaultDefaultTys :: [Type]
 defaultDefaultTys = [integerTy, doubleTy]
 
@@ -283,6 +282,9 @@ getModule = do { env <- getGblEnv; return (tcg_mod env) }
 getGlobalRdrEnv :: TcRn m GlobalRdrEnv
 getGlobalRdrEnv = do { env <- getGblEnv; return (tcg_rdr_env env) }
 
+getImports :: TcRn m ImportAvails
+getImports = do { env <- getGblEnv; return (tcg_imports env) }
+
 getFixityEnv :: TcRn m FixityEnv
 getFixityEnv = do { env <- getGblEnv; return (tcg_fix_env env) }
 
@@ -296,13 +298,13 @@ getDefaultTys = do { env <- getGblEnv; return (tcg_default env) }
 \end{code}
 
 \begin{code}
-getUsageVar :: TcRn m (TcRef Usages)
+getUsageVar :: TcRn m (TcRef EntityUsage)
 getUsageVar = do { env <- getGblEnv; return (tcg_usages env) }
 
-getUsages :: TcRn m Usages
+getUsages :: TcRn m EntityUsage
 getUsages = do { usg_var <- getUsageVar; readMutVar usg_var }
 
-updUsages :: (Usages -> Usages) -> TcRn m () 
+updUsages :: (EntityUsage -> EntityUsage) -> TcRn m () 
 updUsages upd = do { usg_var <- getUsageVar ;
                     usg <- readMutVar usg_var ;
                     writeMutVar usg_var (upd usg) }
index ef32d2e..17c3e0a 100644 (file)
@@ -19,10 +19,11 @@ module TcRnTypes(
 
        -- Ranamer types
        RnMode(..), isInterfaceMode, isCmdLineMode,
-       Usages(..), emptyUsages, ErrCtxt,
-       ImportAvails(..), emptyImportAvails, plusImportAvails, mkImportAvails,
+       EntityUsage, emptyUsages, ErrCtxt,
+       ImportAvails(..), emptyImportAvails, plusImportAvails, 
        plusAvail, pruneAvails,  
-       AvailEnv, emptyAvailEnv, unitAvailEnv, plusAvailEnv, lookupAvailEnv, availEnvElts, addAvail,
+       AvailEnv, emptyAvailEnv, unitAvailEnv, plusAvailEnv, 
+       mkAvailEnv, lookupAvailEnv, availEnvElts, addAvail,
        WhereFrom(..),
 
        -- Typechecker types
@@ -48,7 +49,8 @@ import RnHsSyn                ( RenamedHsExpr, RenamedPat, RenamedArithSeqInfo )
 import HscTypes                ( GhciMode, ExternalPackageState, HomePackageTable, NameCache,
                          GlobalRdrEnv, LocalRdrEnv, FixityEnv, TypeEnv, TyThing, 
                          Avails, GenAvailInfo(..), AvailInfo, availName,
-                         IsBootInterface, Deprecations )
+                         IsBootInterface, Deprecations, WhetherHasOrphans )
+import Packages                ( PackageName )
 import TcType          ( TcTyVarSet, TcType, TcTauType, TcThetaType, TcPredType, TcKind,
                          tcCmpPred, tcCmpType, tcCmpTypes )
 import InstEnv         ( DFunId, InstEnv )
@@ -258,9 +260,8 @@ data TopEnv -- Built once at top level then does not change
 data TcGblEnv
   = TcGblEnv {
        tcg_mod    :: Module,           -- Module being compiled
-       tcg_usages :: TcRef Usages,     -- What version of what entities 
-                                       -- have been used from other modules
-                                       -- (whether home or ext-package modules)
+       tcg_usages :: TcRef EntityUsage,  -- What version of what entities 
+                                         -- have been used from other home-pkg modules
        tcg_rdr_env :: GlobalRdrEnv,    -- Top level envt; used during renaming
        tcg_fix_env :: FixityEnv,       -- Ditto
        tcg_default :: [Type],          -- Types used for defaulting
@@ -416,34 +417,27 @@ isCmdLineMode _ = False
 
 %************************************************************************
 %*                                                                     *
-                       Usages
+                       EntityUsage
 %*                                                                     *
 %************************************************************************
 
-Usages tells what things are actually need in order to compile this
-module.  It is used 
-       * for generating the usages field of the ModIface
-       * for reporting unused things in scope
+EntityUsage tells what things are actually need in order to compile this
+module.  It is used for generating the usage-version field of the ModIface.
 
-\begin{code}
-data Usages
-  = Usages {
-       usg_ext :: ModuleSet,
-               -- The non-home-package modules from which we have
-               -- slurped at least one name.
-
-       usg_home :: NameSet
-               -- The Names are all the (a) home-package
-               --                       (b) "big" (i.e. no data cons, class ops)
-               --                       (c) non-locally-defined
-               --                       (d) non-wired-in
-               -- names that have been slurped in so far.
-               -- This is used to generate the "usage" information for this module.
-    }
+Note that we do not record version info for entities from 
+other (non-home) packages.  If the package changes, GHC doesn't help.
 
-emptyUsages :: Usages
-emptyUsages = Usages { usg_ext = emptyModuleSet,
-                      usg_home = emptyNameSet }
+\begin{code}
+type EntityUsage = NameSet
+       -- The Names are all the (a) home-package
+       --                       (b) "big" (i.e. no data cons, class ops)
+       --                       (c) non-locally-defined
+       --                       (d) non-wired-in
+       -- names that have been slurped in so far.
+       -- This is used to generate the "usage" information for this module.
+
+emptyUsages :: EntityUsage
+emptyUsages = emptyNameSet
 \end{code}
 
 
@@ -477,7 +471,7 @@ data ImportAvails
                -- combine stuff coming from different (unqualified) 
                -- imports of the same module
 
-       imp_mods :: ModuleEnv (Module, Bool)
+       imp_mods :: ModuleEnv (Module, Bool),
                -- Domain is all directly-imported modules
                -- Bool is True if there was an unrestricted import
                --      (i.e. not a selective list)
@@ -488,45 +482,48 @@ data ImportAvails
                --       the interface file; if we import everything we
                --       need to recompile if the module version changes
                --   (b) to specify what child modules to initialise
+
+       dep_mods :: ModuleEnv (ModuleName, WhetherHasOrphans, IsBootInterface),
+               -- For a given import or set of imports, 
+               -- there's an entry here for
+               -- (a) modules below the one being compiled, in the current package
+               -- (b) orphan modules below the one being compiled, regardless of package
+               --
+               -- It doesn't matter whether any of these dependencies are actually
+               -- *used* when compiling the module; they are listed if they are below
+               -- it at all.  For example, suppose M imports A which imports X.  Then
+               -- compiling M might not need to consult X.hi, but X is still listed
+               -- in M's dependencies.
+
+       dep_pkgs :: [PackageName]
+               -- Packages needed by the module being compiled, whether
+               -- directly, or via other modules in this package, or via
+               -- modules imported from other packages.
       }
 
 emptyImportAvails :: ImportAvails
 emptyImportAvails = ImportAvails { imp_env    = emptyAvailEnv, 
                                   imp_unqual = emptyModuleEnv, 
-                                  imp_mods   = emptyModuleEnv }
+                                  imp_mods   = emptyModuleEnv,
+                                  dep_mods   = emptyModuleEnv,
+                                  dep_pkgs   = [] }
 
 plusImportAvails ::  ImportAvails ->  ImportAvails ->  ImportAvails
 plusImportAvails
-  (ImportAvails { imp_env = env1, imp_unqual = unqual1, imp_mods = mods1 })
-  (ImportAvails { imp_env = env2, imp_unqual = unqual2, imp_mods = mods2 })
+  (ImportAvails { imp_env = env1, imp_unqual = unqual1, imp_mods = mods1,
+                 dep_mods = dmods1, dep_pkgs = dpkgs1 })
+  (ImportAvails { imp_env = env2, imp_unqual = unqual2, imp_mods = mods2,
+                 dep_mods = dmods2, dep_pkgs = dpkgs2 })
   = ImportAvails { imp_env    = env1 `plusAvailEnv` env2, 
                   imp_unqual = plusModuleEnv_C plusAvailEnv unqual1 unqual2, 
-                  imp_mods   = mods1 `plusModuleEnv` mods2 }
-
-mkImportAvails :: ModuleName -> Bool
-              -> [AvailInfo] -> ImportAvails
-mkImportAvails mod_name unqual_imp avails 
-  = ImportAvails { imp_unqual = mod_avail_env, 
-                  imp_env    = entity_avail_env,
-                  imp_mods   = emptyModuleEnv }-- Stays empty for module being compiled;
-                                               -- gets updated for imported modules
+                  imp_mods   = mods1  `plusModuleEnv` mods2,   
+                  dep_mods   = plusModuleEnv_C plus_mod_dep dmods1 dmods2,     
+                  dep_pkgs   = nub (dpkgs1 ++ dpkgs2)   }
   where
-    mod_avail_env = unitModuleEnvByName mod_name unqual_avails 
-
-       -- 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
-       --      module M ( module P ) where ...
-       -- Then we must export whatever came from P unqualified.
-
-    unqual_avails | not unqual_imp = emptyAvailEnv     -- Qualified import
-                 | otherwise      = entity_avail_env   -- Unqualified import
-
-    entity_avail_env = foldl insert emptyAvailEnv avails
-    insert env avail = extendNameEnv_C plusAvail env (availName avail) avail
-       -- 'avails' may have several items with the same availName
-       -- E.g  import Ix( Ix(..), index )
-       -- will give Ix(Ix,index,range) and Ix(index)
-       -- We want to combine these
+    plus_mod_dep (m1, orphan1, boot1) (m2, orphan2, boot2) 
+       = ASSERT( m1 == m2 && orphan1 == orphan2 )
+         (m1, orphan1, boot1 && boot2)
+       -- If either side can "see" a non-hi-boot interface, use that
 \end{code}
 
 %************************************************************************
@@ -581,6 +578,13 @@ availEnvElts = nameEnvElts
 
 addAvail :: AvailEnv -> AvailInfo -> AvailEnv
 addAvail avails avail = extendNameEnv_C plusAvail avails (availName avail) avail
+
+mkAvailEnv :: [AvailInfo] -> AvailEnv
+       -- 'avails' may have several items with the same availName
+       -- E.g  import Ix( Ix(..), index )
+       -- will give Ix(Ix,index,range) and Ix(index)
+       -- We want to combine these; addAvail does that
+mkAvailEnv avails = foldl addAvail emptyAvailEnv avails
 \end{code}
 
 %************************************************************************
@@ -598,9 +602,7 @@ data WhereFrom
   | ImportForUsage IsBootInterface     -- Import when chasing usage info from an interaface file
                                        --      Failure in this case is not an error
 
-  | ImportBySystem                     -- Non user import.  Use eps_mod_info to decide whether
-                                       -- the module this module depends on, or is a system-ish module; 
-                                       -- M.hi-boot otherwise
+  | ImportBySystem                     -- Non user import.
 
 instance Outputable WhereFrom where
   ppr (ImportByUser is_boot) | is_boot     = ptext SLIT("{- SOURCE -}")