-type RnM s r = RnMonad () s r
-type RnM_Fixes s r = RnMonad (UniqFM RenamedFixityDecl) s r
-
-type RnMonad x s r = RnDown x s -> SST s r
-
-data RnDown x s
- = RnDown
- x
- Module -- Module name
- SrcLoc -- Source location
- (RnMode s) -- Source or Iface
- RnEnv -- Renaming environment
- (MutableVar s UniqSupply) -- Unique supply
- (MutableVar s (Bag Warning, -- Warnings and Errors
- Bag Error))
-
-data RnMode s
- = RnSource (MutableVar s (Bag (RnName, RdrName)))
- -- Renaming source; returning occurences
-
- | RnIface BuiltinNames BuiltinKeys
- (MutableVar s ImplicitEnv)
- -- Renaming interface; creating and returning implicit names
- -- ImplicitEnv: one map for Values and one for TyCons/Classes.
-
-type ImplicitEnv = (FiniteMap RdrName RnName, FiniteMap RdrName RnName)
-emptyImplicitEnv :: ImplicitEnv
-emptyImplicitEnv = (emptyFM, emptyFM)
-
--- With a builtin polymorphic type for _runSST the type for
--- initTc should use RnM s r instead of RnM _RealWorld r
-
-initRn :: Bool -- True => Source; False => Iface
- -> Module
- -> RnEnv
- -> UniqSupply
- -> RnM _RealWorld r
- -> (r, Bag Error, Bag Warning)
-
-initRn source mod env us do_rn
- = _runSST (
- newMutVarSST emptyBag `thenSST` \ occ_var ->
- newMutVarSST emptyImplicitEnv `thenSST` \ imp_var ->
- newMutVarSST us `thenSST` \ us_var ->
- newMutVarSST (emptyBag,emptyBag) `thenSST` \ errs_var ->
- let
- mode = if source then
- RnSource occ_var
- else
- case builtinNameInfo of { (wiredin_fm, key_fm, _) ->
- RnIface wiredin_fm key_fm imp_var }
-
- rn_down = RnDown () mod mkUnknownSrcLoc mode env us_var errs_var
- in
- -- do the buisness
- do_rn rn_down `thenSST` \ res ->
+type ExportAvails = (FiniteMap ModuleName Avails,
+ -- Used to figure out "module M" export specifiers
+ -- Includes avails only from *unqualified* imports
+ -- (see 1.4 Report Section 5.1.1)
+
+ AvailEnv) -- Used to figure out all other export specifiers.
+\end{code}
+
+%===================================================
+\subsubsection{ INTERFACE FILE STUFF}
+%===================================================
+
+\begin{code}
+type ExportItem = (ModuleName, [RdrAvailInfo])
+
+type ImportVersion name = (ModuleName, WhetherHasOrphans, IsBootInterface, WhatsImported name)
+
+type ModVersionInfo = (Version, -- Version of the whole module
+ Version, -- Version number for all fixity decls together
+ Version) -- ...ditto all rules together
+
+type WhetherHasOrphans = Bool
+ -- An "orphan" is
+ -- * an instance decl in a module other than the defn module for
+ -- one of the tycons or classes in the instance head
+ -- * 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 = NothingAtAll -- The module is below us in the
+ -- hierarchy, but we import nothing
+
+ | Everything Version -- The module version
+
+ | Specifically Version -- Module version
+ Version -- Fixity version
+ Version -- Rules version
+ [(name,Version)] -- List guaranteed non-empty
+ deriving( Eq )
+ -- 'Specifically' doesn't let you say "I imported f but none of the fixities in
+ -- the module". If you use anything in the module you get its fixity and rule version
+ -- So if the fixities or rules change, you'll recompile, even if you don't use either.
+ -- 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
+
+ -- 'Everything' means there was a "module M" in
+ -- this module's export list, so we just have to go by M's version,
+ -- not the list of (name,version) pairs
+
+data ParsedIface
+ = ParsedIface {
+ pi_mod :: Module, -- Complete with package info
+ pi_vers :: Version, -- Module version number
+ pi_orphan :: WhetherHasOrphans, -- Whether this module has orphans
+ pi_usages :: [ImportVersion OccName], -- Usages
+ pi_exports :: [ExportItem], -- Exports
+ pi_insts :: [RdrNameInstDecl], -- Local instance declarations
+ pi_decls :: [(Version, RdrNameHsDecl)], -- Local definitions
+ pi_fixity :: (Version, [RdrNameFixitySig]), -- Local fixity declarations, with their version
+ pi_rules :: (Version, [RdrNameRuleDecl]), -- Rules, with their version
+ pi_deprecs :: [RdrNameDeprecation] -- Deprecations
+ }
+
+
+type RdrNamePragma = () -- Fudge for now
+-------------------
+
+\end{code}
+
+%************************************************************************
+%* *
+\subsection{The renamer state}
+%* *
+%************************************************************************
+
+\begin{code}
+data Ifaces = Ifaces {
+
+ -- PERSISTENT FIELDS
+ iImpModInfo :: ImportedModuleInfo,
+ -- Modules this one depends on: that is, the union
+ -- 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
+ -- we can get away with importing them abstractly
+
+ iInsts :: IfaceInsts,
+ -- The as-yet un-slurped instance decls; this bag is depleted when we
+ -- slurp an instance decl so that we don't slurp the same one twice.
+ -- Each is 'gated' by the names that must be available before
+ -- this instance decl is needed.
+
+ iRules :: IfaceRules,
+ -- Similar to instance decls, only for rules
+
+ -- SEMI-EPHEMERAL FIELDS
+ -- iFixes and iDeprecs are accumulated here while one module
+ -- is compiled, but are transferred to the package symbol table
+ -- at the end. We don't add them to the table as we encounter them
+ -- because doing so would require us to have a mutable symbol table
+ -- which is yukky.
+
+ iFixes :: FixityEnv, -- A single, global map of Names to fixities
+ -- See comments with RnIfaces.lookupFixity
+ iDeprecs :: DeprecationEnv,
+
+ -- EPHEMERAL FIELDS
+ -- These fields persist during the compilation of a single module only
+
+ iSlurp :: NameSet,
+ -- All the names (whether "big" or "small", whether wired-in or not,
+ -- whether locally defined or not) that have been slurped in so far.
+
+ iVSlurp :: [(Name,Version)]
+ -- All the (a) non-wired-in (b) "big" (c) non-locally-defined
+ -- names that have been slurped in so far, with their versions.
+ -- This is used to generate the "usage" information for this module.
+ -- Subset of the previous field.
+ }
+
+type ImportedModuleInfo
+ = FiniteMap ModuleName (WhetherHasOrphans, IsBootInterface,
+ Maybe (Module, Version, Version, Version, WhereFrom, Avails))
+ -- The three Versions are module version, fixity version, rules version
+
+ -- Suppose the domain element is module 'A'
+ --
+ -- The first Bool is True if A contains
+ -- 'orphan' rules or instance decls
+
+ -- The second Bool is true if the interface file actually
+ -- read was an .hi-boot file
+
+ -- Nothing => A's interface not yet read, but this module has
+ -- imported a module, B, that itself depends on A
+ --
+ -- Just xx => A's interface has been read. The Module in
+ -- the Just has the correct Dll flag
+
+ -- This set is used to decide whether to look for
+ -- A.hi or A.hi-boot when importing A.f.
+ -- Basically, we look for A.hi if A is in the map, and A.hi-boot
+ -- otherwise
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Main monad code}
+%* *
+%************************************************************************
+
+\begin{code}
+initRn :: DynFlags -> Finder -> GlobalSymbolTable
+ -> PersistentRenamerState
+ -> Module -> SrcLoc
+
+initRn dflags finder gst prs mod loc do_rn = do
+ himaps <- mkModuleHiMaps dirs
+ names_var <- newIORef (prsNS pcs)
+ errs_var <- newIORef (emptyBag,emptyBag)
+ iface_var <- newIORef (initIfaces prs)
+ let
+ rn_down = RnDown { rn_mod = mod,
+ rn_loc = loc,
+
+ rn_finder = finder,
+ rn_dflags = dflags,
+ rn_gst = gst,
+
+ rn_ns = names_var,
+ rn_errs = errs_var,
+ rn_ifaces = iface_var,
+ }
+
+ -- do the business
+ res <- do_rn rn_down ()