[project @ 2003-10-29 18:14:27 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcRnMonad.lhs
1 \begin{code}
2 module TcRnMonad(
3         module TcRnMonad,
4         module TcRnTypes,
5         module IOEnv
6   ) where
7
8 #include "HsVersions.h"
9
10 import TcRnTypes        -- Re-export all
11 import IOEnv            -- Re-export all
12
13 import HsSyn            ( MonoBinds(..) )
14 import HscTypes         ( HscEnv(..), ModGuts(..), ModIface(..),
15                           TyThing, Dependencies(..), TypeEnv, emptyTypeEnv,
16                           ExternalPackageState(..), HomePackageTable,
17                           ModDetails(..), HomeModInfo(..), 
18                           Deprecs(..), FixityEnv, FixItem,
19                           GhciMode, lookupType, unQualInScope )
20 import Module           ( Module, ModuleName, unitModuleEnv, foldModuleEnv, emptyModuleEnv )
21 import RdrName          ( GlobalRdrEnv, emptyGlobalRdrEnv,      
22                           LocalRdrEnv, emptyLocalRdrEnv )
23 import Name             ( Name, isInternalName )
24 import Type             ( Type )
25 import NameEnv          ( extendNameEnvList )
26 import InstEnv          ( InstEnv, emptyInstEnv, extendInstEnv )
27
28 import VarSet           ( emptyVarSet )
29 import VarEnv           ( TidyEnv, emptyTidyEnv )
30 import ErrUtils         ( Message, Messages, emptyMessages, errorsFound, 
31                           addShortErrLocLine, addShortWarnLocLine, printErrorsAndWarnings )
32 import SrcLoc           ( SrcLoc, mkGeneralSrcLoc )
33 import NameEnv          ( emptyNameEnv )
34 import NameSet          ( emptyDUs, emptyNameSet )
35 import OccName          ( emptyOccEnv )
36 import Module           ( moduleName )
37 import Bag              ( emptyBag )
38 import Outputable
39 import UniqSupply       ( UniqSupply, mkSplitUniqSupply, uniqFromSupply, splitUniqSupply )
40 import Unique           ( Unique )
41 import CmdLineOpts      ( DynFlags, DynFlag(..), dopt, opt_PprStyle_Debug )
42 import Bag              ( snocBag, unionBags )
43 import Panic            ( showException )
44  
45 import Maybe            ( isJust )
46 import IO               ( stderr )
47 import DATA_IOREF       ( newIORef, readIORef )
48 import EXCEPTION        ( Exception )
49 \end{code}
50
51
52
53 %************************************************************************
54 %*                                                                      *
55                         initTc
56 %*                                                                      *
57 %************************************************************************
58
59 \begin{code}
60 ioToTcRn :: IO r -> TcRn r
61 ioToTcRn = ioToIOEnv
62 \end{code}
63
64 \begin{code}
65 initTc :: HscEnv
66        -> Module 
67        -> TcM r
68        -> IO (Maybe r)
69                 -- Nothing => error thrown by the thing inside
70                 -- (error messages should have been printed already)
71
72 initTc hsc_env mod do_this
73  = do { errs_var     <- newIORef (emptyBag, emptyBag) ;
74         tvs_var      <- newIORef emptyVarSet ;
75         type_env_var <- newIORef emptyNameEnv ;
76         dfuns_var    <- newIORef emptyNameSet ;
77
78         let {
79              gbl_env = TcGblEnv {
80                 tcg_mod      = mod,
81                 tcg_rdr_env  = emptyGlobalRdrEnv,
82                 tcg_fix_env  = emptyNameEnv,
83                 tcg_default  = Nothing,
84                 tcg_type_env = emptyNameEnv,
85                 tcg_type_env_var = type_env_var,
86                 tcg_inst_env  = mkImpInstEnv hsc_env,
87                 tcg_inst_uses = dfuns_var,
88                 tcg_exports  = [],
89                 tcg_imports  = init_imports,
90                 tcg_dus      = emptyDUs,
91                 tcg_binds    = EmptyMonoBinds,
92                 tcg_deprecs  = NoDeprecs,
93                 tcg_insts    = [],
94                 tcg_rules    = [],
95                 tcg_fords    = [],
96                 tcg_keep     = emptyNameSet
97              } ;
98              lcl_env = TcLclEnv {
99                 tcl_errs       = errs_var,
100                 tcl_loc        = mkGeneralSrcLoc FSLIT("Top level of module"),
101                 tcl_ctxt       = [],
102                 tcl_rdr        = emptyLocalRdrEnv,
103                 tcl_th_ctxt    = topStage,
104                 tcl_arrow_ctxt = topArrowCtxt,
105                 tcl_env        = emptyNameEnv,
106                 tcl_tyvars     = tvs_var,
107                 tcl_lie        = panic "initTc:LIE"     -- LIE only valid inside a getLIE
108              } ;
109         } ;
110    
111         -- OK, here's the business end!
112         maybe_res <- initTcRnIf 'a' hsc_env gbl_env lcl_env $
113                              do { r <- tryM do_this 
114                                 ; case r of
115                                     Right res -> return (Just res)
116                                     Left _    -> return Nothing } ;
117
118         -- Print any error messages
119         msgs <- readIORef errs_var ;
120         printErrorsAndWarnings msgs ;
121
122         let { dflags = hsc_dflags hsc_env
123             ; final_res | errorsFound dflags msgs = Nothing
124                         | otherwise               = maybe_res } ;
125
126         return final_res
127     }
128   where
129     init_imports = emptyImportAvails { imp_qual = unitModuleEnv mod emptyAvailEnv }
130         -- Initialise tcg_imports with an empty set of bindings for
131         -- this module, so that if we see 'module M' in the export
132         -- list, and there are no bindings in M, we don't bleat 
133         -- "unknown module M".
134
135 mkImpInstEnv :: HscEnv -> InstEnv
136 -- At the moment we (wrongly) build an instance environment from all the
137 -- home-package modules we have already compiled.
138 -- We should really only get instances from modules below us in the 
139 -- module import tree.
140 mkImpInstEnv (HscEnv {hsc_dflags = dflags, hsc_HPT = hpt})
141   = foldModuleEnv (add . md_insts . hm_details) emptyInstEnv hpt
142   where
143     add dfuns inst_env = foldl extendInstEnv inst_env dfuns
144
145 -- mkImpTypeEnv makes the imported symbol table
146 mkImpTypeEnv :: ExternalPackageState -> HomePackageTable
147              -> Name -> Maybe TyThing
148 mkImpTypeEnv pcs hpt = lookup 
149   where
150     pte = eps_PTE pcs
151     lookup name | isInternalName name = Nothing
152                 | otherwise           = lookupType hpt pte name
153 \end{code}
154
155
156 %************************************************************************
157 %*                                                                      *
158                 Initialisation
159 %*                                                                      *
160 %************************************************************************
161
162
163 \begin{code}
164 initTcRnIf :: Char              -- Tag for unique supply
165            -> HscEnv
166            -> gbl -> lcl 
167            -> TcRnIf gbl lcl a 
168            -> IO a
169 initTcRnIf uniq_tag hsc_env gbl_env lcl_env thing_inside
170    = do { us     <- mkSplitUniqSupply uniq_tag ;
171         ; us_var <- newIORef us ;
172
173         ; let { env = Env { env_top = hsc_env,
174                             env_us  = us_var,
175                             env_gbl = gbl_env,
176                             env_lcl = lcl_env } }
177
178         ; runIOEnv env thing_inside
179         }
180 \end{code}
181
182 %************************************************************************
183 %*                                                                      *
184                 Simple accessors
185 %*                                                                      *
186 %************************************************************************
187
188 \begin{code}
189 getTopEnv :: TcRnIf gbl lcl HscEnv
190 getTopEnv = do { env <- getEnv; return (env_top env) }
191
192 getGblEnv :: TcRnIf gbl lcl gbl
193 getGblEnv = do { env <- getEnv; return (env_gbl env) }
194
195 updGblEnv :: (gbl -> gbl) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
196 updGblEnv upd = updEnv (\ env@(Env { env_gbl = gbl }) -> 
197                           env { env_gbl = upd gbl })
198
199 setGblEnv :: gbl -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
200 setGblEnv gbl_env = updEnv (\ env -> env { env_gbl = gbl_env })
201
202 getLclEnv :: TcRnIf gbl lcl lcl
203 getLclEnv = do { env <- getEnv; return (env_lcl env) }
204
205 updLclEnv :: (lcl -> lcl) -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
206 updLclEnv upd = updEnv (\ env@(Env { env_lcl = lcl }) -> 
207                           env { env_lcl = upd lcl })
208
209 setLclEnv :: lcl' -> TcRnIf gbl lcl' a -> TcRnIf gbl lcl a
210 setLclEnv lcl_env = updEnv (\ env -> env { env_lcl = lcl_env })
211
212 getEnvs :: TcRnIf gbl lcl (gbl, lcl)
213 getEnvs = do { env <- getEnv; return (env_gbl env, env_lcl env) }
214
215 setEnvs :: (gbl', lcl') -> TcRnIf gbl' lcl' a -> TcRnIf gbl lcl a
216 setEnvs (gbl_env, lcl_env) = updEnv (\ env -> env { env_gbl = gbl_env, env_lcl = lcl_env })
217 \end{code}
218
219
220 Command-line flags
221
222 \begin{code}
223 getDOpts :: TcRnIf gbl lcl DynFlags
224 getDOpts = do { env <- getTopEnv; return (hsc_dflags env) }
225
226 doptM :: DynFlag -> TcRnIf gbl lcl Bool
227 doptM flag = do { dflags <- getDOpts; return (dopt flag dflags) }
228
229 ifOptM :: DynFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl ()     -- Do it flag is true
230 ifOptM flag thing_inside = do { b <- doptM flag; 
231                                 if b then thing_inside else return () }
232
233 getGhciMode :: TcRnIf gbl lcl GhciMode
234 getGhciMode = do { env <- getTopEnv; return (hsc_mode env) }
235 \end{code}
236
237 \begin{code}
238 getEpsVar :: TcRnIf gbl lcl (TcRef ExternalPackageState)
239 getEpsVar = do { env <- getTopEnv; return (hsc_EPS env) }
240
241 getEps :: TcRnIf gbl lcl ExternalPackageState
242 getEps = do { env <- getTopEnv; readMutVar (hsc_EPS env) }
243
244 setEps :: ExternalPackageState -> TcRnIf gbl lcl ()
245 setEps eps = do { env <- getTopEnv; writeMutVar (hsc_EPS env) eps }
246
247 updateEps :: (ExternalPackageState -> (ExternalPackageState, a))
248           -> TcRnIf gbl lcl a
249 updateEps upd_fn = do   { eps_var <- getEpsVar
250                         ; eps <- readMutVar eps_var
251                         ; let { (eps', val) = upd_fn eps }
252                         ; writeMutVar eps_var eps'
253                         ; return val }
254
255 updateEps_ :: (ExternalPackageState -> ExternalPackageState)
256            -> TcRnIf gbl lcl ()
257 updateEps_ upd_fn = do  { eps_var <- getEpsVar
258                         ; updMutVar eps_var upd_fn }
259
260 getHpt :: TcRnIf gbl lcl HomePackageTable
261 getHpt = do { env <- getTopEnv; return (hsc_HPT env) }
262 \end{code}
263
264 %************************************************************************
265 %*                                                                      *
266                 Unique supply
267 %*                                                                      *
268 %************************************************************************
269
270 \begin{code}
271 newUnique :: TcRnIf gbl lcl Unique
272 newUnique = do { us <- newUniqueSupply ; 
273                  return (uniqFromSupply us) }
274
275 newUniqueSupply :: TcRnIf gbl lcl UniqSupply
276 newUniqueSupply
277  = do { env <- getEnv ;
278         let { u_var = env_us env } ;
279         us <- readMutVar u_var ;
280         let { (us1, us2) = splitUniqSupply us } ;
281         writeMutVar u_var us1 ;
282         return us2 }
283 \end{code}
284
285
286 %************************************************************************
287 %*                                                                      *
288                 Debugging
289 %*                                                                      *
290 %************************************************************************
291
292 \begin{code}
293 traceTc, traceRn :: SDoc -> TcRn ()
294 traceRn      = dumpOptTcRn Opt_D_dump_rn_trace
295 traceTc      = dumpOptTcRn Opt_D_dump_tc_trace
296 traceSplice  = dumpOptTcRn Opt_D_dump_splices
297
298
299 traceIf :: SDoc -> TcRnIf m n ()        
300 traceIf      = dumpOptIf Opt_D_dump_if_trace
301 traceHiDiffs = dumpOptIf Opt_D_dump_hi_diffs
302
303
304 dumpOptIf :: DynFlag -> SDoc -> TcRnIf m n ()  -- No RdrEnv available, so qualify everything
305 dumpOptIf flag doc = ifOptM flag $
306                      ioToIOEnv (printForUser stderr alwaysQualify doc)
307
308 dumpOptTcRn :: DynFlag -> SDoc -> TcRn ()
309 dumpOptTcRn flag doc = ifOptM flag (dumpTcRn doc)
310
311 dumpTcRn :: SDoc -> TcRn ()
312 dumpTcRn doc = do { rdr_env <- getGlobalRdrEnv ;
313                     ioToTcRn (printForUser stderr (unQualInScope rdr_env) doc) }
314 \end{code}
315
316
317 %************************************************************************
318 %*                                                                      *
319                 Typechecker global environment
320 %*                                                                      *
321 %************************************************************************
322
323 \begin{code}
324 getModule :: TcRn Module
325 getModule = do { env <- getGblEnv; return (tcg_mod env) }
326
327 getGlobalRdrEnv :: TcRn GlobalRdrEnv
328 getGlobalRdrEnv = do { env <- getGblEnv; return (tcg_rdr_env env) }
329
330 getImports :: TcRn ImportAvails
331 getImports = do { env <- getGblEnv; return (tcg_imports env) }
332
333 getFixityEnv :: TcRn FixityEnv
334 getFixityEnv = do { env <- getGblEnv; return (tcg_fix_env env) }
335
336 extendFixityEnv :: [(Name,FixItem)] -> RnM a -> RnM a
337 extendFixityEnv new_bit
338   = updGblEnv (\env@(TcGblEnv { tcg_fix_env = old_fix_env }) -> 
339                 env {tcg_fix_env = extendNameEnvList old_fix_env new_bit})           
340
341 getDefaultTys :: TcRn (Maybe [Type])
342 getDefaultTys = do { env <- getGblEnv; return (tcg_default env) }
343 \end{code}
344
345 %************************************************************************
346 %*                                                                      *
347                 Error management
348 %*                                                                      *
349 %************************************************************************
350
351 \begin{code}
352 getSrcLocM :: TcRn SrcLoc
353         -- Avoid clash with Name.getSrcLoc
354 getSrcLocM = do { env <- getLclEnv; return (tcl_loc env) }
355
356 addSrcLoc :: SrcLoc -> TcRn a -> TcRn a
357 addSrcLoc loc = updLclEnv (\env -> env { tcl_loc = loc })
358 \end{code}
359
360
361 \begin{code}
362 getErrsVar :: TcRn (TcRef Messages)
363 getErrsVar = do { env <- getLclEnv; return (tcl_errs env) }
364
365 setErrsVar :: TcRef Messages -> TcRn a -> TcRn a
366 setErrsVar v = updLclEnv (\ env -> env { tcl_errs =  v })
367
368 addErr :: Message -> TcRn ()
369 addErr msg = do { loc <- getSrcLocM ; addErrAt loc msg }
370
371 addErrAt :: SrcLoc -> Message -> TcRn ()
372 addErrAt loc msg
373  = do {  errs_var <- getErrsVar ;
374          rdr_env <- getGlobalRdrEnv ;
375          let { err = addShortErrLocLine loc (unQualInScope rdr_env) msg } ;
376          (warns, errs) <- readMutVar errs_var ;
377          writeMutVar errs_var (warns, errs `snocBag` err) }
378
379 addErrs :: [(SrcLoc,Message)] -> TcRn ()
380 addErrs msgs = mappM_ add msgs
381              where
382                add (loc,msg) = addErrAt loc msg
383
384 addWarn :: Message -> TcRn ()
385 addWarn msg
386   = do { errs_var <- getErrsVar ;
387          loc <- getSrcLocM ;
388          rdr_env <- getGlobalRdrEnv ;
389          let { warn = addShortWarnLocLine loc (unQualInScope rdr_env) msg } ;
390          (warns, errs) <- readMutVar errs_var ;
391          writeMutVar errs_var (warns `snocBag` warn, errs) }
392
393 checkErr :: Bool -> Message -> TcRn ()
394 -- Add the error if the bool is False
395 checkErr ok msg = checkM ok (addErr msg)
396
397 warnIf :: Bool -> Message -> TcRn ()
398 warnIf True  msg = addWarn msg
399 warnIf False msg = return ()
400
401 addMessages :: Messages -> TcRn ()
402 addMessages (m_warns, m_errs)
403   = do { errs_var <- getErrsVar ;
404          (warns, errs) <- readMutVar errs_var ;
405          writeMutVar errs_var (warns `unionBags` m_warns,
406                                errs  `unionBags` m_errs) }
407
408 discardWarnings :: TcRn a -> TcRn a
409 -- Ignore warnings inside the thing inside;
410 -- used to ignore-unused-variable warnings inside derived code
411 -- With -dppr-debug, the effects is switched off, so you can still see
412 -- what warnings derived code would give
413 discardWarnings thing_inside
414   | opt_PprStyle_Debug = thing_inside
415   | otherwise
416   = do  { errs_var <- newMutVar emptyMessages
417         ; result <- setErrsVar errs_var thing_inside
418         ; (_warns, errs) <- readMutVar errs_var
419         ; addMessages (emptyBag, errs)
420         ; return result }
421 \end{code}
422
423
424 \begin{code}
425 recoverM :: TcRn r      -- Recovery action; do this if the main one fails
426          -> TcRn r      -- Main action: do this first
427          -> TcRn r
428 recoverM recover thing 
429   = do { mb_res <- try_m thing ;
430          case mb_res of
431            Left exn  -> recover
432            Right res -> returnM res }
433
434 tryTc :: TcRn a -> TcRn (Messages, Maybe a)
435     -- (tryTc m) executes m, and returns
436     --  Just r,  if m succeeds (returning r) and caused no errors
437     --  Nothing, if m fails, or caused errors
438     -- It also returns all the errors accumulated by m
439     --  (even in the Just case, there might be warnings)
440     --
441     -- It always succeeds (never raises an exception)
442 tryTc m 
443  = do { errs_var <- newMutVar emptyMessages ;
444         
445         mb_r <- try_m (setErrsVar errs_var m) ; 
446
447         new_errs <- readMutVar errs_var ;
448
449         dflags <- getDOpts ;
450
451         return (new_errs, 
452                 case mb_r of
453                   Left exn -> Nothing
454                   Right r | errorsFound dflags new_errs -> Nothing
455                           | otherwise                   -> Just r) 
456    }
457
458 try_m :: TcRn r -> TcRn (Either Exception r)
459 -- Does try_m, with a debug-trace on failure
460 try_m thing 
461   = do { mb_r <- tryM thing ;
462          case mb_r of 
463              Left exn -> do { traceTc (exn_msg exn); return mb_r }
464              Right r  -> return mb_r }
465   where
466     exn_msg exn = text "tryTc/recoverM recovering from" <+> text (showException exn)
467
468 tryTcLIE :: TcM a -> TcM (Messages, Maybe a)
469 -- Just like tryTc, except that it ensures that the LIE
470 -- for the thing is propagated only if there are no errors
471 -- Hence it's restricted to the type-check monad
472 tryTcLIE thing_inside
473   = do { ((errs, mb_r), lie) <- getLIE (tryTc thing_inside) ;
474          ifM (isJust mb_r) (extendLIEs lie) ;
475          return (errs, mb_r) }
476
477 tryTcLIE_ :: TcM r -> TcM r -> TcM r
478 -- (tryTcLIE_ r m) tries m; if it succeeds it returns it,
479 -- otherwise it returns r.  Any error messages added by m are discarded,
480 -- whether or not m succeeds.
481 tryTcLIE_ recover main
482   = do { (_msgs, mb_res) <- tryTcLIE main ;
483          case mb_res of
484            Just res -> return res
485            Nothing  -> recover }
486
487 checkNoErrs :: TcM r -> TcM r
488 -- (checkNoErrs m) succeeds iff m succeeds and generates no errors
489 -- If m fails then (checkNoErrsTc m) fails.
490 -- If m succeeds, it checks whether m generated any errors messages
491 --      (it might have recovered internally)
492 --      If so, it fails too.
493 -- Regardless, any errors generated by m are propagated to the enclosing context.
494 checkNoErrs main
495   = do { (msgs, mb_res) <- tryTcLIE main ;
496          addMessages msgs ;
497          case mb_res of
498            Just r  -> return r
499            Nothing -> failM
500    }
501
502 ifErrsM :: TcRn r -> TcRn r -> TcRn r
503 --      ifErrsM bale_out main
504 -- does 'bale_out' if there are errors in errors collection
505 -- otherwise does 'main'
506 ifErrsM bale_out normal
507  = do { errs_var <- getErrsVar ;
508         msgs <- readMutVar errs_var ;
509         dflags <- getDOpts ;
510         if errorsFound dflags msgs then
511            bale_out
512         else    
513            normal }
514
515 failIfErrsM :: TcRn ()
516 -- Useful to avoid error cascades
517 failIfErrsM = ifErrsM failM (return ())
518 \end{code}
519
520
521 %************************************************************************
522 %*                                                                      *
523         Context management and error message generation
524                     for the type checker
525 %*                                                                      *
526 %************************************************************************
527
528 \begin{code}
529 setErrCtxtM, addErrCtxtM :: (TidyEnv -> TcM (TidyEnv, Message)) -> TcM a -> TcM a
530 setErrCtxtM msg = updCtxt (\ msgs -> [msg])
531 addErrCtxtM msg = updCtxt (\ msgs -> msg : msgs)
532
533 setErrCtxt, addErrCtxt :: Message -> TcM a -> TcM a
534 setErrCtxt msg = setErrCtxtM (\env -> returnM (env, msg))
535 addErrCtxt msg = addErrCtxtM (\env -> returnM (env, msg))
536
537 popErrCtxt :: TcM a -> TcM a
538 popErrCtxt = updCtxt (\ msgs -> case msgs of { [] -> []; (m:ms) -> ms })
539
540 getErrCtxt :: TcM ErrCtxt
541 getErrCtxt = do { env <- getLclEnv ; return (tcl_ctxt env) }
542
543 -- Helper function for the above
544 updCtxt :: (ErrCtxt -> ErrCtxt) -> TcM a -> TcM a
545 updCtxt upd = updLclEnv (\ env@(TcLclEnv { tcl_ctxt = ctxt }) -> 
546                            env { tcl_ctxt = upd ctxt })
547
548 getInstLoc :: InstOrigin -> TcM InstLoc
549 getInstLoc origin
550   = do { loc <- getSrcLocM ; env <- getLclEnv ;
551          return (InstLoc origin loc (tcl_ctxt env)) }
552
553 addInstCtxt :: InstLoc -> TcM a -> TcM a
554 -- Add the SrcLoc and context from the first Inst in the list
555 --      (they all have similar locations)
556 addInstCtxt (InstLoc _ src_loc ctxt) thing_inside
557   = addSrcLoc src_loc (updCtxt (\ old_ctxt -> ctxt) thing_inside)
558 \end{code}
559
560     The addErrTc functions add an error message, but do not cause failure.
561     The 'M' variants pass a TidyEnv that has already been used to
562     tidy up the message; we then use it to tidy the context messages
563
564 \begin{code}
565 addErrTc :: Message -> TcM ()
566 addErrTc err_msg = addErrTcM (emptyTidyEnv, err_msg)
567
568 addErrsTc :: [Message] -> TcM ()
569 addErrsTc err_msgs = mappM_ addErrTc err_msgs
570
571 addErrTcM :: (TidyEnv, Message) -> TcM ()
572 addErrTcM (tidy_env, err_msg)
573   = do { ctxt <- getErrCtxt ;
574          loc  <- getSrcLocM ;
575          add_err_tcm tidy_env err_msg loc ctxt }
576 \end{code}
577
578 The failWith functions add an error message and cause failure
579
580 \begin{code}
581 failWithTc :: Message -> TcM a               -- Add an error message and fail
582 failWithTc err_msg 
583   = addErrTc err_msg >> failM
584
585 failWithTcM :: (TidyEnv, Message) -> TcM a   -- Add an error message and fail
586 failWithTcM local_and_msg
587   = addErrTcM local_and_msg >> failM
588
589 checkTc :: Bool -> Message -> TcM ()         -- Check that the boolean is true
590 checkTc True  err = returnM ()
591 checkTc False err = failWithTc err
592 \end{code}
593
594         Warnings have no 'M' variant, nor failure
595
596 \begin{code}
597 addWarnTc :: Message -> TcM ()
598 addWarnTc msg
599  = do { ctxt <- getErrCtxt ;
600         ctxt_msgs <- do_ctxt emptyTidyEnv ctxt ;
601         addWarn (vcat (msg : ctxt_to_use ctxt_msgs)) }
602
603 warnTc :: Bool -> Message -> TcM ()
604 warnTc warn_if_true warn_msg
605   | warn_if_true = addWarnTc warn_msg
606   | otherwise    = return ()
607 \end{code}
608
609         Helper functions
610
611 \begin{code}
612 add_err_tcm tidy_env err_msg loc ctxt
613  = do { ctxt_msgs <- do_ctxt tidy_env ctxt ;
614         addErrAt loc (vcat (err_msg : ctxt_to_use ctxt_msgs)) }
615
616 do_ctxt tidy_env []
617  = return []
618 do_ctxt tidy_env (c:cs)
619  = do { (tidy_env', m) <- c tidy_env  ;
620         ms             <- do_ctxt tidy_env' cs  ;
621         return (m:ms) }
622
623 ctxt_to_use ctxt | opt_PprStyle_Debug = ctxt
624                  | otherwise          = take 3 ctxt
625 \end{code}
626
627 %************************************************************************
628 %*                                                                      *
629              Type constraints (the so-called LIE)
630 %*                                                                      *
631 %************************************************************************
632
633 \begin{code}
634 getLIEVar :: TcM (TcRef LIE)
635 getLIEVar = do { env <- getLclEnv; return (tcl_lie env) }
636
637 setLIEVar :: TcRef LIE -> TcM a -> TcM a
638 setLIEVar lie_var = updLclEnv (\ env -> env { tcl_lie = lie_var })
639
640 getLIE :: TcM a -> TcM (a, [Inst])
641 -- (getLIE m) runs m, and returns the type constraints it generates
642 getLIE thing_inside
643   = do { lie_var <- newMutVar emptyLIE ;
644          res <- updLclEnv (\ env -> env { tcl_lie = lie_var }) 
645                           thing_inside ;
646          lie <- readMutVar lie_var ;
647          return (res, lieToList lie) }
648
649 extendLIE :: Inst -> TcM ()
650 extendLIE inst
651   = do { lie_var <- getLIEVar ;
652          lie <- readMutVar lie_var ;
653          writeMutVar lie_var (inst `consLIE` lie) }
654
655 extendLIEs :: [Inst] -> TcM ()
656 extendLIEs [] 
657   = returnM ()
658 extendLIEs insts
659   = do { lie_var <- getLIEVar ;
660          lie <- readMutVar lie_var ;
661          writeMutVar lie_var (mkLIE insts `plusLIE` lie) }
662 \end{code}
663
664 \begin{code}
665 setLclTypeEnv :: TcLclEnv -> TcM a -> TcM a
666 -- Set the local type envt, but do *not* disturb other fields,
667 -- notably the lie_var
668 setLclTypeEnv lcl_env thing_inside
669   = updLclEnv upd thing_inside
670   where
671     upd env = env { tcl_env = tcl_env lcl_env,
672                     tcl_tyvars = tcl_tyvars lcl_env }
673 \end{code}
674
675
676 %************************************************************************
677 %*                                                                      *
678              Template Haskell context
679 %*                                                                      *
680 %************************************************************************
681
682 \begin{code}
683 getStage :: TcM ThStage
684 getStage = do { env <- getLclEnv; return (tcl_th_ctxt env) }
685
686 setStage :: ThStage -> TcM a -> TcM a 
687 setStage s = updLclEnv (\ env -> env { tcl_th_ctxt = s })
688 \end{code}
689
690
691 %************************************************************************
692 %*                                                                      *
693              Arrow context
694 %*                                                                      *
695 %************************************************************************
696
697 \begin{code}
698 popArrowBinders :: TcM a -> TcM a       -- Move to the left of a (-<); see comments in TcRnTypes
699 popArrowBinders 
700   = updLclEnv (\ env -> env { tcl_arrow_ctxt = pop (tcl_arrow_ctxt env)  })
701   where
702     pop (ArrCtxt {proc_level = curr_lvl, proc_banned = banned})
703         = ASSERT( not (curr_lvl `elem` banned) )
704           ArrCtxt {proc_level = curr_lvl, proc_banned = curr_lvl : banned}
705
706 getBannedProcLevels :: TcM [ProcLevel]
707   = do { env <- getLclEnv; return (proc_banned (tcl_arrow_ctxt env)) }
708
709 incProcLevel :: TcM a -> TcM a
710 incProcLevel 
711   = updLclEnv (\ env -> env { tcl_arrow_ctxt = inc (tcl_arrow_ctxt env) })
712   where
713     inc ctxt = ctxt { proc_level = proc_level ctxt + 1 }
714 \end{code}
715
716
717 %************************************************************************
718 %*                                                                      *
719              Stuff for the renamer's local env
720 %*                                                                      *
721 %************************************************************************
722
723 \begin{code}
724 getLocalRdrEnv :: RnM LocalRdrEnv
725 getLocalRdrEnv = do { env <- getLclEnv; return (tcl_rdr env) }
726
727 setLocalRdrEnv :: LocalRdrEnv -> RnM a -> RnM a
728 setLocalRdrEnv rdr_env thing_inside 
729   = updLclEnv (\env -> env {tcl_rdr = rdr_env}) thing_inside
730 \end{code}
731
732
733 %************************************************************************
734 %*                                                                      *
735              Stuff for interface decls
736 %*                                                                      *
737 %************************************************************************
738
739 \begin{code}
740 initIfaceTcRn :: IfG a -> TcRn a
741 initIfaceTcRn thing_inside
742   = do  { tcg_env <- getGblEnv 
743         ; let { if_env = IfGblEnv { 
744                         if_rec_types = Just (tcg_mod tcg_env, get_type_env),
745                         if_is_boot   = imp_dep_mods (tcg_imports tcg_env) }
746               ; get_type_env = readMutVar (tcg_type_env_var tcg_env) }
747         ; setEnvs (if_env, ()) thing_inside }
748
749 initIfaceExtCore :: IfL a -> TcRn a
750 initIfaceExtCore thing_inside
751   = do  { tcg_env <- getGblEnv 
752         ; let { mod = tcg_mod tcg_env
753               ; if_env = IfGblEnv { 
754                         if_rec_types = Just (mod, return (tcg_type_env tcg_env)), 
755                         if_is_boot   = imp_dep_mods (tcg_imports tcg_env) }
756               ; if_lenv = IfLclEnv { if_mod     = moduleName mod,
757                                      if_tv_env  = emptyOccEnv,
758                                      if_id_env  = emptyOccEnv }
759           }
760         ; setEnvs (if_env, if_lenv) thing_inside }
761
762 initIfaceCheck :: HscEnv -> IfG a -> IO a
763 -- Used when checking the up-to-date-ness of the old Iface
764 -- Initialise the environment with no useful info at all
765 initIfaceCheck hsc_env do_this
766  = do   { let { gbl_env = IfGblEnv { if_is_boot   = emptyModuleEnv,
767                                      if_rec_types = Nothing } ;
768            }
769         ; initTcRnIf 'i' hsc_env gbl_env () do_this
770     }
771
772 initIfaceTc :: HscEnv -> ModIface 
773             -> (TcRef TypeEnv -> IfL a) -> IO a
774 -- Used when type-checking checking an up-to-date interface file
775 -- No type envt from the current module, but we do know the module dependencies
776 initIfaceTc hsc_env iface do_this
777  = do   { tc_env_var <- newIORef emptyTypeEnv
778         ; let { gbl_env = IfGblEnv { if_is_boot   = mkModDeps (dep_mods (mi_deps iface)),
779                                      if_rec_types = Just (mod, readMutVar tc_env_var) } ;
780               ; if_lenv = IfLclEnv { if_mod     = moduleName mod,
781                                      if_tv_env  = emptyOccEnv,
782                                      if_id_env  = emptyOccEnv }
783            }
784         ; initTcRnIf 'i' hsc_env gbl_env if_lenv (do_this tc_env_var)
785     }
786   where
787     mod = mi_module iface
788
789 initIfaceRules :: HscEnv -> ModGuts -> IfG a -> IO a
790 -- Used when sucking in new Rules in SimplCore
791 -- We have available the type envt of the module being compiled, and we must use it
792 initIfaceRules hsc_env guts do_this
793  = do   { let {
794              is_boot = mkModDeps (dep_mods (mg_deps guts))
795                         -- Urgh!  But we do somehow need to get the info
796                         -- on whether (for this particular compilation) we should
797                         -- import a hi-boot file or not.
798            ; type_info = (mg_module guts, return (mg_types guts))
799            ; gbl_env = IfGblEnv { if_is_boot   = is_boot,
800                                   if_rec_types = Just type_info } ;
801            }
802
803         -- Run the thing; any exceptions just bubble out from here
804         ; initTcRnIf 'i' hsc_env gbl_env () do_this
805     }
806
807 initIfaceLcl :: ModuleName -> IfL a -> IfM lcl a
808 initIfaceLcl mod thing_inside 
809   = setLclEnv (IfLclEnv { if_mod      = mod,
810                            if_tv_env  = emptyOccEnv,
811                            if_id_env  = emptyOccEnv })
812               thing_inside
813
814
815 --------------------
816 forkM_maybe :: SDoc -> IfL a -> IfL (Maybe a)
817 -- Run thing_inside in an interleaved thread.  
818 -- It shares everything with the parent thread, so this is DANGEROUS.  
819 --
820 -- It returns Nothing if the computation fails
821 -- 
822 -- It's used for lazily type-checking interface
823 -- signatures, which is pretty benign
824
825 forkM_maybe doc thing_inside
826  = do { unsafeInterleaveM $
827         do { traceIf (text "Starting fork {" <+> doc)
828            ; mb_res <- tryM thing_inside ;
829              case mb_res of
830                 Right r  -> do  { traceIf (text "} ending fork" <+> doc)
831                                 ; return (Just r) }
832                 Left exn -> do {
833
834                     -- Bleat about errors in the forked thread, if -ddump-if-trace is on
835                     -- Otherwise we silently discard errors. Errors can legitimately
836                     -- happen when compiling interface signatures (see tcInterfaceSigs)
837                       ifOptM Opt_D_dump_if_trace 
838                              (print_errs (hang (text "forkM failed:" <+> doc)
839                                              4 (text (show exn))))
840
841                     ; traceIf (text "} ending fork (badly)" <+> doc)
842                     ; return Nothing }
843         }}
844   where
845     print_errs sdoc = ioToIOEnv (printErrs (sdoc defaultErrStyle))
846
847 forkM :: SDoc -> IfL a -> IfL a
848 forkM doc thing_inside
849  = do   { mb_res <- forkM_maybe doc thing_inside
850         ; return (case mb_res of 
851                         Nothing -> pprPanic "forkM" doc
852                         Just r  -> r) }
853 \end{code}