+
+%************************************************************************
+%* *
+\subsection{Data types}
+%* *
+%************************************************************************
+
+===================================================
+ MONAD TYPES
+===================================================
+
+\begin{code}
+type RnM s d r = RnDown s -> d -> SST s r
+type RnMS s r = RnM s (SDown s) r -- Renaming source
+type RnMG r = RnM REAL_WORLD GDown r -- Getting global names etc
+type MutVar a = MutableVar REAL_WORLD a -- ToDo: there ought to be a standard defn of this
+
+ -- Common part
+data RnDown s = RnDown
+ SrcLoc
+ (MutableVar s RnNameSupply)
+ (MutableVar s (Bag Warning, Bag Error))
+ (MutableVar s [(Name,Necessity)]) -- Occurrences
+
+data Necessity = Compulsory | Optional -- We *must* find definitions for
+ -- compulsory occurrences; we *may* find them
+ -- for optional ones.
+
+ -- For getting global names
+data GDown = GDown
+ SearchPath
+ (MutVar Ifaces)
+
+ -- For renaming source code
+data SDown s = SDown
+ RnEnv -- Global envt
+ NameEnv -- Local name envt (includes global name envt,
+ -- but may shadow it)
+ Module
+ RnSMode
+
+
+data RnSMode = SourceMode
+ | InterfaceMode
+
+type SearchPath = [String] -- List of directories to seach for interface files
+type FreeVars = NameSet
+\end{code}
+
+===================================================
+ ENVIRONMENTS
+===================================================
+
+\begin{code}
+type RnNameSupply = (UniqSupply, Int, FiniteMap (Module,OccName) Name)
+ -- Ensures that one (m,n) pair gets one unique
+ -- The Int is used to give a number to each instance declaration;
+ -- it's really a separate name supply.
+
+data RnEnv = RnEnv NameEnv FixityEnv
+emptyRnEnv = RnEnv emptyNameEnv emptyFixityEnv
+
+type NameEnv = FiniteMap RdrName Name
+emptyNameEnv = emptyFM
+
+type FixityEnv = FiniteMap RdrName (Fixity, Provenance)
+emptyFixityEnv = emptyFM
+ -- It's possible to have a different fixity for B.op than for op:
+ --
+ -- module A( op ) where module B where
+ -- import qualified B( op ) infixr 2 op
+ -- infixl 9 `op` op = ...
+ -- op a b = a `B.op` b
+
+data ExportEnv = ExportEnv Avails Fixities
+type Avails = [AvailInfo]
+type Fixities = [(OccName, (Fixity, Provenance))]
+ -- Can contain duplicates, if one module defines the same fixity,
+ -- or the same type/class/id, more than once. Hence a boring old list.
+ -- This allows us to report duplicates in just one place, namely plusRnEnv.
+
+type ModuleAvails = FiniteMap Module Avails
+
+data AvailInfo = NotAvailable
+ | Avail Name -- An ordinary identifier
+ | AvailTC Name -- The name of the type or class
+ [Name] -- The available pieces of type/class. NB: If the type or
+ -- class is itself to be in scope, it must be in this list.
+ -- Thus, typically: Avail Eq [Eq, ==, /=]
+\end{code}
+
+===================================================
+ INTERFACE FILE STUFF
+===================================================
+
+\begin{code}
+type ExportItem = (Module, [(OccName, [OccName])])
+type VersionInfo name = [ImportVersion name]
+type ImportVersion name = (Module, Version, [LocalVersion name])
+type LocalVersion name = (name, Version)
+
+data ParsedIface
+ = ParsedIface
+ Module -- Module name
+ Version -- Module version number
+ [ImportVersion OccName] -- Usages
+ [ExportItem] -- Exports
+ [Module] -- Special instance modules
+ [(OccName,Fixity)] -- Fixities
+ [(Version, RdrNameHsDecl)] -- Local definitions
+ [RdrNameInstDecl] -- Local instance declarations
+
+type InterfaceDetails = (VersionInfo Name, -- Version information
+ ExportEnv, -- What this module exports
+ [Module]) -- Instance modules
+
+type RdrNamePragma = () -- Fudge for now
+-------------------
+
+data Ifaces = Ifaces
+ Module -- Name of this module
+ (FiniteMap Module Version)
+ (FiniteMap Module (Avails, [(OccName,Fixity)])) -- Exports
+ DeclsMap
+
+ 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.
+
+ [(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. Subset of
+ -- the previous field. This is used to generate the "usage" information
+ -- for this module.
+
+ (Bag IfaceInst) -- Un-slurped instance decls; this bag is depleted when we
+ -- slurp an instance decl so that we don't slurp the same one twice.
+
+ [Module] -- Set of modules with "special" instance declarations
+ -- Excludes this module
+
+type DeclsMap = FiniteMap Name (Version, AvailInfo, RdrNameHsDecl)
+type IfaceInst = ((Module, RdrNameInstDecl), -- Instance decl
+ [Name]) -- "Gate" names. Slurp this instance decl when this
+ -- list becomes empty. It's depleted whenever we
+ -- slurp another type or class decl.
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Main monad code}
+%* *
+%************************************************************************
+
+\begin{code}
+initRn :: Module -> UniqSupply -> SearchPath -> SrcLoc
+ -> RnMG r
+ -> IO (r, Bag Error, Bag Warning)
+
+initRn mod us dirs loc do_rn
+ = sstToIO $
+ newMutVarSST (us, 1, builtins) `thenSST` \ names_var ->
+ newMutVarSST (emptyBag,emptyBag) `thenSST` \ errs_var ->
+ newMutVarSST (emptyIfaces mod) `thenSST` \ iface_var ->
+ newMutVarSST initOccs `thenSST` \ occs_var ->
+ let
+ rn_down = RnDown loc names_var errs_var occs_var
+ g_down = GDown dirs iface_var
+ in