[project @ 2001-01-25 17:54:24 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcMonad.lhs
index 21a8d89..3e3322e 100644 (file)
@@ -2,7 +2,7 @@
 module TcMonad(
        TcType, 
        TcTauType, TcPredType, TcThetaType, TcRhoType,
-       TcTyVar, TcTyVarSet,
+       TcTyVar, TcTyVarSet, TcClassContext,
        TcKind,
 
        TcM, NF_TcM, TcDown, TcEnv, 
@@ -21,12 +21,14 @@ module TcMonad(
        listNF_Tc, mapAndUnzipNF_Tc, mapBagNF_Tc,
 
        checkTc, checkTcM, checkMaybeTc, checkMaybeTcM, 
-       failTc, failWithTc, addErrTc, addErrsTc, warnTc, recoverTc, checkNoErrsTc, recoverNF_Tc, discardErrsTc,
+       failTc, failWithTc, addErrTc, addErrsTc, warnTc, 
+       recoverTc, checkNoErrsTc, recoverNF_Tc, discardErrsTc,
        addErrTcM, addInstErrTcM, failWithTcM,
 
        tcGetEnv, tcSetEnv,
        tcGetDefaultTys, tcSetDefaultTys,
-       tcGetUnique, tcGetUniques, tcGetDFunUniq,
+       tcGetUnique, tcGetUniques, 
+       doptsTc, getDOptsTc,
 
        tcAddSrcLoc, tcGetSrcLoc, tcGetInstLoc,
        tcAddErrCtxtM, tcSetErrCtxtM,
@@ -49,24 +51,22 @@ import RnHsSyn              ( RenamedPat, RenamedArithSeqInfo, RenamedHsExpr, RenamedHsOverL
 import Type            ( Type, Kind, PredType, ThetaType, RhoType, TauType,
                        )
 import ErrUtils                ( addShortErrLocLine, addShortWarnLocLine, ErrMsg, Message, WarnMsg )
-import CmdLineOpts      ( opt_PprStyle_Debug )
 
 import Bag             ( Bag, emptyBag, isEmptyBag,
                          foldBag, unitBag, unionBags, snocBag )
-import Class           ( Class )
+import Class           ( Class, ClassContext )
 import Name            ( Name )
 import Var             ( Id, TyVar, newMutTyVar, newSigTyVar, readMutTyVar, writeMutTyVar )
 import VarEnv          ( TidyEnv, emptyTidyEnv )
 import VarSet          ( TyVarSet )
-import UniqSupply      ( UniqSupply, uniqFromSupply, uniqsFromSupply, splitUniqSupply,
+import UniqSupply      ( UniqSupply, uniqFromSupply, uniqsFromSupply, 
+                         splitUniqSupply, mkSplitUniqSupply,
                          UniqSM, initUs_ )
 import SrcLoc          ( SrcLoc, noSrcLoc )
-import FiniteMap       ( FiniteMap, lookupFM, addToFM, emptyFM )
-import UniqFM          ( UniqFM, emptyUFM )
+import UniqFM          ( emptyUFM )
 import Unique          ( Unique )
-import BasicTypes      ( Unused )
+import CmdLineOpts
 import Outputable
-import FastString      ( FastString )
 
 import IOExts          ( IORef, newIORef, readIORef, writeIORef,
                          unsafeInterleaveIO, fixIO
@@ -93,11 +93,12 @@ type TcType = Type          -- A TcType can have mutable type variables
        -- a cannot occur inside a MutTyVar in T; that is,
        -- T is "flattened" before quantifying over a
 
-type TcPredType  = PredType
-type TcThetaType = ThetaType
-type TcRhoType   = RhoType
-type TcTauType   = TauType
-type TcKind      = TcType
+type TcClassContext = ClassContext
+type TcPredType     = PredType
+type TcThetaType    = ThetaType
+type TcRhoType      = RhoType
+type TcTauType      = TauType
+type TcKind         = TcType
 \end{code}
 
 
@@ -110,9 +111,6 @@ type TcKind      = TcType
 \begin{code}
 type NF_TcM r =  TcDown -> TcEnv -> IO r       -- Can't raise UserError
 type TcM    r =  TcDown -> TcEnv -> IO r       -- Can raise UserError
-       -- ToDo: nuke the 's' part
-       -- The difference between the two is
-       -- now for documentation purposes only
 
 type Either_TcM r =  TcDown -> TcEnv -> IO r   -- Either NF_TcM or TcM
        -- Used only in this file for type signatures which
@@ -123,26 +121,26 @@ type TcRef a = IORef a
 \end{code}
 
 \begin{code}
-initTc :: TcEnv
-       -> SrcLoc
+
+initTc :: DynFlags 
+       -> TcEnv
        -> TcM r
-       -> IO (Maybe r, (Bag ErrMsg, Bag WarnMsg))
+       -> IO (Maybe r, (Bag WarnMsg, Bag ErrMsg))
 
-initTc tc_env src_loc do_this
+initTc dflags tc_env do_this
   = do {
       us       <- mkSplitUniqSupply 'a' ;
       us_var   <- newIORef us ;
-      dfun_var <- newIORef emptyFM ;
       errs_var <- newIORef (emptyBag,emptyBag) ;
       tvs_var  <- newIORef emptyUFM ;
 
       let
-          init_down = TcDown [] us_var dfun_var
-                            src_loc
-                            [] errs_var
+          init_down = TcDown { tc_dflags = dflags, tc_def = [],
+                              tc_us = us_var, tc_loc = noSrcLoc,
+                              tc_ctxt = [], tc_errs = errs_var }
       ;
 
-      maybe_res <- catch (do {  res <- do_this init_down env ;
+      maybe_res <- catch (do {  res <- do_this init_down tc_env ;
                                return (Just res)})
                         (\_ -> return Nothing) ;
         
@@ -252,7 +250,7 @@ We throw away any error messages!
 
 \begin{code}
 forkNF_Tc :: NF_TcM r -> NF_TcM r
-forkNF_Tc m (TcDown deflts u_var df_var src_loc err_cxt err_var) env
+forkNF_Tc m down@(TcDown { tc_us = u_var }) env
   = do
        -- Get a fresh unique supply
        us <- readIORef u_var
@@ -262,8 +260,7 @@ forkNF_Tc m (TcDown deflts u_var df_var src_loc err_cxt err_var) env
        unsafeInterleaveIO (do {
                us_var'  <- newIORef us2 ;
                err_var' <- newIORef (emptyBag,emptyBag) ;
-               tv_var'  <- newIORef emptyUFM ;
-               let { down' = TcDown deflts us_var' df_var src_loc err_cxt err_var' } ;
+               let { down' = down { tc_us = us_var', tc_errs = err_var' } };
                m down' env
                        -- ToDo: optionally dump any error messages
                })
@@ -271,7 +268,7 @@ forkNF_Tc m (TcDown deflts u_var df_var src_loc err_cxt err_var) env
 
 \begin{code}
 traceTc :: SDoc -> NF_TcM ()
-traceTc doc down env = printErrs doc
+traceTc doc down env = printDump doc
 
 ioToTc :: IO a -> NF_TcM a
 ioToTc io down env = io
@@ -303,7 +300,7 @@ addErrTc err_msg = addErrTcM (emptyTidyEnv, err_msg)
 
 addErrsTc :: [Message] -> NF_TcM ()
 addErrsTc []      = returnNF_Tc ()
-addErrsTc err_msgs = listNF_Tc_ (map addErrTc err_msgs)        `thenNF_Tc_` returnNF_Tc ()
+addErrsTc err_msgs = listNF_Tc (map addErrTc err_msgs) `thenNF_Tc_` returnNF_Tc ()
 
 -- The 'M' variants do the TidyEnv bit
 failWithTcM :: (TidyEnv, Message) -> TcM a     -- Add an error message and fail
@@ -560,20 +557,6 @@ uniqSMToTcM m down env
 \end{code}
 
 
-\begin{code}
-tcGetDFunUniq :: String -> NF_TcM Int
-tcGetDFunUniq key down env
-  = do dfun_supply <- readIORef d_var
-       let uniq = case lookupFM dfun_supply key of
-                     Just x  -> x+1
-                     Nothing -> 0
-       let dfun_supply' = addToFM dfun_supply key uniq
-       writeIORef d_var dfun_supply'
-       return uniq
-  where
-    d_var = getDFunSupplyVar down
-\end{code}
-
 
 %************************************************************************
 %*                                                                     *
@@ -583,53 +566,46 @@ tcGetDFunUniq key down env
 
 \begin{code}
 data TcDown
-  = TcDown
-       [Type]                  -- Types used for defaulting
-
-       (TcRef UniqSupply)      -- Unique supply
-       (TcRef DFunNameSupply)  -- Name supply for dictionary function names
-
-       SrcLoc                  -- Source location
-       ErrCtxt                 -- Error context
-       (TcRef (Bag WarnMsg, Bag ErrMsg))
+   = TcDown {
+        tc_dflags :: DynFlags,
+       tc_def    :: [Type],                    -- Types used for defaulting
+       tc_us     :: (TcRef UniqSupply),        -- Unique supply
+       tc_loc    :: SrcLoc,                    -- Source location
+       tc_ctxt   :: ErrCtxt,                   -- Error context
+       tc_errs   :: (TcRef (Bag WarnMsg, Bag ErrMsg))
+   }
 
 type ErrCtxt = [TidyEnv -> NF_TcM (TidyEnv, Message)]  
                        -- Innermost first.  Monadic so that we have a chance
                        -- to deal with bound type variables just before error
                        -- message construction
-
-type DFunNameSupply = FiniteMap String Int
-       -- This is used as a name supply for dictionary functions
-       -- From the inst decl we derive a string, usually by glomming together
-       -- the class and tycon name -- but it doesn't matter exactly how;
-       -- this map then gives a unique int for each inst decl with that
-       -- string.  (In Haskell 98 there can only be one,
-       -- but not so in more extended versions; also class CC type T
-       -- and class C type TT might both give the string CCT
-       --      
-       -- We could just use one Int for all the instance decls, but this
-       -- way the uniques change less when you add an instance decl,   
-       -- hence less recompilation
 \end{code}
 
 -- These selectors are *local* to TcMonad.lhs
 
 \begin{code}
-getTcErrs (TcDown def us ds loc ctxt errs)      = errs
-setTcErrs (TcDown def us ds loc ctxt _   ) errs = TcDown def us ds loc ctxt errs
+getTcErrs (TcDown{tc_errs=errs}) = errs
+setTcErrs down errs = down{tc_errs=errs}
+
+getDefaultTys (TcDown{tc_def=def}) = def
+setDefaultTys down def = down{tc_def=def}
 
-getDefaultTys (TcDown def us ds loc ctxt errs)     = def
-setDefaultTys (TcDown _   us ds loc ctxt errs) def = TcDown def us ds loc ctxt errs
+getLoc (TcDown{tc_loc=loc}) = loc
+setLoc down loc = down{tc_loc=loc}
 
-getLoc (TcDown def us ds loc ctxt errs)     = loc
-setLoc (TcDown def us ds _   ctxt errs) loc = TcDown def us ds loc ctxt errs
+getUniqSupplyVar (TcDown{tc_us=us}) = us
 
-getUniqSupplyVar (TcDown def us ds loc ctxt errs) = us
-getDFunSupplyVar (TcDown def us ds loc ctxt errs) = ds
+getErrCtxt (TcDown{tc_ctxt=ctxt}) = ctxt
+setErrCtxt down msg = down{tc_ctxt=[msg]}
+addErrCtxt down msg = down{tc_ctxt = msg : tc_ctxt down}
 
-setErrCtxt (TcDown def us ds loc ctxt errs) msg = TcDown def us ds loc [msg]      errs
-addErrCtxt (TcDown def us ds loc ctxt errs) msg = TcDown def us ds loc (msg:ctxt) errs
-getErrCtxt (TcDown def us ds loc ctxt errs)     = ctxt
+doptsTc :: DynFlag -> TcM Bool
+doptsTc dflag (TcDown{tc_dflags=dflags}) env_down
+   = return (dopt dflag dflags)
+
+getDOptsTc :: TcM DynFlags
+getDOptsTc (TcDown{tc_dflags=dflags}) env_down
+   = return dflags
 \end{code}
 
 
@@ -683,6 +659,9 @@ type InstLoc = (InstOrigin, SrcLoc, ErrCtxt)
 data InstOrigin
   = OccurrenceOf Id            -- Occurrence of an overloaded identifier
 
+  | IPOcc Name                 -- Occurrence of an implicit parameter
+  | IPBind Name                        -- Binding site of an implicit parameter
+
   | RecordUpdOrigin
 
   | DataDeclOrigin             -- Typechecking a data declaration
@@ -734,6 +713,10 @@ pprInstLoc (orig, locn, ctxt)
   where
     pp_orig (OccurrenceOf id)
        = hsep [ptext SLIT("use of"), quotes (ppr id)]
+    pp_orig (IPOcc name)
+       = hsep [ptext SLIT("use of implicit parameter"), quotes (char '?' <> ppr name)]
+    pp_orig (IPBind name)
+       = hsep [ptext SLIT("binding for implicit parameter"), quotes (char '?' <> ppr name)]
     pp_orig (LiteralOrigin lit)
        = hsep [ptext SLIT("the literal"), quotes (ppr lit)]
     pp_orig (PatOrigin pat)