[project @ 2001-03-08 12:07:38 by simonpj]
[ghc-hetmet.git] / ghc / compiler / main / HscTypes.lhs
index c630078..c358e8e 100644 (file)
@@ -8,25 +8,29 @@ module HscTypes (
        ModuleLocation(..),
 
        ModDetails(..), ModIface(..), 
-       HomeSymbolTable, PackageTypeEnv,
+       HomeSymbolTable, emptySymbolTable,
+       PackageTypeEnv,
        HomeIfaceTable, PackageIfaceTable, emptyIfaceTable,
        lookupIface, lookupIfaceByModName,
        emptyModIface,
 
+       InteractiveContext(..),
+
        IfaceDecls, mkIfaceDecls, dcl_tycl, dcl_rules, dcl_insts,
 
-       VersionInfo(..), initialVersionInfo,
+       VersionInfo(..), initialVersionInfo, lookupVersion,
 
-       TyThing(..), isTyClThing,
+       TyThing(..), isTyClThing, implicitTyThingIds,
 
-       TypeEnv, lookupType, mkTypeEnv, extendTypeEnvList, 
-       typeEnvClasses, typeEnvTyCons,
+       TypeEnv, lookupType, mkTypeEnv, emptyTypeEnv,
+       extendTypeEnvList, extendTypeEnvWithIds,
+       typeEnvClasses, typeEnvTyCons, typeEnvIds,
 
-       WhetherHasOrphans, ImportVersion, WhatsImported(..),
-       PersistentRenamerState(..), IsBootInterface, Avails, DeclsMap,
+       ImportedModuleInfo, WhetherHasOrphans, ImportVersion, WhatsImported(..),
+       PersistentRenamerState(..), IsBootInterface, DeclsMap,
        IfaceInsts, IfaceRules, GatedDecl, IsExported,
-       OrigNameEnv(..), OrigNameNameEnv, OrigNameIParamEnv,
-       AvailEnv, AvailInfo, GenAvailInfo(..),
+       NameSupply(..), OrigNameCache, OrigIParamCache,
+       Avails, AvailEnv, GenAvailInfo(..), AvailInfo, RdrAvailInfo, 
        PersistentCompilerState(..),
 
        Deprecations(..), lookupDeprec,
@@ -34,7 +38,9 @@ module HscTypes (
        InstEnv, ClsInstEnv, DFunId,
        PackageInstEnv, PackageRuleBase,
 
-       GlobalRdrEnv, RdrAvailInfo, pprGlobalRdrEnv,
+       GlobalRdrEnv, GlobalRdrElt(..), pprGlobalRdrEnv,
+       LocalRdrEnv, extendLocalRdrEnv,
+       
 
        -- Provenance
        Provenance(..), ImportReason(..), 
@@ -44,9 +50,9 @@ module HscTypes (
 
 #include "HsVersions.h"
 
-import RdrName         ( RdrNameEnv, emptyRdrEnv, rdrEnvToList )
-import Name            ( Name, NamedThing, getName, nameModule, nameSrcLoc )
-import Name -- Env
+import RdrName         ( RdrNameEnv, addListToRdrEnv, emptyRdrEnv, mkRdrUnqual, rdrEnvToList )
+import Name            ( Name, NamedThing, getName, nameOccName, nameModule, nameSrcLoc )
+import NameEnv
 import OccName         ( OccName )
 import Module          ( Module, ModuleName, ModuleEnv,
                          lookupModuleEnv, lookupModuleEnvByName, emptyModuleEnv
@@ -54,8 +60,9 @@ import Module         ( Module, ModuleName, ModuleEnv,
 import InstEnv         ( InstEnv, ClsInstEnv, DFunId )
 import Rules           ( RuleBase )
 import Id              ( Id )
-import Class           ( Class )
-import TyCon           ( TyCon )
+import Class           ( Class, classSelIds )
+import TyCon           ( TyCon, tyConGenIds, tyConSelIds, tyConDataConsIfAvailable )
+import DataCon         ( dataConId, dataConWrapId )
 
 import BasicTypes      ( Version, initialVersion, Fixity )
 
@@ -67,7 +74,7 @@ import CoreSyn                ( IdCoreRule )
 
 import FiniteMap       ( FiniteMap )
 import Bag             ( Bag )
-import Maybes          ( seqMaybe )
+import Maybes          ( seqMaybe, orElse )
 import Outputable
 import SrcLoc          ( SrcLoc, isGoodSrcLoc )
 import Util            ( thenCmp, sortLt )
@@ -149,24 +156,8 @@ mkIfaceDecls tycls rules insts
                 dcl_rules = sortLt lt_rule rules,
                 dcl_insts = insts }
   where
-    d1 `lt_tycl` d2 = nameOccName (tyClDeclName      d1) < nameOccName (tyClDeclName      d2)
-    r1 `lt_rule` r2 = nameOccName (ifaceRuleDeclName r1) < nameOccName (ifaceRuleDeclName r2)
-
-       -- I wanted to sort just by the Name, but there's a problem: we are comparing
-       -- the old version of an interface with the new version.  The latter will use
-       -- local names like 'lvl23' that were constructed not by the renamer but by
-       -- the simplifier.  So the unqiues aren't going to line up.
-       --
-       -- It's ok to compare by OccName because this comparison only drives the
-       -- computation of new version numbers.
-       --
-       -- Better solutions:    Compare in a way that is insensitive to the name used
-       --                      for local things.  This would decrease the wobbles due
-       --                      to 'lvl23' changing to 'lvl24'.
-       --
-       -- NB: there's a related comparision on MkIface.diffDecls!  
-
-
+    d1 `lt_tycl` d2 = tyClDeclName      d1 < tyClDeclName      d2
+    r1 `lt_rule` r2 = ifaceRuleDeclName r1 < ifaceRuleDeclName r2
 
 
 -- typechecker should only look at this, not ModIface
@@ -178,6 +169,25 @@ data ModDetails
         md_insts    :: [DFunId],       -- Dfun-ids for the instances in this module
         md_rules    :: [IdCoreRule]    -- Domain may include Ids from other modules
      }
+
+--     NOT YET IMPLEMENTED
+-- The ModDetails takes on several slightly different forms:
+--
+-- After typecheck + desugar
+--     md_types        contains TyCons, Classes, and hasNoBinding Ids
+--     md_insts        all instances from this module (incl derived ones)
+--     md_rules        all rules from this module
+--     md_binds        desugared bindings
+--
+-- After simplification
+--     md_types        same as after typecheck
+--     md_insts        ditto
+--     md_rules        orphan rules only (local ones attached to binds)
+--     md_binds        with rules attached
+--
+-- After tidy 
+--     md_types        now contains Ids as well, replete with correct IdInfo
+--                     apart from
 \end{code}
 
 \begin{code}
@@ -214,6 +224,9 @@ type PackageIfaceTable  = IfaceTable
 
 type HomeSymbolTable    = SymbolTable  -- Domain = modules in the home package
 
+emptySymbolTable :: SymbolTable
+emptySymbolTable = emptyModuleEnv
+
 emptyIfaceTable :: IfaceTable
 emptyIfaceTable = emptyModuleEnv
 \end{code}
@@ -237,6 +250,26 @@ lookupIfaceByModName hit pit mod
 
 %************************************************************************
 %*                                                                     *
+\subsection{The interactive context}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+data InteractiveContext 
+  = InteractiveContext { 
+       ic_module :: Module,            -- The current module in which 
+                                       -- the  user is sitting
+
+       ic_rn_env :: LocalRdrEnv,       -- Lexical context for variables bound
+                                       -- during interaction
+
+       ic_type_env :: TypeEnv          -- Ditto for types
+    }
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
 \subsection{Type environment stuff}
 %*                                                                     *
 %************************************************************************
@@ -256,9 +289,27 @@ instance NamedThing TyThing where
   getName (ATyCon tc) = getName tc
   getName (AClass cl) = getName cl
 
+instance Outputable TyThing where
+  ppr (AnId   id) = ptext SLIT("AnId")   <+> ppr id
+  ppr (ATyCon tc) = ptext SLIT("ATyCon") <+> ppr tc
+  ppr (AClass cl) = ptext SLIT("AClass") <+> ppr cl
+
 typeEnvClasses env = [cl | AClass cl <- nameEnvElts env]
 typeEnvTyCons  env = [tc | ATyCon tc <- nameEnvElts env] 
+typeEnvIds     env = [id | AnId id   <- nameEnvElts env] 
 
+implicitTyThingIds :: [TyThing] -> [Id]
+-- Add the implicit data cons and selectors etc 
+implicitTyThingIds things
+  = concat (map go things)
+  where
+    go (AnId f)    = []
+    go (AClass cl) = classSelIds cl
+    go (ATyCon tc) = tyConGenIds tc ++
+                    tyConSelIds tc ++
+                    [ n | dc <- tyConDataConsIfAvailable tc, 
+                          n  <- [dataConId dc, dataConWrapId dc] ] 
+               -- Synonyms return empty list of constructors and selectors
 \end{code}
 
 
@@ -272,10 +323,11 @@ mkTypeEnv things = extendTypeEnvList emptyTypeEnv things
                
 extendTypeEnvList :: TypeEnv -> [TyThing] -> TypeEnv
 extendTypeEnvList env things
-  = foldl add_thing env things
-  where
-    add_thing :: TypeEnv -> TyThing -> TypeEnv
-    add_thing env thing = extendNameEnv env (getName thing) thing
+  = extendNameEnvList env [(getName thing, thing) | thing <- things]
+
+extendTypeEnvWithIds :: TypeEnv -> [Id] -> TypeEnv
+extendTypeEnvWithIds env ids
+  = extendNameEnvList env [(getName id, AnId id) | id <- ids]
 \end{code}
 
 \begin{code}
@@ -306,13 +358,19 @@ data VersionInfo
                -- The version of an Id changes if its fixity changes
                -- Ditto data constructors, class operations, except that the version of
                -- the parent class/tycon changes
+               --
+               -- If a name isn't in the map, it means 'initialVersion'
     }
 
 initialVersionInfo :: VersionInfo
 initialVersionInfo = VersionInfo { vers_module  = initialVersion,
                                   vers_exports = initialVersion,
                                   vers_rules   = initialVersion,
-                                  vers_decls   = emptyNameEnv }
+                                  vers_decls   = emptyNameEnv
+                       }
+
+lookupVersion :: NameEnv Version -> Name -> Version
+lookupVersion env name = lookupNameEnv env name `orElse` initialVersion
 
 data Deprecations = NoDeprecs
                  | DeprecAll DeprecTxt                         -- Whole module deprecated
@@ -326,6 +384,13 @@ lookupDeprec (DeprecAll  txt) name = Just txt
 lookupDeprec (DeprecSome env) name = case lookupNameEnv env name of
                                            Just (_, txt) -> Just txt
                                            Nothing       -> Nothing
+
+instance Eq Deprecations where
+  -- Used when checking whether we need write a new interface
+  NoDeprecs       == NoDeprecs      = True
+  (DeprecAll t1)  == (DeprecAll t2)  = t1 == t2
+  (DeprecSome e1) == (DeprecSome e2) = nameEnvElts e1 == nameEnvElts e2
+  d1             == d2              = False
 \end{code}
 
 
@@ -425,7 +490,6 @@ data PersistentCompilerState
 
         pcs_PRS :: PersistentRenamerState
      }
-
 \end{code}
 
 The @PersistentRenamerState@ persists across successive calls to the
@@ -455,15 +519,15 @@ type PackageRuleBase = RuleBase
 type PackageInstEnv  = InstEnv
 
 data PersistentRenamerState
-  = PRS { prsOrig  :: OrigNameEnv,
-         prsDecls :: DeclsMap,
-         prsInsts :: IfaceInsts,
-         prsRules :: IfaceRules,
-         prsNS    :: UniqSupply
+  = PRS { prsOrig    :: NameSupply,
+         prsImpMods :: ImportedModuleInfo,
+         prsDecls   :: DeclsMap,
+         prsInsts   :: IfaceInsts,
+         prsRules   :: IfaceRules
     }
 \end{code}
 
-The OrigNameEnv makes sure that there is just one Unique assigned for
+The NameSupply makes sure that there is just one Unique assigned for
 each original name; i.e. (module-name, occ-name) pair.  The Name is
 always stored as a Global, and has the SrcLoc of its binding location.
 Actually that's not quite right.  When we first encounter the original
@@ -476,17 +540,29 @@ encounter the occurrence, we may not know the details of the module, so
 we just store junk.  Then when we find the binding site, we fix it up.
 
 \begin{code}
-data OrigNameEnv
- = Orig { origNames  :: OrigNameNameEnv,
+data NameSupply
+ = NameSupply { nsUniqs :: UniqSupply,
+               -- Supply of uniques
+               nsNames :: OrigNameCache,
                -- Ensures that one original name gets one unique
-         origIParam :: OrigNameIParamEnv
+               nsIPs   :: OrigIParamCache
                -- Ensures that one implicit parameter name gets one unique
    }
 
-type OrigNameNameEnv   = FiniteMap (ModuleName,OccName) Name
-type OrigNameIParamEnv = FiniteMap OccName Name
+type OrigNameCache   = FiniteMap (ModuleName,OccName) Name
+type OrigIParamCache = FiniteMap OccName Name
 \end{code}
 
+@ImportedModuleInfo@ contains info ONLY about modules that have not yet 
+been loaded into the iPIT.  These modules are mentioned in interfaces we've
+already read, so we know a tiny bit about them, but we havn't yet looked
+at the interface file for the module itself.  It needs to persist across 
+invocations of the renamer, at least from Rename.checkOldIface to Rename.renameSource.
+And there's no harm in it persisting across multiple compilations.
+
+\begin{code}
+type ImportedModuleInfo = FiniteMap ModuleName (WhetherHasOrphans, IsBootInterface)
+\end{code}
 
 A DeclsMap contains a binding for each Name in the declaration
 including the constructors of a type decl etc.  The Bool is True just
@@ -510,19 +586,32 @@ type GatedDecl  d = ([Name], (Module, d))
 %*                                                                     *
 %************************************************************************
 
+A LocalRdrEnv is used for local bindings (let, where, lambda, case)
+
+\begin{code}
+type LocalRdrEnv = RdrNameEnv Name
+
+extendLocalRdrEnv :: LocalRdrEnv -> [Name] -> LocalRdrEnv
+extendLocalRdrEnv env names
+  = addListToRdrEnv env [(mkRdrUnqual (nameOccName n), n) | n <- names]
+\end{code}
+
 The GlobalRdrEnv gives maps RdrNames to Names.  There is a separate
 one for each module, corresponding to that module's top-level scope.
 
 \begin{code}
-type GlobalRdrEnv = RdrNameEnv [(Name,Provenance)]     -- The list is because there may be name clashes
-                                                       -- These only get reported on lookup,
-                                                       -- not on construction
+type GlobalRdrEnv = RdrNameEnv [GlobalRdrElt]
+       -- The list is because there may be name clashes
+       -- These only get reported on lookup, not on construction
+
+data GlobalRdrElt = GRE Name Provenance (Maybe DeprecTxt)
+       -- The Maybe DeprecTxt tells whether this name is deprecated
 
 pprGlobalRdrEnv env
   = vcat (map pp (rdrEnvToList env))
   where
     pp (rn, nps) = ppr rn <> colon <+> 
-                  vcat [ppr n <+> pprNameProvenance n p | (n,p) <- nps]
+                  vcat [ppr n <+> pprNameProvenance n p | (GRE n p _) <- nps]
 \end{code}
 
 The "provenance" of something says how it came to be in scope.