[project @ 2000-10-16 10:05:00 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_hst     :: HomeSymbolTable,
119
120         rn_errs    :: IORef (Bag WarnMsg, Bag ErrMsg),
121         rn_ns      :: IORef (UniqSupply, OrigNameEnv),
122         rn_ifaces  :: IORef Ifaces
123     }
124
125         -- For renaming source code
126 data SDown = SDown {
127                   rn_mode :: RnMode,
128
129                   rn_genv :: GlobalRdrEnv,      -- Global envt
130
131                   rn_lenv :: LocalRdrEnv,       -- Local name envt
132                         --   Does *not* include global name envt; may shadow it
133                         --   Includes both ordinary variables and type variables;
134                         --   they are kept distinct because tyvar have a different
135                         --   occurrence contructor (Name.TvOcc)
136                         -- We still need the unsullied global name env so that
137                         --   we can look up record field names
138
139                   rn_fixenv :: LocalFixityEnv   -- Local fixities
140                         -- The global fixities are held in the
141                         -- rn_ifaces field.  Why?  See the comments
142                         -- with RnIfaces.lookupLocalFixity
143                 }
144
145 data RnMode     = SourceMode                    -- Renaming source code
146                 | InterfaceMode                 -- Renaming interface declarations.  
147 \end{code}
148
149 %===================================================
150 \subsubsection{         ENVIRONMENTS}
151 %===================================================
152
153 \begin{code}
154 --------------------------------
155 type LocalRdrEnv    = RdrNameEnv Name
156 type LocalFixityEnv = NameEnv RenamedFixitySig
157         -- We keep the whole fixity sig so that we
158         -- can report line-number info when there is a duplicate
159         -- fixity declaration
160
161 lookupLocalFixity :: FixityEnv -> Name -> Fixity
162 lookupLocalFixity env name
163   = case lookupNameEnv env name of 
164         Just (FixitySig _ fix _) -> fix
165         Nothing                  -> defaultFixity
166 \end{code}
167
168 \begin{code}
169 type ExportAvails = (FiniteMap ModuleName Avails,
170         -- Used to figure out "module M" export specifiers
171         -- Includes avails only from *unqualified* imports
172         -- (see 1.4 Report Section 5.1.1)
173
174                      AvailEnv)  -- Used to figure out all other export specifiers.
175 \end{code}
176
177 %===================================================
178 \subsubsection{         INTERFACE FILE STUFF}
179 %===================================================
180
181 \begin{code}
182
183 data ParsedIface
184   = ParsedIface {
185       pi_mod       :: Module,                           -- Complete with package info
186       pi_vers      :: Version,                          -- Module version number
187       pi_orphan    :: WhetherHasOrphans,                -- Whether this module has orphans
188       pi_usages    :: [ImportVersion OccName],          -- Usages
189       pi_exports   :: [ExportItem],                     -- Exports
190       pi_insts     :: [RdrNameInstDecl],                -- Local instance declarations
191       pi_decls     :: [(Version, RdrNameHsDecl)],       -- Local definitions
192       pi_fixity    :: (Version, [RdrNameFixitySig]),    -- Local fixity declarations, with their version
193       pi_rules     :: (Version, [RdrNameRuleDecl]),     -- Rules, with their version
194       pi_deprecs   :: [RdrNameDeprecation]              -- Deprecations
195     }
196 \end{code}
197
198 %************************************************************************
199 %*                                                                      *
200 \subsection{The renamer state}
201 %*                                                                      *
202 %************************************************************************
203
204 \begin{code}
205 data Ifaces = Ifaces {
206     -- PERSISTENT FIELDS
207         iPST :: PackageSymbolTable,     
208                 -- The ModuleDetails for modules in other packages
209                 -- whose interfaces we have opened
210                 -- The contents of those interface files may be mostly
211                 -- in the iDecls, iInsts, iRules (below), but what *will*
212                 -- be in the PackageSymbolTable is:
213                 --      * The Module 
214                 --      * Version info
215                 --      * Its exports
216                 --      * Fixities
217                 --      * Deprecations
218                 -- This field is initialised from the compiler's persistent
219                 -- package symbol table, and the renamer incrementally adds
220                 -- to it.
221
222         iDecls :: DeclsMap,     
223                 -- A single, global map of Names to unslurped decls
224
225         iInsts :: IfaceInsts,
226                 -- The as-yet un-slurped instance decls; this bag is depleted when we
227                 -- slurp an instance decl so that we don't slurp the same one twice.
228                 -- Each is 'gated' by the names that must be available before
229                 -- this instance decl is needed.
230
231         iRules :: IfaceRules,
232                 -- Similar to instance decls, only for rules
233
234     -- EPHEMERAL FIELDS
235     -- These fields persist during the compilation of a single module only
236         iImpModInfo :: ImportedModuleInfo,
237                         -- Modules this one depends on: that is, the union 
238                         -- of the modules its *direct* imports depend on.
239                         -- NB: The direct imports have .hi files that enumerate *all* the
240                         -- dependencies (direct or not) of the imported module.
241
242         iSlurp :: NameSet,
243                 -- All the names (whether "big" or "small", whether wired-in or not,
244                 -- whether locally defined or not) that have been slurped in so far.
245
246         iVSlurp :: [(Name,Version)]
247                 -- All the (a) non-wired-in (b) "big" (c) non-locally-defined 
248                 -- names that have been slurped in so far, with their versions.
249                 -- This is used to generate the "usage" information for this module.
250                 -- Subset of the previous field.
251     }
252
253 type ImportedModuleInfo = FiniteMap ModuleName (WhetherHasOrphans, IsBootInterface, IsLoaded)
254 type IsLoaded = True
255 \end{code}
256
257
258 %************************************************************************
259 %*                                                                      *
260 \subsection{Main monad code}
261 %*                                                                      *
262 %************************************************************************
263
264 \begin{code}
265 initRn :: DynFlags -> Finder -> HomeSymbolTable
266        -> PersistentCompilerState
267        -> Module -> SrcLoc
268        -> RnMG t
269        -> IO (t, PersistentCompilerState, (Bag WarnMsg, Bag ErrMsg))
270
271 initRn dflags finder hst pcs mod loc do_rn
272   = do 
273         let prs = pcsPRS pcs
274         uniqs     <- mkSplitUniqSupply 'r'
275         names_var <- newIORef (uniqs, prsOrig prs)
276         errs_var  <- newIORef (emptyBag,emptyBag)
277         iface_var <- newIORef (initIfaces pcs)
278         let rn_down = RnDown { rn_mod = mod,
279                                rn_loc = loc, 
280         
281                                rn_finder = finder,
282                                rn_dflags = dflags,
283                                rn_hst    = hst,
284                                              
285                                rn_ns     = names_var, 
286                                rn_errs   = errs_var, 
287                                rn_ifaces = iface_var,
288                              }
289         
290         -- do the business
291         res <- do_rn rn_down ()
292         
293         -- Grab state and record it
294         (warns, errs) <- readIORef errs_var
295         new_ifaces    <- readIORef iface_var
296         (_, new_orig) <- readIORef names_var
297
298         let new_prs = prs { prsOrig = new_orig, 
299                             prsDecls = iDecls new_ifaces,
300                             prsInsts = iInsts new_ifaces,
301                             prsRules = iRules new_ifaces }
302         let new_pcs = pcs { pcsPST = iPST new_ifaces, 
303                             pcsPRS = new_prs }
304         
305         return (res, new_pcs, (warns, errs))
306
307
308 initIfaces :: PersistentCompilerState -> Ifaces
309 initIfaces (PCS { pcsPST = pst, psrPRS = prs })
310   = Ifaces { iPST   = pst,
311              iDecls = prsDecls prs,
312              iInsts = prsInsts prs,
313              iRules = prsRules prs,
314
315              iImpModInfo = emptyFM,
316              iSlurp      = unitNameSet (mkUnboundName dummyRdrVarName),
317                         -- Pretend that the dummy unbound name has already been
318                         -- slurped.  This is what's returned for an out-of-scope name,
319                         -- and we don't want thereby to try to suck it in!
320              iVSlurp = []
321       }
322
323
324 initRnMS :: GlobalRdrEnv -> FixityEnv -> RnMode -> RnMS r -> RnM d r
325 initRnMS rn_env fixity_env mode thing_inside rn_down g_down
326   = let
327         s_down = SDown { rn_genv = rn_env, rn_lenv = emptyRdrEnv, 
328                          rn_fixenv = fixity_env, rn_mode = mode }
329     in
330     thing_inside rn_down s_down
331
332 initIfaceRnMS :: Module -> RnMS r -> RnM d r
333 initIfaceRnMS mod thing_inside 
334   = initRnMS emptyRdrEnv emptyNameEnv InterfaceMode $
335     setModuleRn mod thing_inside
336
337 \end{code}
338
339 @renameSourceCode@ is used to rename stuff ``out-of-line'';
340 that is, not as part of the main renamer.
341 Sole examples: derived definitions,
342 which are only generated in the type checker.
343
344 The @NameSupply@ includes a @UniqueSupply@, so if you call it more than
345 once you must either split it, or install a fresh unique supply.
346
347 \begin{code}
348 renameSourceCode :: DynFlags 
349                  -> Module
350                  -> PersistentRenamerState
351                  -> RnMS r
352                  -> r
353
354 renameSourceCode dflags mod prs m
355   = unsafePerformIO (
356         -- It's not really unsafe!  When renaming source code we
357         -- only do any I/O if we need to read in a fixity declaration;
358         -- and that doesn't happen in pragmas etc
359
360         mkSplitUniqSupply 'r'                   >>= \ new_us ->
361         newIORef (new_us, prsOrig prs)          >>= \ names_var ->
362         newIORef (emptyBag,emptyBag)            >>= \ errs_var ->
363         let
364             rn_down = RnDown { rn_dflags = dflags,
365                                rn_loc = mkGeneratedSrcLoc, rn_ns = names_var,
366                                rn_errs = errs_var, 
367                                rn_mod = mod, 
368                                rn_ifaces = panic "rnameSourceCode: rn_ifaces"  -- Not required
369                              }
370             s_down = SDown { rn_mode = InterfaceMode,
371                                -- So that we can refer to PrelBase.True etc
372                              rn_genv = emptyRdrEnv, rn_lenv = emptyRdrEnv,
373                              rn_fixenv = emptyNameEnv }
374         in
375         m rn_down s_down                        >>= \ result ->
376         
377         readIORef errs_var                      >>= \ (warns,errs) ->
378
379         (if not (isEmptyBag errs) then
380                 pprTrace "Urk! renameSourceCode found errors" (display errs) 
381 #ifdef DEBUG
382          else if not (isEmptyBag warns) then
383                 pprTrace "Note: renameSourceCode found warnings" (display warns)
384 #endif
385          else
386                 id) $
387
388         return result
389     )
390   where
391     display errs = pprBagOfErrors errs
392
393 {-# INLINE thenRn #-}
394 {-# INLINE thenRn_ #-}
395 {-# INLINE returnRn #-}
396 {-# INLINE andRn #-}
397
398 returnRn :: a -> RnM d a
399 thenRn   :: RnM d a -> (a -> RnM d b) -> RnM d b
400 thenRn_  :: RnM d a -> RnM d b -> RnM d b
401 andRn    :: (a -> a -> a) -> RnM d a -> RnM d a -> RnM d a
402 mapRn    :: (a -> RnM d b) -> [a] -> RnM d [b]
403 mapRn_   :: (a -> RnM d b) -> [a] -> RnM d ()
404 mapMaybeRn :: (a -> RnM d (Maybe b)) -> [a] -> RnM d [b]
405 flatMapRn  :: (a -> RnM d [b])       -> [a] -> RnM d [b]
406 sequenceRn :: [RnM d a] -> RnM d [a]
407 foldlRn :: (b  -> a -> RnM d b) -> b -> [a] -> RnM d b
408 mapAndUnzipRn :: (a -> RnM d (b,c)) -> [a] -> RnM d ([b],[c])
409 fixRn    :: (a -> RnM d a) -> RnM d a
410
411 returnRn v gdown ldown  = return v
412 thenRn m k gdown ldown  = m gdown ldown >>= \ r -> k r gdown ldown
413 thenRn_ m k gdown ldown = m gdown ldown >> k gdown ldown
414 fixRn m gdown ldown = fixIO (\r -> m r gdown ldown)
415 andRn combiner m1 m2 gdown ldown
416   = m1 gdown ldown >>= \ res1 ->
417     m2 gdown ldown >>= \ res2 ->
418     return (combiner res1 res2)
419
420 sequenceRn []     = returnRn []
421 sequenceRn (m:ms) =  m                  `thenRn` \ r ->
422                      sequenceRn ms      `thenRn` \ rs ->
423                      returnRn (r:rs)
424
425 mapRn f []     = returnRn []
426 mapRn f (x:xs)
427   = f x         `thenRn` \ r ->
428     mapRn f xs  `thenRn` \ rs ->
429     returnRn (r:rs)
430
431 mapRn_ f []     = returnRn ()
432 mapRn_ f (x:xs) = 
433     f x         `thenRn_`
434     mapRn_ f xs
435
436 foldlRn k z [] = returnRn z
437 foldlRn k z (x:xs) = k z x      `thenRn` \ z' ->
438                      foldlRn k z' xs
439
440 mapAndUnzipRn f [] = returnRn ([],[])
441 mapAndUnzipRn f (x:xs)
442   = f x                 `thenRn` \ (r1,  r2)  ->
443     mapAndUnzipRn f xs  `thenRn` \ (rs1, rs2) ->
444     returnRn (r1:rs1, r2:rs2)
445
446 mapAndUnzip3Rn f [] = returnRn ([],[],[])
447 mapAndUnzip3Rn f (x:xs)
448   = f x                 `thenRn` \ (r1,  r2,  r3)  ->
449     mapAndUnzip3Rn f xs `thenRn` \ (rs1, rs2, rs3) ->
450     returnRn (r1:rs1, r2:rs2, r3:rs3)
451
452 mapMaybeRn f []     = returnRn []
453 mapMaybeRn f (x:xs) = f x               `thenRn` \ maybe_r ->
454                       mapMaybeRn f xs   `thenRn` \ rs ->
455                       case maybe_r of
456                         Nothing -> returnRn rs
457                         Just r  -> returnRn (r:rs)
458
459 flatMapRn f []     = returnRn []
460 flatMapRn f (x:xs) = f x                `thenRn` \ r ->
461                      flatMapRn f xs     `thenRn` \ rs ->
462                      returnRn (r ++ rs)
463 \end{code}
464
465
466
467 %************************************************************************
468 %*                                                                      *
469 \subsection{Boring plumbing for common part}
470 %*                                                                      *
471 %************************************************************************
472
473
474 %================
475 \subsubsection{  Errors and warnings}
476 %=====================
477
478 \begin{code}
479 failWithRn :: a -> Message -> RnM d a
480 failWithRn res msg (RnDown {rn_errs = errs_var, rn_loc = loc}) l_down
481   = readIORef  errs_var                                         >>=  \ (warns,errs) ->
482     writeIORef errs_var (warns, errs `snocBag` err)             >> 
483     return res
484   where
485     err = addShortErrLocLine loc msg
486
487 warnWithRn :: a -> Message -> RnM d a
488 warnWithRn res msg (RnDown {rn_errs = errs_var, rn_loc = loc}) l_down
489   = readIORef  errs_var                                         >>=  \ (warns,errs) ->
490     writeIORef errs_var (warns `snocBag` warn, errs)    >> 
491     return res
492   where
493     warn = addShortWarnLocLine loc msg
494
495 addErrRn :: Message -> RnM d ()
496 addErrRn err = failWithRn () err
497
498 checkRn :: Bool -> Message -> RnM d ()  -- Check that a condition is true
499 checkRn False err = addErrRn err
500 checkRn True  err = returnRn ()
501
502 warnCheckRn :: Bool -> Message -> RnM d ()      -- Check that a condition is true
503 warnCheckRn False err = addWarnRn err
504 warnCheckRn True  err = returnRn ()
505
506 addWarnRn :: Message -> RnM d ()
507 addWarnRn warn = warnWithRn () warn
508
509 checkErrsRn :: RnM d Bool               -- True <=> no errors so far
510 checkErrsRn (RnDown {rn_errs = errs_var}) l_down
511   = readIORef  errs_var                                         >>=  \ (warns,errs) ->
512     return (isEmptyBag errs)
513
514 doptsRn :: (DynFlags -> Bool) -> RnM d Bool
515 doptsRn dopt (RnDown { rn_dflags = dflags}) l_down
516    = return (dopt dflags)
517 \end{code}
518
519
520 %================
521 \subsubsection{  Source location}
522 %=====================
523
524 \begin{code}
525 pushSrcLocRn :: SrcLoc -> RnM d a -> RnM d a
526 pushSrcLocRn loc' m down l_down
527   = m (down {rn_loc = loc'}) l_down
528
529 getSrcLocRn :: RnM d SrcLoc
530 getSrcLocRn down l_down
531   = return (rn_loc down)
532 \end{code}
533
534 %================
535 \subsubsection{The finder and home symbol table}
536 %=====================
537
538 \begin{code}
539 getFinderRn :: RnM d Finder
540 getFinderRn down l_down = return (rn_finder down)
541
542 getHomeSymbolTableRn :: RnM d HomeSymbolTable
543 getHomeSymbolTableRn down l_down = return (rn_hst down)
544 \end{code}
545
546 %================
547 \subsubsection{Name supply}
548 %=====================
549
550 \begin{code}
551 getNameSupplyRn :: RnM d (UniqSupply, OrigNameEnv)
552 getNameSupplyRn rn_down l_down
553   = readIORef (rn_ns rn_down)
554
555 setNameSupplyRn :: (UniqSupply, OrigNameEnv) -> RnM d ()
556 setNameSupplyRn names' (RnDown {rn_ns = names_var}) l_down
557   = writeIORef names_var names'
558
559 getUniqRn :: RnM d Unique
560 getUniqRn (RnDown {rn_ns = names_var}) l_down
561  = readIORef names_var >>= \ (us, {-cache,-} ipcache) ->
562    let
563      (us1,us') = splitUniqSupply us
564    in
565    writeIORef names_var (us', {-cache,-} ipcache)  >>
566    return (uniqFromSupply us1)
567 \end{code}
568
569 %================
570 \subsubsection{  Module}
571 %=====================
572
573 \begin{code}
574 getModuleRn :: RnM d Module
575 getModuleRn (RnDown {rn_mod = mod}) l_down
576   = return mod
577
578 setModuleRn :: Module -> RnM d a -> RnM d a
579 setModuleRn new_mod enclosed_thing rn_down l_down
580   = enclosed_thing (rn_down {rn_mod = new_mod}) l_down
581 \end{code}
582
583
584 %************************************************************************
585 %*                                                                      *
586 \subsection{Plumbing for rename-source part}
587 %*                                                                      *
588 %************************************************************************
589
590 %================
591 \subsubsection{  RnEnv}
592 %=====================
593
594 \begin{code}
595 getLocalNameEnv :: RnMS LocalRdrEnv
596 getLocalNameEnv rn_down (SDown {rn_lenv = local_env})
597   = return local_env
598
599 getGlobalNameEnv :: RnMS GlobalRdrEnv
600 getGlobalNameEnv rn_down (SDown {rn_genv = global_env})
601   = return global_env
602
603 setLocalNameEnv :: LocalRdrEnv -> RnMS a -> RnMS a
604 setLocalNameEnv local_env' m rn_down l_down
605   = m rn_down (l_down {rn_lenv = local_env'})
606
607 getFixityEnv :: RnMS LocalFixityEnv
608 getFixityEnv rn_down (SDown {rn_fixenv = fixity_env})
609   = return fixity_env
610
611 extendFixityEnv :: [(Name, RenamedFixitySig)] -> RnMS a -> RnMS a
612 extendFixityEnv fixes enclosed_scope
613                 rn_down l_down@(SDown {rn_fixenv = fixity_env})
614   = let
615         new_fixity_env = extendNameEnvList fixity_env fixes
616     in
617     enclosed_scope rn_down (l_down {rn_fixenv = new_fixity_env})
618 \end{code}
619
620 %================
621 \subsubsection{  Mode}
622 %=====================
623
624 \begin{code}
625 getModeRn :: RnMS RnMode
626 getModeRn rn_down (SDown {rn_mode = mode})
627   = return mode
628
629 setModeRn :: RnMode -> RnMS a -> RnMS a
630 setModeRn new_mode thing_inside rn_down l_down
631   = thing_inside rn_down (l_down {rn_mode = new_mode})
632 \end{code}
633
634
635 %************************************************************************
636 %*                                                                      *
637 \subsection{Plumbing for rename-globals part}
638 %*                                                                      *
639 %************************************************************************
640
641 \begin{code}
642 getIfacesRn :: RnM d Ifaces
643 getIfacesRn (RnDown {rn_ifaces = iface_var}) _
644   = readIORef iface_var
645
646 setIfacesRn :: Ifaces -> RnM d ()
647 setIfacesRn ifaces (RnDown {rn_ifaces = iface_var}) _
648   = writeIORef iface_var ifaces
649 \end{code}