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