Interface file optimisation and removal of nameParent
[ghc-hetmet.git] / compiler / main / HscTypes.lhs
index c46d78e..d3c5f7f 100644 (file)
@@ -1,5 +1,5 @@
-
-% (c) The University of Glasgow, 2000
+%
+% (c) The University of Glasgow, 2006
 %
 \section[HscTypes]{Types for the per-module compiler}
 
@@ -7,7 +7,7 @@
 module HscTypes ( 
        -- * Sessions and compilation state
        Session(..), HscEnv(..), hscEPS,
-       FinderCache, FinderCacheEntry,
+       FinderCache, FindResult(..), ModLocationCache,
        Target(..), TargetId(..), pprTarget, pprTargetId,
        ModuleGraph, emptyMG,
 
@@ -24,29 +24,30 @@ module HscTypes (
 
        ExternalPackageState(..), EpsStats(..), addEpsInStats,
        PackageTypeEnv, PackageIfaceTable, emptyPackageIfaceTable,
-       lookupIface, lookupIfaceByModule, emptyModIface,
+       lookupIfaceByModule, emptyModIface,
 
        InteractiveContext(..), emptyInteractiveContext, 
-       icPrintUnqual, unQualInScope,
+       icPrintUnqual, mkPrintUnqualified,
 
        ModIface(..), mkIfaceDepCache, mkIfaceVerCache, mkIfaceFixCache,
-       emptyIfaceDepCache, 
+       emptyIfaceDepCache,
 
        Deprecs(..), IfaceDeprecs,
 
        FixityEnv, FixItem(..), lookupFixity, emptyFixityEnv,
 
-       implicitTyThings, 
+       implicitTyThings, isImplicitTyThing,
 
        TyThing(..), tyThingClass, tyThingTyCon, tyThingDataCon, tyThingId,
        TypeEnv, lookupType, mkTypeEnv, emptyTypeEnv,
        extendTypeEnv, extendTypeEnvList, extendTypeEnvWithIds, lookupTypeEnv,
        typeEnvElts, typeEnvClasses, typeEnvTyCons, typeEnvIds,
+       typeEnvDataCons,
 
        WhetherHasOrphans, IsBootInterface, Usage(..), 
        Dependencies(..), noDependencies,
        NameCache(..), OrigNameCache, OrigIParamCache,
-       Avails, availsToNameSet, availName, availNames,
+       Avails, availsToNameSet, availsToNameEnv, availName, availNames,
        GenAvailInfo(..), AvailInfo, RdrAvailInfo, 
        IfaceExport,
 
@@ -67,8 +68,9 @@ import ByteCodeAsm    ( CompiledByteCode )
 #endif
 
 import RdrName         ( GlobalRdrEnv, emptyGlobalRdrEnv,
-                         LocalRdrEnv, emptyLocalRdrEnv,
-                         GlobalRdrElt(..), mkRdrUnqual, lookupGRE_RdrName )
+                         LocalRdrEnv, emptyLocalRdrEnv, GlobalRdrElt(..), 
+                          unQualOK, ImpDeclSpec(..), Provenance(..),
+                          ImportSpec(..), lookupGlobalRdrEnv )
 import Name            ( Name, NamedThing, getName, nameOccName, nameModule )
 import NameEnv
 import NameSet 
@@ -76,33 +78,34 @@ import OccName              ( OccName, OccEnv, lookupOccEnv, mkOccEnv, emptyOccEnv,
                          extendOccEnv )
 import Module
 import InstEnv         ( InstEnv, Instance )
+import FamInstEnv      ( FamInstEnv, FamInst )
 import Rules           ( RuleBase )
 import CoreSyn         ( CoreBind )
-import Id              ( Id )
+import Id              ( Id, isImplicitId )
 import Type            ( TyThing(..) )
 
-import Class           ( Class, classSelIds, classTyCon )
-import TyCon           ( TyCon, tyConSelIds, tyConDataCons )
-import DataCon         ( dataConImplicitIds )
+import Class           ( Class, classSelIds, classATs, classTyCon )
+import TyCon
+import DataCon         ( DataCon, dataConImplicitIds )
 import PrelNames       ( gHC_PRIM )
-import Packages                ( PackageIdH, PackageId, PackageConfig, HomeModules )
+import Packages                ( PackageId )
 import DynFlags                ( DynFlags(..), isOneShot, HscTarget (..) )
 import DriverPhases    ( HscSource(..), isHsBoot, hscSourceString, Phase )
 import BasicTypes      ( Version, initialVersion, IPName, 
                          Fixity, defaultFixity, DeprecTxt )
-
-import IfaceSyn                ( IfaceInst, IfaceRule, IfaceDecl(ifName) )
-
+import IfaceSyn
 import FiniteMap       ( FiniteMap )
 import CoreSyn         ( CoreRule )
-import Maybes          ( orElse, expectJust, expectJust )
+import Maybes          ( orElse, expectJust )
 import Outputable
 import SrcLoc          ( SrcSpan, Located )
+import UniqFM          ( lookupUFM, eltsUFM, emptyUFM )
 import UniqSupply      ( UniqSupply )
 import FastString      ( FastString )
 
 import DATA_IOREF      ( IORef, readIORef )
 import StringBuffer    ( StringBuffer )
+import Maybes           ( catMaybes, seqMaybe )
 import Time            ( ClockTime )
 \end{code}
 
@@ -172,9 +175,11 @@ data HscEnv
                -- sucking in interface files.  They cache the state of
                -- external interface files, in effect.
 
-       hsc_FC  :: {-# UNPACK #-} !(IORef FinderCache),
+       hsc_FC   :: {-# UNPACK #-} !(IORef FinderCache),
+       hsc_MLC  :: {-# UNPACK #-} !(IORef ModLocationCache),
                -- The finder's cache.  This caches the location of modules,
                -- so we don't have to search the filesystem multiple times.
+
         hsc_global_rdr_env :: GlobalRdrEnv,
         hsc_global_type_env :: TypeEnv
  }
@@ -191,7 +196,7 @@ hscEPS hsc_env = readIORef (hsc_EPS hsc_env)
 data Target = Target TargetId (Maybe (StringBuffer,ClockTime))
 
 data TargetId
-  = TargetModule Module
+  = TargetModule ModuleName
        -- ^ A module name: search for the file
   | TargetFile FilePath (Maybe Phase)
        -- ^ A filename: preprocess & parse it to find the module name.
@@ -206,16 +211,13 @@ pprTarget (Target id _) = pprTargetId id
 pprTargetId (TargetModule m) = ppr m
 pprTargetId (TargetFile f _) = text f
 
-type FinderCache = ModuleEnv FinderCacheEntry
-type FinderCacheEntry = (ModLocation, Maybe (PackageConfig,Bool))
-       -- The finder's cache (see module Finder)
-
-type HomePackageTable  = ModuleEnv HomeModInfo
+type HomePackageTable  = ModuleNameEnv HomeModInfo
        -- Domain = modules in the home package
+       -- "home" package name cached here for convenience
 type PackageIfaceTable = ModuleEnv ModIface
        -- Domain = modules in the imported packages
 
-emptyHomePackageTable  = emptyModuleEnv
+emptyHomePackageTable  = emptyUFM
 emptyPackageIfaceTable = emptyModuleEnv
 
 data HomeModInfo 
@@ -232,40 +234,46 @@ data HomeModInfo
                -- When re-linking a module (hscNoRecomp), we construct
                -- the HomModInfo by building a new ModDetails from the
                -- old ModIface (only).
-\end{code}
-
-Simple lookups in the symbol table.
 
-\begin{code}
-lookupIface :: HomePackageTable -> PackageIfaceTable -> Module -> Maybe ModIface
--- We often have two IfaceTables, and want to do a lookup
-lookupIface hpt pit mod
-  = case lookupModuleEnv hpt mod of
-       Just mod_info -> Just (hm_iface mod_info)
-       Nothing       -> lookupModuleEnv pit mod
-
-lookupIfaceByModule :: HomePackageTable -> PackageIfaceTable -> Module -> Maybe ModIface
--- We often have two IfaceTables, and want to do a lookup
-lookupIfaceByModule hpt pit mod
-  = case lookupModuleEnv hpt mod of
-       Just mod_info -> Just (hm_iface mod_info)
-       Nothing       -> lookupModuleEnv pit mod
+-- | Find the 'ModIface' for a 'Module'
+lookupIfaceByModule
+       :: DynFlags
+       -> HomePackageTable
+       -> PackageIfaceTable
+       -> Module
+       -> Maybe ModIface
+lookupIfaceByModule dflags hpt pit mod
+  | modulePackageId mod == thisPackage dflags
+  =    -- The module comes from the home package, so look first
+       -- in the HPT.  If it's not from the home package it's wrong to look
+       -- in the HPT, because the HPT is indexed by *ModuleName* not Module
+    fmap hm_iface (lookupUFM hpt (moduleName mod)) 
+    `seqMaybe` lookupModuleEnv pit mod
+
+  | otherwise = lookupModuleEnv pit mod                -- Look in PIT only 
+
+-- If the module does come from the home package, why do we look in the PIT as well?
+-- (a) In OneShot mode, even home-package modules accumulate in the PIT
+-- (b) Even in Batch (--make) mode, there is *one* case where a home-package
+--     module is in the PIT, namely GHC.Prim when compiling the base package.
+-- We could eliminate (b) if we wanted, by making GHC.Prim belong to a packake
+-- of its own, but it doesn't seem worth the bother.
 \end{code}
 
 
 \begin{code}
-hptInstances :: HscEnv -> (Module -> Bool) -> [Instance]
+hptInstances :: HscEnv -> (ModuleName -> Bool) -> [Instance]
 -- Find all the instance declarations that are in modules imported 
 -- by this one, directly or indirectly, and are in the Home Package Table
 -- This ensures that we don't see instances from modules --make compiled 
 -- before this one, but which are not below this one
 hptInstances hsc_env want_this_module
   = [ ispec 
-    | mod_info <- moduleEnvElts (hsc_HPT hsc_env)
-    , want_this_module (mi_module (hm_iface mod_info))
+    | mod_info <- eltsUFM (hsc_HPT hsc_env)
+    , want_this_module (moduleName (mi_module (hm_iface mod_info)))
     , ispec <- md_insts (hm_details mod_info) ]
 
-hptRules :: HscEnv -> [(Module, IsBootInterface)] -> [CoreRule]
+hptRules :: HscEnv -> [(ModuleName, IsBootInterface)] -> [CoreRule]
 -- Get rules from modules "below" this one (in the dependency sense)
 -- C.f Inst.hptInstances
 hptRules hsc_env deps
@@ -283,10 +291,10 @@ hptRules hsc_env deps
        -- be in the HPT, because we never compile it; it's in the EPT
        -- instead.  ToDo: clean up, and remove this slightly bogus
        -- filter:
-    , mod /= gHC_PRIM
+    , mod /= moduleName gHC_PRIM
 
        -- Look it up in the HPT
-    , let mod_info = case lookupModuleEnv hpt mod of
+    , let mod_info = case lookupUFM hpt mod of
                        Nothing -> pprPanic "hptRules" (ppr mod <+> ppr deps)
                        Just x  -> x
 
@@ -294,6 +302,47 @@ hptRules hsc_env deps
     , rule <- md_rules (hm_details mod_info) ]
 \end{code}
 
+%************************************************************************
+%*                                                                     *
+\subsection{The Finder cache}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+-- | The 'FinderCache' maps home module names to the result of
+-- searching for that module.  It records the results of searching for
+-- modules along the search path.  On @:load@, we flush the entire
+-- contents of this cache.
+--
+-- Although the @FinderCache@ range is 'FindResult' for convenience ,
+-- in fact it will only ever contain 'Found' or 'NotFound' entries.
+--
+type FinderCache = ModuleNameEnv FindResult
+
+-- | The result of searching for an imported module.
+data FindResult
+  = Found ModLocation Module
+       -- the module was found
+  | NoPackage PackageId
+       -- the requested package was not found
+  | FoundMultiple [PackageId]
+       -- *error*: both in multiple packages
+  | PackageHidden PackageId
+       -- for an explicit source import: the package containing the module is
+       -- not exposed.
+  | ModuleHidden  PackageId
+       -- for an explicit source import: the package containing the module is
+       -- exposed, but the module itself is hidden.
+  | NotFound [FilePath] (Maybe PackageId)
+       -- the module was not found, the specified places were searched
+  | NotFoundInPackage PackageId
+       -- the module was not found in this package
+
+-- | Cache that remembers where we found a particular module.  Contains both
+-- home modules and package modules.  On @:load@, only home modules are
+-- purged from this cache.
+type ModLocationCache = ModuleEnv ModLocation
+\end{code}
 
 %************************************************************************
 %*                                                                     *
@@ -313,7 +362,6 @@ the declarations into a single indexed map in the @PersistentRenamerState@.
 \begin{code}
 data ModIface 
    = ModIface {
-       mi_package  :: !PackageIdH,         -- Which package the module comes from
         mi_module   :: !Module,
         mi_mod_vers :: !Version,           -- Module version: changes when anything changes
 
@@ -367,35 +415,41 @@ data ModIface
                -- HomeModInfo, but that leads to more plumbing.
 
                -- Instance declarations and rules
-       mi_insts     :: [IfaceInst],    -- Sorted
-       mi_rules     :: [IfaceRule],    -- Sorted
-       mi_rule_vers :: !Version,       -- Version number for rules and instances combined
+       mi_insts     :: [IfaceInst],                    -- Sorted
+       mi_fam_insts :: [IfaceFamInst],                 -- Sorted
+       mi_rules     :: [IfaceRule],                    -- Sorted
+       mi_rule_vers :: !Version,       -- Version number for rules and 
+                                       -- instances combined
 
                -- Cached environments for easy lookup
                -- These are computed (lazily) from other fields
                -- and are not put into the interface file
        mi_dep_fn  :: Name -> Maybe DeprecTxt,  -- Cached lookup for mi_deprecs
        mi_fix_fn  :: OccName -> Fixity,        -- Cached lookup for mi_fixities
-       mi_ver_fn  :: OccName -> Maybe Version  -- Cached lookup for mi_decls
+       mi_ver_fn  :: OccName -> Maybe (OccName, Version)
+                        -- Cached lookup for mi_decls
                        -- The Nothing in mi_ver_fn means that the thing
                        -- isn't in decls. It's useful to know that when
                        -- seeing if we are up to date wrt the old interface
+                        -- The 'OccName' is the parent of the name, if it has one.
      }
 
 -- Should be able to construct ModDetails from mi_decls in ModIface
 data ModDetails
    = ModDetails {
        -- The next three fields are created by the typechecker
-       md_exports  :: NameSet,
+       md_exports  :: [AvailInfo],
         md_types    :: !TypeEnv,
+        md_fam_insts :: ![FamInst],    -- Cached value extracted from md_types
         md_insts    :: ![Instance],    -- Dfun-ids for the instances in this module
         md_rules    :: ![CoreRule]     -- Domain may include Ids from other modules
      }
 
 emptyModDetails = ModDetails { md_types = emptyTypeEnv,
-                              md_exports = emptyNameSet,
-                              md_insts = [],
-                              md_rules = [] }
+                              md_exports = [],
+                              md_insts     = [],
+                              md_rules     = [],
+                              md_fam_insts = [] }
 
 -- 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
@@ -404,24 +458,26 @@ emptyModDetails = ModDetails { md_types = emptyTypeEnv,
 
 data ModGuts
   = ModGuts {
-        mg_module   :: !Module,
-       mg_boot     :: IsBootInterface, -- Whether it's an hs-boot module
-       mg_exports  :: !NameSet,        -- What it exports
-       mg_deps     :: !Dependencies,   -- What is below it, directly or otherwise
-       mg_home_mods :: !HomeModules,   -- For calling isHomeModule etc.
-       mg_dir_imps :: ![Module],       -- Directly-imported modules; used to
-                                       --      generate initialisation code
-       mg_usages   :: ![Usage],        -- Version info for what it needed
-
-        mg_rdr_env  :: !GlobalRdrEnv,  -- Top-level lexical environment
-       mg_fix_env  :: !FixityEnv,      -- Fixity env, for things declared in this module
-       mg_deprecs  :: !Deprecations,   -- Deprecations declared in the module
-
-       mg_types    :: !TypeEnv,
-       mg_insts    :: ![Instance],     -- Instances 
-        mg_rules    :: ![CoreRule],    -- Rules from this module
-       mg_binds    :: ![CoreBind],     -- Bindings for this module
-       mg_foreign  :: !ForeignStubs
+        mg_module    :: !Module,
+       mg_boot      :: IsBootInterface, -- Whether it's an hs-boot module
+       mg_exports   :: ![AvailInfo],    -- 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],        -- 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 
+       mg_deprecs   :: !Deprecations,   -- Deprecations declared in the module
+
+       mg_types     :: !TypeEnv,
+       mg_insts     :: ![Instance],     -- Instances 
+       mg_fam_insts :: ![FamInst],      -- Instances 
+        mg_rules     :: ![CoreRule],    -- Rules from this module
+       mg_binds     :: ![CoreBind],     -- Bindings for this module
+       mg_foreign   :: !ForeignStubs
     }
 
 -- The ModGuts takes on several slightly different forms:
@@ -458,7 +514,6 @@ data CgGuts
                -- initialisation code
 
        cg_foreign  :: !ForeignStubs,   
-       cg_home_mods :: !HomeModules,   -- for calling isHomeModule etc.
        cg_dep_pkgs :: ![PackageId]     -- Used to generate #includes for C code gen
     }
 
@@ -489,10 +544,9 @@ data ForeignStubs = NoStubs
 \end{code}
 
 \begin{code}
-emptyModIface :: PackageIdH -> Module -> ModIface
-emptyModIface pkg mod
-  = ModIface { mi_package  = pkg,
-              mi_module   = mod,
+emptyModIface :: Module -> ModIface
+emptyModIface mod
+  = ModIface { mi_module   = mod,
               mi_mod_vers = initialVersion,
               mi_orphan   = False,
               mi_boot     = False,
@@ -502,10 +556,11 @@ emptyModIface pkg mod
               mi_exp_vers = initialVersion,
               mi_fixities = [],
               mi_deprecs  = NoDeprecs,
-              mi_insts = [],
-              mi_rules = [],
-              mi_decls = [],
-              mi_globals  = Nothing,
+              mi_insts     = [],
+              mi_fam_insts = [],
+              mi_rules     = [],
+              mi_decls     = [],
+              mi_globals   = Nothing,
               mi_rule_vers = initialVersion,
               mi_dep_fn = emptyIfaceDepCache,
               mi_fix_fn = emptyIfaceFixCache,
@@ -546,25 +601,32 @@ emptyInteractiveContext
                         ic_type_env = emptyTypeEnv }
 
 icPrintUnqual :: InteractiveContext -> PrintUnqualified
-icPrintUnqual ictxt = unQualInScope (ic_rn_gbl_env ictxt)
+icPrintUnqual ictxt = mkPrintUnqualified (ic_rn_gbl_env ictxt)
 \end{code}
 
-@unQualInScope@ returns a function that takes a @Name@ and tells whether
-its unqualified name is in scope.  This is put as a boolean flag in
-the @Name@'s provenance to guide whether or not to print the name qualified
-in error messages.
+%************************************************************************
+%*                                                                     *
+        Building a PrintUnqualified            
+%*                                                                     *
+%************************************************************************
 
 \begin{code}
-unQualInScope :: GlobalRdrEnv -> PrintUnqualified
--- True if 'f' is in scope, and has only one binding,
--- and the thing it is bound to is the name we are looking for
--- (i.e. false if A.f and B.f are both in scope as unqualified 'f')
---
--- [Out of date] Also checks for built-in syntax, which is always 'in scope'
-unQualInScope env mod occ
-  = case lookupGRE_RdrName (mkRdrUnqual occ) env of
-       [gre] -> nameModule (gre_name gre) == mod
-       other -> False
+mkPrintUnqualified :: GlobalRdrEnv -> PrintUnqualified
+mkPrintUnqualified env = (qual_name, qual_mod)
+  where
+  qual_name mod occ
+        | null gres = Just (moduleName mod)
+                -- it isn't in scope at all, this probably shouldn't happen,
+                -- but we'll qualify it by the original module anyway.
+        | any unQualOK gres = Nothing
+        | (Imported is : _) <- map gre_prov gres, (idecl : _) <- is
+          = Just (is_as (is_decl idecl))
+        | otherwise = panic "mkPrintUnqualified" 
+      where
+        gres  = [ gre | gre <- lookupGlobalRdrEnv env occ,
+                       nameModule (gre_name gre) == mod ]
+
+  qual_mod mod = Nothing       -- For now...
 \end{code}
 
 
@@ -576,24 +638,44 @@ unQualInScope env mod occ
 
 \begin{code}
 implicitTyThings :: TyThing -> [TyThing]
+-- If you change this, make sure you change LoadIface.ifaceDeclSubBndrs in sync
+
 implicitTyThings (AnId id)   = []
 
        -- For type constructors, add the data cons (and their extras),
        -- and the selectors and generic-programming Ids too
        --
        -- Newtypes don't have a worker Id, so don't generate that?
-implicitTyThings (ATyCon tc) = map AnId (tyConSelIds tc) ++ 
-                              concatMap (extras_plus . ADataCon) (tyConDataCons tc)
+implicitTyThings (ATyCon tc) = implicitCoTyCon tc ++
+                              map AnId (tyConSelIds tc) ++ 
+                              concatMap (extras_plus . ADataCon) 
+                                        (tyConDataCons tc)
                     
        -- For classes, add the class TyCon too (and its extras)
-       -- and the class selector Ids
+       -- and the class selector Ids and the associated types (they don't
+       -- have extras as these are only the family decls)
 implicitTyThings (AClass cl) = map AnId (classSelIds cl) ++
+                              map ATyCon (classATs cl) ++
                               extras_plus (ATyCon (classTyCon cl))
-                        
 
        -- For data cons add the worker and wrapper (if any)
 implicitTyThings (ADataCon dc) = map AnId (dataConImplicitIds dc)
 
+-- | returns 'True' if there should be no interface-file declaration
+-- for this thing on its own: either it is built-in, or it is part
+-- of some other declaration, or it is generated implicitly by some
+-- other declaration.
+isImplicitTyThing :: TyThing -> Bool
+isImplicitTyThing (ADataCon _)  = True
+isImplicitTyThing (AnId     id) = isImplicitId id
+isImplicitTyThing (AClass   _)  = False
+isImplicitTyThing (ATyCon   tc) = isImplicitTyCon tc
+
+       -- For newtypes and indexed data types, add the implicit coercion tycon
+implicitCoTyCon tc 
+  = map ATyCon . catMaybes $ [newTyConCo_maybe tc, 
+                             tyConFamilyCoercion_maybe tc]
+
 extras_plus thing = thing : implicitTyThings thing
 
 extendTypeEnvWithIds :: TypeEnv -> [Id] -> TypeEnv
@@ -610,18 +692,20 @@ extendTypeEnvWithIds env ids
 \begin{code}
 type TypeEnv = NameEnv TyThing
 
-emptyTypeEnv   :: TypeEnv
-typeEnvElts    :: TypeEnv -> [TyThing]
-typeEnvClasses :: TypeEnv -> [Class]
-typeEnvTyCons  :: TypeEnv -> [TyCon]
-typeEnvIds     :: TypeEnv -> [Id]
-lookupTypeEnv  :: TypeEnv -> Name -> Maybe TyThing
-
-emptyTypeEnv      = emptyNameEnv
-typeEnvElts    env = nameEnvElts env
-typeEnvClasses env = [cl | AClass cl <- typeEnvElts env]
-typeEnvTyCons  env = [tc | ATyCon tc <- typeEnvElts env] 
-typeEnvIds     env = [id | AnId id   <- typeEnvElts env] 
+emptyTypeEnv    :: TypeEnv
+typeEnvElts     :: TypeEnv -> [TyThing]
+typeEnvClasses  :: TypeEnv -> [Class]
+typeEnvTyCons   :: TypeEnv -> [TyCon]
+typeEnvIds      :: TypeEnv -> [Id]
+typeEnvDataCons :: TypeEnv -> [DataCon]
+lookupTypeEnv   :: TypeEnv -> Name -> Maybe TyThing
+
+emptyTypeEnv       = emptyNameEnv
+typeEnvElts     env = nameEnvElts env
+typeEnvClasses  env = [cl | AClass cl   <- typeEnvElts env]
+typeEnvTyCons   env = [tc | ATyCon tc   <- typeEnvElts env] 
+typeEnvIds      env = [id | AnId id     <- typeEnvElts env] 
+typeEnvDataCons env = [dc | ADataCon dc <- typeEnvElts env] 
 
 mkTypeEnv :: [TyThing] -> TypeEnv
 mkTypeEnv things = extendTypeEnvList emptyTypeEnv things
@@ -637,14 +721,23 @@ extendTypeEnvList env things = foldl extendTypeEnv env things
 \end{code}
 
 \begin{code}
-lookupType :: HomePackageTable -> PackageTypeEnv -> Name -> Maybe TyThing
-lookupType hpt pte name
-  = case lookupModuleEnv hpt (nameModule name) of
-       Just details -> lookupNameEnv (md_types (hm_details details)) name
-       Nothing      -> lookupNameEnv pte name
+lookupType :: DynFlags
+          -> HomePackageTable
+          -> PackageTypeEnv
+          -> Name
+          -> Maybe TyThing
+
+lookupType dflags hpt pte name
+  -- in one-shot, we don't use the HPT
+  | not (isOneShot (ghcMode dflags)) && modulePackageId mod == this_pkg 
+  = do hm <- lookupUFM hpt (moduleName mod) -- Maybe monad
+       lookupNameEnv (md_types (hm_details hm)) name
+  | otherwise
+  = lookupNameEnv pte name
+  where mod = nameModule name
+       this_pkg = thisPackage dflags
 \end{code}
 
-
 \begin{code}
 tyThingTyCon (ATyCon tc) = tc
 tyThingTyCon other      = pprPanic "tyThingTyCon" (ppr other)
@@ -669,14 +762,19 @@ These types are defined here because they are mentioned in ModDetails,
 but they are mostly elaborated elsewhere
 
 \begin{code}
-mkIfaceVerCache :: [(Version,IfaceDecl)] -> OccName -> Maybe Version
+mkIfaceVerCache :: [(Version,IfaceDecl)]
+                -> (OccName -> Maybe (OccName, Version))
 mkIfaceVerCache pairs 
   = \occ -> lookupOccEnv env occ
   where
-    env = foldl add emptyOccEnv pairs
-    add env (v,d) = extendOccEnv env (ifName d) v
-
-emptyIfaceVerCache :: OccName -> Maybe Version
+    env = foldr add_decl emptyOccEnv pairs
+    add_decl (v,d) env0 = foldr add_imp env1 (ifaceDeclSubBndrs d)
+      where
+          decl_name = ifName d
+          env1 = extendOccEnv env0 decl_name (decl_name, v)
+          add_imp bndr env = extendOccEnv env bndr (decl_name, v)
+
+emptyIfaceVerCache :: OccName -> Maybe (OccName, Version)
 emptyIfaceVerCache occ = Nothing
 
 ------------------ Deprecations -------------------------
@@ -735,9 +833,13 @@ data GenAvailInfo name     = Avail name     -- An ordinary identifier
 type IfaceExport = (Module, [GenAvailInfo OccName])
 
 availsToNameSet :: [AvailInfo] -> NameSet
-availsToNameSet avails = foldl add emptyNameSet avails
-                      where
-                        add set avail = addListToNameSet set (availNames avail)
+availsToNameSet avails = foldr add emptyNameSet avails
+      where add avail set = addListToNameSet set (availNames avail)
+
+availsToNameEnv :: [AvailInfo] -> NameEnv AvailInfo
+availsToNameEnv avails = foldr add emptyNameEnv avails
+     where add avail env = extendNameEnvList env
+                                (zip (availNames avail) (repeat avail))
 
 availName :: GenAvailInfo name -> name
 availName (Avail n)     = n
@@ -809,7 +911,7 @@ type IsBootInterface = Bool
 -- Invariant: the dependencies of a module M never includes M
 -- Invariant: the lists are unordered, with no duplicates
 data Dependencies
-  = Deps { dep_mods  :: [(Module,IsBootInterface)],    -- Home-package module dependencies
+  = Deps { dep_mods  :: [(ModuleName,IsBootInterface)],        -- Home-package module dependencies
           dep_pkgs  :: [PackageId],                    -- External package dependencies
           dep_orphs :: [Module] }                      -- Orphan modules (whether home or external pkg)
   deriving( Eq )
@@ -819,9 +921,10 @@ noDependencies :: Dependencies
 noDependencies = Deps [] [] []
          
 data Usage
-  = Usage { usg_name     :: Module,                    -- Name of the module
+  = Usage { usg_name     :: ModuleName,                        -- Name of the module
            usg_mod      :: Version,                    -- Module version
            usg_entities :: [(OccName,Version)],        -- Sorted by occurrence name
+                -- NB. usages are for parent names only, eg. tycon but not constructors.
            usg_exports  :: Maybe Version,              -- Export-list version, if we depend on it
            usg_rules    :: Version                     -- Orphan-rules version (for non-orphan
                                                        -- modules this will always be initialVersion)
@@ -853,20 +956,23 @@ data Usage
 %************************************************************************
 
 \begin{code}
-type PackageTypeEnv  = TypeEnv
-type PackageRuleBase = RuleBase
-type PackageInstEnv  = InstEnv
+type PackageTypeEnv    = TypeEnv
+type PackageRuleBase   = RuleBase
+type PackageInstEnv    = InstEnv
+type PackageFamInstEnv = FamInstEnv
 
 data ExternalPackageState
   = EPS {
-       eps_is_boot :: !(ModuleEnv (Module, IsBootInterface)),
-               -- In OneShot mode (only), home-package modules accumulate in the
-               -- external package state, and are sucked in lazily.
-               -- For these home-pkg modules (only) we need to record which are
-               -- boot modules.  We set this field after loading all the 
-               -- explicitly-imported interfaces, but before doing anything else
+       eps_is_boot :: !(ModuleNameEnv (ModuleName, IsBootInterface)),
+               -- In OneShot mode (only), home-package modules
+               -- accumulate in the external package state, and are
+               -- sucked in lazily.  For these home-pkg modules
+               -- (only) we need to record which are boot modules.
+               -- We set this field after loading all the
+               -- explicitly-imported interfaces, but before doing
+               -- anything else
                --
-               -- The Module part is not necessary, but it's useful for
+               -- The ModuleName part is not necessary, but it's useful for
                -- debug prints, and it's convenient because this field comes
                -- direct from TcRnTypes.ImportAvails.imp_dep_mods
 
@@ -874,8 +980,8 @@ data ExternalPackageState
                -- The ModuleIFaces for modules in external packages
                -- whose interfaces we have opened
                -- The declarations in these interface files are held in
-               -- eps_decls, eps_inst_env, eps_rules (below), not in the 
-               -- mi_decls fields of the iPIT.  
+               -- eps_decls, eps_inst_env, eps_fam_inst_env, eps_rules
+               -- (below), not in the mi_decls fields of the iPIT.  
                -- What _is_ in the iPIT is:
                --      * The Module 
                --      * Version info
@@ -883,11 +989,13 @@ data ExternalPackageState
                --      * Fixities
                --      * Deprecations
 
-       eps_PTE :: !PackageTypeEnv,             -- Domain = external-package modules
+       eps_PTE :: !PackageTypeEnv,        -- Domain = external-package modules
 
-       eps_inst_env :: !PackageInstEnv,        -- The total InstEnv accumulated from
-                                               --   all the external-package modules
-       eps_rule_base :: !PackageRuleBase,      -- Ditto RuleEnv
+       eps_inst_env     :: !PackageInstEnv,   -- The total InstEnv accumulated
+                                              -- from all the external-package
+                                              -- modules 
+       eps_fam_inst_env :: !PackageFamInstEnv,-- Ditto FamInstEnv
+       eps_rule_base    :: !PackageRuleBase,  -- Ditto RuleEnv
 
        eps_stats :: !EpsStats
   }
@@ -957,13 +1065,13 @@ emptyMG = []
 
 data ModSummary
    = ModSummary {
-        ms_mod       :: Module,                        -- Name of the module
+        ms_mod       :: Module,                        -- Identity of the module
        ms_hsc_src   :: HscSource,              -- Source is Haskell, hs-boot, external core
         ms_location  :: ModLocation,           -- Location
         ms_hs_date   :: ClockTime,             -- Timestamp of source file
        ms_obj_date  :: Maybe ClockTime,        -- Timestamp of object, maybe
-        ms_srcimps   :: [Located Module],      -- Source imports
-        ms_imps      :: [Located Module],      -- Non-source imports
+        ms_srcimps   :: [Located ModuleName],  -- Source imports
+        ms_imps      :: [Located ModuleName],  -- Non-source imports
         ms_hspp_file :: FilePath,              -- Filename of preprocessed source.
         ms_hspp_opts :: DynFlags,               -- Cached flags from OPTIONS, INCLUDE
                                                 -- and LANGUAGE pragmas.
@@ -1010,8 +1118,8 @@ showModMsg target recomp mod_summary
                       _other     -> text (msObjFilePath mod_summary),
                    char ')'])
  where 
-    mod     = ms_mod mod_summary 
-    mod_str = moduleString mod ++ hscSourceString (ms_hsc_src mod_summary)
+    mod     = moduleName (ms_mod mod_summary)
+    mod_str = showSDoc (ppr mod) ++ hscSourceString (ms_hsc_src mod_summary)
 \end{code}
 
 
@@ -1077,8 +1185,10 @@ isInterpretable = not . isObject
 nameOfObject (DotO fn)   = fn
 nameOfObject (DotA fn)   = fn
 nameOfObject (DotDLL fn) = fn
+nameOfObject other       = pprPanic "nameOfObject" (ppr other)
 
 byteCodeOfObject (BCOs bc) = bc
+byteCodeOfObject other     = pprPanic "byteCodeOfObject" (ppr other)
 \end{code}