[project @ 2000-10-13 13:43:47 by sewardj]
[ghc-hetmet.git] / ghc / compiler / rename / RnMonad.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[RnMonad]{The monad used by the renamer}
5
6 \begin{code}
7 module RnMonad(
8         module RnMonad,
9
10         module RdrName,         -- Re-exports
11         module Name,            -- from these two
12
13         Module,
14         FiniteMap,
15         Bag,
16         RdrNameHsDecl,
17         RdrNameInstDecl,
18         Version,
19         NameSet,
20         OccName,
21         Fixity
22     ) where
23
24 #include "HsVersions.h"
25
26 #if   defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 405
27 import IOExts           ( fixIO )
28 #elif defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 302
29 import PrelIOBase       ( fixIO )       -- Should be in GlaExts
30 #else
31 import IOBase           ( fixIO )
32 #endif
33 import IOExts           ( IORef, newIORef, readIORef, writeIORef, unsafePerformIO )
34         
35 import HsSyn            
36 import RdrHsSyn
37 import RnHsSyn          ( RenamedFixitySig )
38 import BasicTypes       ( Version, defaultFixity )
39 import ErrUtils         ( addShortErrLocLine, addShortWarnLocLine,
40                           pprBagOfErrors, ErrMsg, WarnMsg, Message
41                         )
42 import RdrName          ( RdrName, dummyRdrVarName, rdrNameModule, rdrNameOcc,
43                           RdrNameEnv, emptyRdrEnv, extendRdrEnv, 
44                           lookupRdrEnv, addListToRdrEnv, rdrEnvToList, rdrEnvElts
45                         )
46 import Name             ( Name, OccName, NamedThing(..), getSrcLoc,
47                           isLocallyDefinedName, nameModule, nameOccName,
48                           decode, mkLocalName, mkKnownKeyGlobal,
49                           NameEnv, lookupNameEnv, emptyNameEnv, unitNameEnv, 
50                           extendNameEnvList
51                         )
52 import Module           ( Module, ModuleName, WhereFrom, moduleName )
53 import NameSet          
54 import CmdLineOpts      ( DynFlags, dopt_D_dump_rn_trace )
55 import SrcLoc           ( SrcLoc, mkGeneratedSrcLoc )
56 import Unique           ( Unique )
57 import FiniteMap        ( FiniteMap, emptyFM, listToFM, plusFM )
58 import Bag              ( Bag, mapBag, emptyBag, isEmptyBag, snocBag )
59 import UniqSupply
60 import Outputable
61 import CmFind           ( Finder )
62 import PrelNames        ( mkUnboundName )
63 import HscTypes         ( GlobalSymbolTable, OrigNameEnv, AvailEnv, 
64                           WhetherHasOrphans, ImportVersion, ExportItem,
65                           PersistentRenamerState(..), IsBootInterface, Avails,
66                           DeclsMap, IfaceInsts, IfaceRules, DeprecationEnv )
67
68 infixr 9 `thenRn`, `thenRn_`
69 \end{code}
70
71
72 %************************************************************************
73 %*                                                                      *
74 \subsection{Somewhat magical interface to other monads}
75 %*                                                                      *
76 %************************************************************************
77
78 \begin{code}
79 ioToRnM :: IO r -> RnM d (Either IOError r)
80 ioToRnM io rn_down g_down = (io >>= \ ok -> return (Right ok)) 
81                             `catch` 
82                             (\ err -> return (Left err))
83             
84 traceRn :: SDoc -> RnM d ()
85 traceRn msg
86    = doptsRn dopt_D_dump_rn_trace `thenRn` \b ->
87      if b then putDocRn msg else returnRn ()
88
89 putDocRn :: SDoc -> RnM d ()
90 putDocRn msg = ioToRnM (printErrs msg)  `thenRn_`
91                returnRn ()
92 \end{code}
93
94
95 %************************************************************************
96 %*                                                                      *
97 \subsection{Data types}
98 %*                                                                      *
99 %************************************************************************
100
101 %===================================================
102 \subsubsection{         MONAD TYPES}
103 %===================================================
104
105 \begin{code}
106 type RnM d r = RnDown -> d -> IO r
107 type RnMS r  = RnM SDown r              -- Renaming source
108 type RnMG r  = RnM ()    r              -- Getting global names etc
109
110         -- Common part
111 data RnDown
112   = RnDown {
113         rn_mod     :: Module,                   -- This module
114         rn_loc     :: SrcLoc,                   -- Current locn
115
116         rn_finder  :: Finder,
117         rn_dflags  :: DynFlags,
118         rn_gst     :: GlobalSymbolTable,        -- Both home modules and packages,
119                                                 -- at the moment we started compiling 
120                                                 -- this module
121
122         rn_errs    :: IORef (Bag WarnMsg, Bag ErrMsg),
123         rn_ns      :: IORef (UniqSupply, OrigNameEnv),
124         rn_ifaces  :: IORef Ifaces
125     }
126
127         -- For renaming source code
128 data SDown = SDown {
129                   rn_mode :: RnMode,
130
131                   rn_genv :: GlobalRdrEnv,      -- Global envt
132
133                   rn_lenv :: LocalRdrEnv,       -- Local name envt
134                         --   Does *not* include global name envt; may shadow it
135                         --   Includes both ordinary variables and type variables;
136                         --   they are kept distinct because tyvar have a different
137                         --   occurrence contructor (Name.TvOcc)
138                         -- We still need the unsullied global name env so that
139                         --   we can look up record field names
140
141                   rn_fixenv :: FixityEnv        -- Local fixities
142                         -- The global fixities are held in the
143                         -- rn_ifaces field.  Why?  See the comments
144                         -- with RnIfaces.lookupFixity
145                 }
146
147 data RnMode     = SourceMode                    -- Renaming source code
148                 | InterfaceMode                 -- Renaming interface declarations.  
149 \end{code}
150
151 %===================================================
152 \subsubsection{         ENVIRONMENTS}
153 %===================================================
154
155 \begin{code}
156 --------------------------------
157 type GlobalRdrEnv = RdrNameEnv [Name]   -- The list is because there may be name clashes
158                                         -- These only get reported on lookup,
159                                         -- not on construction
160 type LocalRdrEnv  = RdrNameEnv Name
161
162 --------------------------------
163 type FixityEnv = NameEnv RenamedFixitySig
164         -- We keep the whole fixity sig so that we
165         -- can report line-number info when there is a duplicate
166         -- fixity declaration
167
168 lookupFixity :: FixityEnv -> Name -> Fixity
169 lookupFixity env name
170   = case lookupNameEnv env name of 
171         Just (FixitySig _ fix _) -> fix
172         Nothing                  -> defaultFixity
173 \end{code}
174
175 \begin{code}
176 type ExportAvails = (FiniteMap ModuleName Avails,
177         -- Used to figure out "module M" export specifiers
178         -- Includes avails only from *unqualified* imports
179         -- (see 1.4 Report Section 5.1.1)
180
181                      AvailEnv)  -- Used to figure out all other export specifiers.
182 \end{code}
183
184 %===================================================
185 \subsubsection{         INTERFACE FILE STUFF}
186 %===================================================
187
188 \begin{code}
189
190 data ParsedIface
191   = ParsedIface {
192       pi_mod       :: Module,                           -- Complete with package info
193       pi_vers      :: Version,                          -- Module version number
194       pi_orphan    :: WhetherHasOrphans,                -- Whether this module has orphans
195       pi_usages    :: [ImportVersion OccName],          -- Usages
196       pi_exports   :: [ExportItem],                     -- Exports
197       pi_insts     :: [RdrNameInstDecl],                -- Local instance declarations
198       pi_decls     :: [(Version, RdrNameHsDecl)],       -- Local definitions
199       pi_fixity    :: (Version, [RdrNameFixitySig]),    -- Local fixity declarations, with their version
200       pi_rules     :: (Version, [RdrNameRuleDecl]),     -- Rules, with their version
201       pi_deprecs   :: [RdrNameDeprecation]              -- Deprecations
202     }
203
204
205 type RdrNamePragma = ()                         -- Fudge for now
206 -------------------
207
208 \end{code}
209
210 %************************************************************************
211 %*                                                                      *
212 \subsection{The renamer state}
213 %*                                                                      *
214 %************************************************************************
215
216 \begin{code}
217 data Ifaces = Ifaces {
218
219         -- PERSISTENT FIELDS
220                 iImpModInfo :: ImportedModuleInfo,
221                                 -- Modules this one depends on: that is, the union 
222                                 -- of the modules its *direct* imports depend on.
223                                 -- NB: The direct imports have .hi files that enumerate *all* the
224                                 -- dependencies (direct or not) of the imported module.
225
226                 iDecls :: DeclsMap,     -- A single, global map of Names to decls
227                                         -- we can get away with importing them abstractly
228
229                 iInsts :: IfaceInsts,
230                 -- The as-yet un-slurped instance decls; this bag is depleted when we
231                 -- slurp an instance decl so that we don't slurp the same one twice.
232                 -- Each is 'gated' by the names that must be available before
233                 -- this instance decl is needed.
234
235                 iRules :: IfaceRules,
236                 -- Similar to instance decls, only for rules
237
238         -- SEMI-EPHEMERAL FIELDS
239                 -- iFixes and iDeprecs are accumulated here while one module
240                 -- is compiled, but are transferred to the package symbol table
241                 -- at the end.  We don't add them to the table as we encounter them
242                 -- because doing so would require us to have a mutable symbol table
243                 -- which is yukky.
244
245                 iFixes :: FixityEnv,            -- A single, global map of Names to fixities
246                                                 -- See comments with RnIfaces.lookupFixity
247                 iDeprecs :: DeprecationEnv,
248
249         -- EPHEMERAL FIELDS
250         -- These fields persist during the compilation of a single module only
251
252                 iSlurp :: NameSet,
253                 -- All the names (whether "big" or "small", whether wired-in or not,
254                 -- whether locally defined or not) that have been slurped in so far.
255
256                 iVSlurp :: [(Name,Version)]
257                 -- All the (a) non-wired-in (b) "big" (c) non-locally-defined 
258                 -- names that have been slurped in so far, with their versions.
259                 -- This is used to generate the "usage" information for this module.
260                 -- Subset of the previous field.
261         }
262
263 type ImportedModuleInfo 
264      = FiniteMap ModuleName (WhetherHasOrphans, IsBootInterface, 
265                              Maybe (Module, Version, Version, Version, WhereFrom, Avails))
266                                 -- The three Versions are module version, fixity version, rules version
267
268                 -- Suppose the domain element is module 'A'
269                 --
270                 -- The first Bool is True if A contains 
271                 -- 'orphan' rules or instance decls
272
273                 -- The second Bool is true if the interface file actually
274                 -- read was an .hi-boot file
275
276                 -- Nothing => A's interface not yet read, but this module has
277                 --            imported a module, B, that itself depends on A
278                 --
279                 -- Just xx => A's interface has been read.  The Module in 
280                 --              the Just has the correct Dll flag
281
282                 -- This set is used to decide whether to look for
283                 -- A.hi or A.hi-boot when importing A.f.
284                 -- Basically, we look for A.hi if A is in the map, and A.hi-boot
285                 -- otherwise
286 \end{code}
287
288
289 %************************************************************************
290 %*                                                                      *
291 \subsection{Main monad code}
292 %*                                                                      *
293 %************************************************************************
294
295 \begin{code}
296 initRn :: DynFlags -> Finder -> GlobalSymbolTable
297        -> PersistentRenamerState
298        -> Module -> SrcLoc
299        -> RnMG t
300        -> IO (t, Bag WarnMsg, Bag ErrMsg)
301
302 initRn dflags finder gst prs mod loc do_rn
303   = do uniqs     <- mkSplitUniqSupply 'r'
304        names_var <- newIORef (uniqs, prsOrig prs)
305        errs_var  <- newIORef (emptyBag,emptyBag)
306        iface_var <- newIORef (initIfaces prs)
307        let rn_down = RnDown { rn_mod = mod,
308                               rn_loc = loc, 
309     
310                               rn_finder = finder,
311                               rn_dflags = dflags,
312                               rn_gst    = gst,
313                                      
314                               rn_ns     = names_var, 
315                               rn_errs   = errs_var, 
316                               rn_ifaces = iface_var,
317                      }
318
319        -- do the business
320        res <- do_rn rn_down ()
321
322        -- grab errors and return
323        (warns, errs) <- readIORef errs_var
324
325        return (res, errs, warns)
326
327
328 initIfaces :: PersistentRenamerState -> Ifaces
329 initIfaces prs
330   = Ifaces { iDecls = prsDecls prs,
331              iInsts = prsInsts prs,
332              iRules = prsRules prs,
333
334              iFixes   = emptyNameEnv,
335              iDeprecs = emptyNameEnv,
336
337              iImpModInfo = emptyFM,
338              --iDeferred   = emptyNameSet,
339              iSlurp      = unitNameSet (mkUnboundName dummyRdrVarName),
340                         -- Pretend that the dummy unbound name has already been
341                         -- slurped.  This is what's returned for an out-of-scope name,
342                         -- and we don't want thereby to try to suck it in!
343              iVSlurp = []
344       }
345
346
347 initRnMS :: GlobalRdrEnv -> FixityEnv -> RnMode -> RnMS r -> RnM d r
348 initRnMS rn_env fixity_env mode thing_inside rn_down g_down
349   = let
350         s_down = SDown { rn_genv = rn_env, rn_lenv = emptyRdrEnv, 
351                          rn_fixenv = fixity_env, rn_mode = mode }
352     in
353     thing_inside rn_down s_down
354
355 initIfaceRnMS :: Module -> RnMS r -> RnM d r
356 initIfaceRnMS mod thing_inside 
357   = initRnMS emptyRdrEnv emptyNameEnv InterfaceMode $
358     setModuleRn mod thing_inside
359
360 \end{code}
361
362 @renameSourceCode@ is used to rename stuff ``out-of-line'';
363 that is, not as part of the main renamer.
364 Sole examples: derived definitions,
365 which are only generated in the type checker.
366
367 The @NameSupply@ includes a @UniqueSupply@, so if you call it more than
368 once you must either split it, or install a fresh unique supply.
369
370 \begin{code}
371 renameSourceCode :: DynFlags 
372                  -> Module
373                  -> PersistentRenamerState
374                  -> RnMS r
375                  -> r
376
377 renameSourceCode dflags mod prs m
378   = unsafePerformIO (
379         -- It's not really unsafe!  When renaming source code we
380         -- only do any I/O if we need to read in a fixity declaration;
381         -- and that doesn't happen in pragmas etc
382
383         mkSplitUniqSupply 'r'                   >>= \ new_us ->
384         newIORef (new_us, prsOrig prs)          >>= \ names_var ->
385         newIORef (emptyBag,emptyBag)            >>= \ errs_var ->
386         let
387             rn_down = RnDown { rn_dflags = dflags,
388                                rn_loc = mkGeneratedSrcLoc, rn_ns = names_var,
389                                rn_errs = errs_var, 
390                                rn_mod = mod, 
391                                rn_ifaces = panic "rnameSourceCode: rn_ifaces"  -- Not required
392                              }
393             s_down = SDown { rn_mode = InterfaceMode,
394                                -- So that we can refer to PrelBase.True etc
395                              rn_genv = emptyRdrEnv, rn_lenv = emptyRdrEnv,
396                              rn_fixenv = emptyNameEnv }
397         in
398         m rn_down s_down                        >>= \ result ->
399         
400         readIORef errs_var                      >>= \ (warns,errs) ->
401
402         (if not (isEmptyBag errs) then
403                 pprTrace "Urk! renameSourceCode found errors" (display errs) 
404 #ifdef DEBUG
405          else if not (isEmptyBag warns) then
406                 pprTrace "Note: renameSourceCode found warnings" (display warns)
407 #endif
408          else
409                 id) $
410
411         return result
412     )
413   where
414     display errs = pprBagOfErrors errs
415
416 {-# INLINE thenRn #-}
417 {-# INLINE thenRn_ #-}
418 {-# INLINE returnRn #-}
419 {-# INLINE andRn #-}
420
421 returnRn :: a -> RnM d a
422 thenRn   :: RnM d a -> (a -> RnM d b) -> RnM d b
423 thenRn_  :: RnM d a -> RnM d b -> RnM d b
424 andRn    :: (a -> a -> a) -> RnM d a -> RnM d a -> RnM d a
425 mapRn    :: (a -> RnM d b) -> [a] -> RnM d [b]
426 mapRn_   :: (a -> RnM d b) -> [a] -> RnM d ()
427 mapMaybeRn :: (a -> RnM d (Maybe b)) -> [a] -> RnM d [b]
428 flatMapRn  :: (a -> RnM d [b])       -> [a] -> RnM d [b]
429 sequenceRn :: [RnM d a] -> RnM d [a]
430 foldlRn :: (b  -> a -> RnM d b) -> b -> [a] -> RnM d b
431 mapAndUnzipRn :: (a -> RnM d (b,c)) -> [a] -> RnM d ([b],[c])
432 fixRn    :: (a -> RnM d a) -> RnM d a
433
434 returnRn v gdown ldown  = return v
435 thenRn m k gdown ldown  = m gdown ldown >>= \ r -> k r gdown ldown
436 thenRn_ m k gdown ldown = m gdown ldown >> k gdown ldown
437 fixRn m gdown ldown = fixIO (\r -> m r gdown ldown)
438 andRn combiner m1 m2 gdown ldown
439   = m1 gdown ldown >>= \ res1 ->
440     m2 gdown ldown >>= \ res2 ->
441     return (combiner res1 res2)
442
443 sequenceRn []     = returnRn []
444 sequenceRn (m:ms) =  m                  `thenRn` \ r ->
445                      sequenceRn ms      `thenRn` \ rs ->
446                      returnRn (r:rs)
447
448 mapRn f []     = returnRn []
449 mapRn f (x:xs)
450   = f x         `thenRn` \ r ->
451     mapRn f xs  `thenRn` \ rs ->
452     returnRn (r:rs)
453
454 mapRn_ f []     = returnRn ()
455 mapRn_ f (x:xs) = 
456     f x         `thenRn_`
457     mapRn_ f xs
458
459 foldlRn k z [] = returnRn z
460 foldlRn k z (x:xs) = k z x      `thenRn` \ z' ->
461                      foldlRn k z' xs
462
463 mapAndUnzipRn f [] = returnRn ([],[])
464 mapAndUnzipRn f (x:xs)
465   = f x                 `thenRn` \ (r1,  r2)  ->
466     mapAndUnzipRn f xs  `thenRn` \ (rs1, rs2) ->
467     returnRn (r1:rs1, r2:rs2)
468
469 mapAndUnzip3Rn f [] = returnRn ([],[],[])
470 mapAndUnzip3Rn f (x:xs)
471   = f x                 `thenRn` \ (r1,  r2,  r3)  ->
472     mapAndUnzip3Rn f xs `thenRn` \ (rs1, rs2, rs3) ->
473     returnRn (r1:rs1, r2:rs2, r3:rs3)
474
475 mapMaybeRn f []     = returnRn []
476 mapMaybeRn f (x:xs) = f x               `thenRn` \ maybe_r ->
477                       mapMaybeRn f xs   `thenRn` \ rs ->
478                       case maybe_r of
479                         Nothing -> returnRn rs
480                         Just r  -> returnRn (r:rs)
481
482 flatMapRn f []     = returnRn []
483 flatMapRn f (x:xs) = f x                `thenRn` \ r ->
484                      flatMapRn f xs     `thenRn` \ rs ->
485                      returnRn (r ++ rs)
486 \end{code}
487
488
489
490 %************************************************************************
491 %*                                                                      *
492 \subsection{Boring plumbing for common part}
493 %*                                                                      *
494 %************************************************************************
495
496
497 %================
498 \subsubsection{  Errors and warnings}
499 %=====================
500
501 \begin{code}
502 failWithRn :: a -> Message -> RnM d a
503 failWithRn res msg (RnDown {rn_errs = errs_var, rn_loc = loc}) l_down
504   = readIORef  errs_var                                         >>=  \ (warns,errs) ->
505     writeIORef errs_var (warns, errs `snocBag` err)             >> 
506     return res
507   where
508     err = addShortErrLocLine loc msg
509
510 warnWithRn :: a -> Message -> RnM d a
511 warnWithRn res msg (RnDown {rn_errs = errs_var, rn_loc = loc}) l_down
512   = readIORef  errs_var                                         >>=  \ (warns,errs) ->
513     writeIORef errs_var (warns `snocBag` warn, errs)    >> 
514     return res
515   where
516     warn = addShortWarnLocLine loc msg
517
518 addErrRn :: Message -> RnM d ()
519 addErrRn err = failWithRn () err
520
521 checkRn :: Bool -> Message -> RnM d ()  -- Check that a condition is true
522 checkRn False err = addErrRn err
523 checkRn True  err = returnRn ()
524
525 warnCheckRn :: Bool -> Message -> RnM d ()      -- Check that a condition is true
526 warnCheckRn False err = addWarnRn err
527 warnCheckRn True  err = returnRn ()
528
529 addWarnRn :: Message -> RnM d ()
530 addWarnRn warn = warnWithRn () warn
531
532 checkErrsRn :: RnM d Bool               -- True <=> no errors so far
533 checkErrsRn (RnDown {rn_errs = errs_var}) l_down
534   = readIORef  errs_var                                         >>=  \ (warns,errs) ->
535     return (isEmptyBag errs)
536
537 doptsRn :: (DynFlags -> Bool) -> RnM d Bool
538 doptsRn dopt (RnDown { rn_dflags = dflags}) l_down
539    = return (dopt dflags)
540 \end{code}
541
542
543 %================
544 \subsubsection{  Source location}
545 %=====================
546
547 \begin{code}
548 pushSrcLocRn :: SrcLoc -> RnM d a -> RnM d a
549 pushSrcLocRn loc' m down l_down
550   = m (down {rn_loc = loc'}) l_down
551
552 getSrcLocRn :: RnM d SrcLoc
553 getSrcLocRn down l_down
554   = return (rn_loc down)
555 \end{code}
556
557 %================
558 \subsubsection{  Name supply}
559 %=====================
560
561 \begin{code}
562 getNameSupplyRn :: RnM d (UniqSupply, OrigNameEnv)
563 getNameSupplyRn rn_down l_down
564   = readIORef (rn_ns rn_down)
565
566 setNameSupplyRn :: (UniqSupply, OrigNameEnv) -> RnM d ()
567 setNameSupplyRn names' (RnDown {rn_ns = names_var}) l_down
568   = writeIORef names_var names'
569
570 getUniqRn :: RnM d Unique
571 getUniqRn (RnDown {rn_ns = names_var}) l_down
572  = readIORef names_var >>= \ (us, {-cache,-} ipcache) ->
573    let
574      (us1,us') = splitUniqSupply us
575    in
576    writeIORef names_var (us', {-cache,-} ipcache)  >>
577    return (uniqFromSupply us1)
578 \end{code}
579
580 %================
581 \subsubsection{  Module}
582 %=====================
583
584 \begin{code}
585 getModuleRn :: RnM d Module
586 getModuleRn (RnDown {rn_mod = mod}) l_down
587   = return mod
588
589 setModuleRn :: Module -> RnM d a -> RnM d a
590 setModuleRn new_mod enclosed_thing rn_down l_down
591   = enclosed_thing (rn_down {rn_mod = new_mod}) l_down
592 \end{code}
593
594
595 %************************************************************************
596 %*                                                                      *
597 \subsection{Plumbing for rename-source part}
598 %*                                                                      *
599 %************************************************************************
600
601 %================
602 \subsubsection{  RnEnv}
603 %=====================
604
605 \begin{code}
606 getNameEnvs :: RnMS (GlobalRdrEnv, LocalRdrEnv)
607 getNameEnvs rn_down (SDown {rn_genv = global_env, rn_lenv = local_env})
608   = return (global_env, local_env)
609
610 getLocalNameEnv :: RnMS LocalRdrEnv
611 getLocalNameEnv rn_down (SDown {rn_lenv = local_env})
612   = return local_env
613
614 getGlobalNameEnv :: RnMS GlobalRdrEnv
615 getGlobalNameEnv rn_down (SDown {rn_genv = global_env})
616   = return global_env
617
618 setLocalNameEnv :: LocalRdrEnv -> RnMS a -> RnMS a
619 setLocalNameEnv local_env' m rn_down l_down
620   = m rn_down (l_down {rn_lenv = local_env'})
621
622 getFixityEnv :: RnMS FixityEnv
623 getFixityEnv rn_down (SDown {rn_fixenv = fixity_env})
624   = return fixity_env
625
626 extendFixityEnv :: [(Name, RenamedFixitySig)] -> RnMS a -> RnMS a
627 extendFixityEnv fixes enclosed_scope
628                 rn_down l_down@(SDown {rn_fixenv = fixity_env})
629   = let
630         new_fixity_env = extendNameEnvList fixity_env fixes
631     in
632     enclosed_scope rn_down (l_down {rn_fixenv = new_fixity_env})
633 \end{code}
634
635 %================
636 \subsubsection{  Mode}
637 %=====================
638
639 \begin{code}
640 getModeRn :: RnMS RnMode
641 getModeRn rn_down (SDown {rn_mode = mode})
642   = return mode
643
644 setModeRn :: RnMode -> RnMS a -> RnMS a
645 setModeRn new_mode thing_inside rn_down l_down
646   = thing_inside rn_down (l_down {rn_mode = new_mode})
647 \end{code}
648
649
650 %************************************************************************
651 %*                                                                      *
652 \subsection{Plumbing for rename-globals part}
653 %*                                                                      *
654 %************************************************************************
655
656 \begin{code}
657 getIfacesRn :: RnM d Ifaces
658 getIfacesRn (RnDown {rn_ifaces = iface_var}) _
659   = readIORef iface_var
660
661 setIfacesRn :: Ifaces -> RnM d ()
662 setIfacesRn ifaces (RnDown {rn_ifaces = iface_var}) _
663   = writeIORef iface_var ifaces
664 \end{code}