[project @ 2000-04-05 16:25:51 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / RnMonad.lhs
index fae50f3..95a248e 100644 (file)
@@ -20,12 +20,18 @@ module RnMonad(
 
 #include "HsVersions.h"
 
+#if   defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 405
+import IOExts          ( fixIO )
+#elif defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 302
 import PrelIOBase      ( fixIO )       -- Should be in GlaExts
+#else
+import IOBase          ( fixIO )
+#endif
 import IOExts          ( IORef, newIORef, readIORef, writeIORef, unsafePerformIO )
        
 import HsSyn           
 import RdrHsSyn
-import RnHsSyn         ( RenamedFixitySig )
+import RnHsSyn         ( RenamedFixitySig, RenamedDeprecation )
 import BasicTypes      ( Version )
 import SrcLoc          ( noSrcLoc )
 import ErrUtils                ( addShortErrLocLine, addShortWarnLocLine,
@@ -33,14 +39,14 @@ import ErrUtils             ( addShortErrLocLine, addShortWarnLocLine,
                        )
 import Name            ( Name, OccName, NamedThing(..),
                          isLocallyDefinedName, nameModule, nameOccName,
-                         decode, mkLocalName
+                         decode, mkLocalName, mkUnboundName
                        )
 import Module          ( Module, ModuleName, ModuleHiMap, SearchPath, WhereFrom,
-                         mkModuleHiMaps, moduleName
+                         mkModuleHiMaps, moduleName, mkVanillaModule, mkSearchPath
                        )
 import NameSet         
 import RdrName         ( RdrName, dummyRdrVarName, rdrNameOcc )
-import CmdLineOpts     ( opt_D_dump_rn_trace, opt_IgnoreIfacePragmas )
+import CmdLineOpts     ( opt_D_dump_rn_trace, opt_HiMap )
 import PrelInfo                ( builtinNames )
 import TysWiredIn      ( boolTyCon )
 import SrcLoc          ( SrcLoc, mkGeneratedSrcLoc )
@@ -126,8 +132,9 @@ data SDown = SDown {
                        --   we can look up record field names
 
                  rn_fixenv :: FixityEnv        -- Local fixities
-                                               -- The global ones are held in the
-                                               -- rn_ifaces field
+                       -- The global fixities are held in the
+                       -- rn_ifaces field.  Why?  See the comments
+                       -- with RnIfaces.lookupFixity
                }
 
 data RnMode    = SourceMode                    -- Renaming source code
@@ -166,26 +173,33 @@ nameEnvElts    :: NameEnv a -> [a]
 addToNameEnv_C :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a
 addToNameEnv   :: NameEnv a -> Name -> a -> NameEnv a
 plusNameEnv    :: NameEnv a -> NameEnv a -> NameEnv a
+plusNameEnv_C  :: (a->a->a) -> NameEnv a -> NameEnv a -> NameEnv a
 extendNameEnv  :: NameEnv a -> [(Name,a)] -> NameEnv a
 lookupNameEnv  :: NameEnv a -> Name -> Maybe a
 delFromNameEnv :: NameEnv a -> Name -> NameEnv a
 elemNameEnv    :: Name -> NameEnv a -> Bool
+unitNameEnv    :: Name -> a -> NameEnv a
 
 emptyNameEnv   = emptyUFM
 nameEnvElts    = eltsUFM
 addToNameEnv_C = addToUFM_C
 addToNameEnv   = addToUFM
 plusNameEnv    = plusUFM
+plusNameEnv_C  = plusUFM_C
 extendNameEnv  = addListToUFM
 lookupNameEnv  = lookupUFM
 delFromNameEnv = delFromUFM
 elemNameEnv    = elemUFM
+unitNameEnv    = unitUFM
 
 --------------------------------
 type FixityEnv = NameEnv RenamedFixitySig
        -- We keep the whole fixity sig so that we
        -- can report line-number info when there is a duplicate
        -- fixity declaration
+
+--------------------------------
+type DeprecationEnv = NameEnv DeprecTxt
 \end{code}
 
 \begin{code}
@@ -193,12 +207,14 @@ type FixityEnv = NameEnv RenamedFixitySig
 type RnNameSupply
  = ( UniqSupply
 
-   , FiniteMap (OccName, OccName) Int
+   , FiniteMap String Int
        -- This is used as a name supply for dictionary functions
-       -- From the inst decl we derive a (class, tycon) pair;
+       -- From the inst decl we derive a string, usually by glomming together
+       -- the class and tycon name -- but it doesn't matter exactly how;
        -- this map then gives a unique int for each inst decl with that
-       -- (class, tycon) pair.  (In Haskell 98 there can only be one,
-       -- but not so in more extended versions.)
+       -- string.  (In Haskell 98 there can only be one,
+       -- but not so in more extended versions; also class CC type T
+       -- and class C type TT might both give the string CCT
        --      
        -- We could just use one Int for all the instance decls, but this
        -- way the uniques change less when you add an instance decl,   
@@ -206,11 +222,16 @@ type RnNameSupply
 
    , FiniteMap (ModuleName, OccName) Name
        -- Ensures that one (module,occname) pair gets one unique
+   , FiniteMap OccName Name
+       -- Ensures that one implicit parameter name gets one unique
    )
 
 
 --------------------------------
-data ExportEnv   = ExportEnv Avails Fixities
+data ExportEnv   = ExportEnv Avails Fixities [ModuleName]
+                       -- The list of modules is the modules exported
+                       -- with 'module M' in the export list
+
 type Avails      = [AvailInfo]
 type Fixities    = [(Name, Fixity)]
 
@@ -219,9 +240,8 @@ type ExportAvails = (FiniteMap ModuleName Avails,
        -- Includes avails only from *unqualified* imports
        -- (see 1.4 Report Section 5.1.1)
 
-       NameEnv AvailInfo)      -- Used to figure out all other export specifiers.
-                               -- Maps a Name to the AvailInfo that contains it
-
+                    AvailEnv)  -- Used to figure out all other export specifiers.
+                       
 
 data GenAvailInfo name = Avail name     -- An ordinary identifier
                        | AvailTC name   -- The name of the type or class
@@ -230,6 +250,7 @@ data GenAvailInfo name      = Avail name     -- An ordinary identifier
                                         -- to be in scope, it must be in this list.
                                         -- Thus, typically: AvailTC Eq [Eq, ==, /=]
 
+type AvailEnv    = NameEnv AvailInfo   -- Maps a Name to the AvailInfo that contains it
 type AvailInfo    = GenAvailInfo Name
 type RdrAvailInfo = GenAvailInfo OccName
 \end{code}
@@ -242,7 +263,8 @@ type RdrAvailInfo = GenAvailInfo OccName
 type ExportItem                 = (ModuleName, [RdrAvailInfo])
 type VersionInfo name    = [ImportVersion name]
 
-type ImportVersion name  = (ModuleName, Version, WhetherHasOrphans, WhatsImported name)
+type ImportVersion name  = (ModuleName, Version, 
+                            WhetherHasOrphans, IsBootInterface, WhatsImported name)
 
 type WhetherHasOrphans   = Bool
        -- An "orphan" is 
@@ -251,6 +273,8 @@ 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
+
 data WhatsImported name  = Everything 
                         | Specifically [LocalVersion name] -- List guaranteed non-empty
 
@@ -269,17 +293,20 @@ data ParsedIface
       pi_exports   :: [ExportItem],                    -- Exports
       pi_decls    :: [(Version, RdrNameHsDecl)],       -- Local definitions
       pi_insts    :: [RdrNameInstDecl],                -- Local instance declarations
-      pi_rules    :: [RdrNameRuleDecl]                 -- Rules
+      pi_rules    :: [RdrNameRuleDecl],                -- Rules
+      pi_deprecs   :: [RdrNameDeprecation]             -- Deprecations
     }
 
-type InterfaceDetails = (WhetherHasOrphans,
-                        VersionInfo Name, -- Version information for what this module imports
-                        ExportEnv)        -- What modules this one depends on
+data InterfaceDetails
+   = InterfaceDetails WhetherHasOrphans
+                     (VersionInfo Name)   -- Version information for what this module imports
+                     ExportEnv            -- What modules this one depends on
+                     [Deprecation Name]
 
 
 -- needed by Main to fish out the fixities assoc list.
 getIfaceFixities :: InterfaceDetails -> Fixities
-getIfaceFixities (_, _, ExportEnv _ fs) = fs
+getIfaceFixities (InterfaceDetails _ _ (ExportEnv _ fs _) _) = fs
 
 
 type RdrNamePragma = ()                                -- Fudge for now
@@ -288,11 +315,14 @@ type RdrNamePragma = ()                           -- Fudge for now
 data Ifaces = Ifaces {
                iImpModInfo :: ImportedModuleInfo,
                                -- Modules this one depends on: that is, the union 
-                               -- of the modules its direct imports depend on.
+                               -- of the modules its *direct* imports depend on.
+                               -- NB: The direct imports have .hi files that enumerate *all* the
+                               -- dependencies (direct or not) of the imported module.
 
                iDecls :: DeclsMap,     -- A single, global map of Names to decls
 
                iFixes :: FixityEnv,    -- A single, global map of Names to fixities
+                                       -- See comments with RnIfaces.lookupFixity
 
                iSlurp :: NameSet,
                -- All the names (whether "big" or "small", whether wired-in or not,
@@ -310,14 +340,16 @@ data Ifaces = Ifaces {
                -- Each is 'gated' by the names that must be available before
                -- this instance decl is needed.
 
-               iRules :: Bag GatedDecl
+               iRules :: Bag GatedDecl,
                        -- Ditto transformation rules
+
+               iDeprecs :: DeprecationEnv
        }
 
 type GatedDecl = (NameSet, (Module, RdrNameHsDecl))
 
 type ImportedModuleInfo 
-     = FiniteMap ModuleName (Version, Bool, Maybe (Module, Bool, Avails))
+     = FiniteMap ModuleName (Version, WhetherHasOrphans, IsBootInterface, Maybe (Module, Avails))
                -- Suppose the domain element is module 'A'
                --
                -- The first Bool is True if A contains 
@@ -357,7 +389,7 @@ initRn :: ModuleName -> UniqSupply -> SearchPath -> SrcLoc
 
 initRn mod us dirs loc do_rn = do
   himaps    <- mkModuleHiMaps dirs
-  names_var <- newIORef (us, emptyFM, builtins)
+  names_var <- newIORef (us, emptyFM, builtins, emptyFM)
   errs_var  <- newIORef (emptyBag,emptyBag)
   iface_var <- newIORef emptyIfaces 
   let
@@ -399,17 +431,10 @@ emptyIfaces = Ifaces { iImpModInfo = emptyFM,
                        -- and we don't want thereby to try to suck it in!
                       iVSlurp = [],
                       iInsts = emptyBag,
-                      iRules = emptyBag
+                      iRules = emptyBag,
+                      iDeprecs = emptyNameEnv
              }
 
--- mkUnboundName makes a place-holder Name; it shouldn't be looked at except possibly
--- during compiler debugging.
-mkUnboundName :: RdrName -> Name
-mkUnboundName rdr_name = mkLocalName unboundKey (rdrNameOcc rdr_name) noSrcLoc
-
-isUnboundName :: Name -> Bool
-isUnboundName name = getUnique name == unboundKey
-
 builtins :: FiniteMap (ModuleName,OccName) Name
 builtins = 
    bagToFM (
@@ -437,12 +462,15 @@ renameSourceCode mod_name name_supply m
        -- only do any I/O if we need to read in a fixity declaration;
        -- and that doesn't happen in pragmas etc
 
+        mkModuleHiMaps (mkSearchPath opt_HiMap) >>= \ himaps ->
        newIORef name_supply            >>= \ names_var ->
        newIORef (emptyBag,emptyBag)    >>= \ errs_var ->
        let
            rn_down = RnDown { rn_loc = mkGeneratedSrcLoc, rn_ns = names_var,
-                              rn_errs = errs_var,
-                              rn_mod = mod_name }
+                              rn_errs = errs_var, rn_hi_maps = himaps,
+                              rn_mod = mod_name, 
+                              rn_ifaces = panic "rnameSourceCode: rn_ifaces"  -- Not required
+                            }
            s_down = SDown { rn_mode = InterfaceMode,
                               -- So that we can refer to PrelBase.True etc
                             rn_genv = emptyRdrEnv, rn_lenv = emptyRdrEnv,
@@ -478,6 +506,7 @@ andRn    :: (a -> a -> a) -> RnM d a -> RnM d a -> RnM d a
 mapRn    :: (a -> RnM d b) -> [a] -> RnM d [b]
 mapRn_   :: (a -> RnM d b) -> [a] -> RnM d ()
 mapMaybeRn :: (a -> RnM d (Maybe b)) -> [a] -> RnM d [b]
+flatMapRn  :: (a -> RnM d [b])       -> [a] -> RnM d [b]
 sequenceRn :: [RnM d a] -> RnM d [a]
 foldlRn :: (b  -> a -> RnM d b) -> b -> [a] -> RnM d b
 mapAndUnzipRn :: (a -> RnM d (b,c)) -> [a] -> RnM d ([b],[c])
@@ -530,6 +559,11 @@ mapMaybeRn f (x:xs) = f x          `thenRn` \ maybe_r ->
                      case maybe_r of
                        Nothing -> returnRn rs
                        Just r  -> returnRn (r:rs)
+
+flatMapRn f []     = returnRn []
+flatMapRn f (x:xs) = f x               `thenRn` \ r ->
+                    flatMapRn f xs     `thenRn` \ rs ->
+                    returnRn (r ++ rs)
 \end{code}
 
 
@@ -611,25 +645,25 @@ setNameSupplyRn names' (RnDown {rn_ns = names_var}) l_down
   = writeIORef names_var names'
 
 -- See comments with RnNameSupply above.
-newInstUniq :: (OccName, OccName) -> RnM d Int
+newInstUniq :: String -> RnM d Int
 newInstUniq key (RnDown {rn_ns = names_var}) l_down
-  = readIORef names_var                                >>= \ (us, mapInst, cache) ->
+  = readIORef names_var                                >>= \ (us, mapInst, cache, ipcache) ->
     let
        uniq = case lookupFM mapInst key of
                   Just x  -> x+1
                   Nothing -> 0
        mapInst' = addToFM mapInst key uniq
     in
-    writeIORef names_var (us, mapInst', cache) >>
+    writeIORef names_var (us, mapInst', cache, ipcache) >>
     return uniq
 
 getUniqRn :: RnM d Unique
 getUniqRn (RnDown {rn_ns = names_var}) l_down
- = readIORef names_var >>= \ (us, mapInst, cache) ->
+ = readIORef names_var >>= \ (us, mapInst, cache, ipcache) ->
    let
      (us1,us') = splitUniqSupply us
    in
-   writeIORef names_var (us', mapInst, cache)  >>
+   writeIORef names_var (us', mapInst, cache, ipcache)  >>
    return (uniqFromSupply us1)
 \end{code}
 
@@ -718,3 +752,13 @@ getHiMaps :: RnM d (ModuleHiMap, ModuleHiMap)
 getHiMaps (RnDown {rn_hi_maps = himaps}) _ 
   = return himaps
 \end{code}
+
+\begin{code}
+lookupModuleRn :: ModuleName -> RnM d Module
+lookupModuleRn x = 
+  getHiMaps `thenRn` \ (himap, _) ->
+  case lookupFM himap x of
+    Nothing    -> returnRn (mkVanillaModule x)
+    Just (_,x) -> returnRn x
+
+\end{code}