Don't import FastString in HsVersions.h
[ghc-hetmet.git] / compiler / deSugar / DsMonad.lhs
index acdecfe..10cd28a 100644 (file)
@@ -1,13 +1,16 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-\section[DsMonad]{@DsMonad@: monadery used in desugaring}
+
+@DsMonad@: monadery used in desugaring
 
 \begin{code}
 module DsMonad (
-       DsM, mappM, mapAndUnzipM,
-       initDs, initDsTc, returnDs, thenDs, listDs, fixDs, mapAndUnzipDs, 
-       foldlDs, foldrDs,
+       DsM, mapM, mapAndUnzipM,
+       initDs, initDsTc, fixDs,
+       foldlM, foldrM, ifOptM,
+       Applicative(..),(<$>),
 
        newTyVarsDs, newLocalName,
        duplicateLocalDs, newSysLocalDs, newSysLocalsDs, newUniqueId,
@@ -16,8 +19,9 @@ module DsMonad (
        getModuleDs,
        newUnique, 
        UniqSupply, newUniqueSupply,
-       getDOptsDs,
+       getDOptsDs, getGhcModeDs, doptDs,
        dsLookupGlobal, dsLookupGlobalId, dsLookupTyCon, dsLookupDataCon,
+        dsLookupClass,
 
        DsMetaEnv, DsMetaVal(..), dsLookupMetaEnv, dsExtendMetaEnv,
 
@@ -26,38 +30,38 @@ module DsMonad (
 
        -- Data types
        DsMatchContext(..),
-       EquationInfo(..), MatchResult(..), DsWrapper, idWrapper,
+       EquationInfo(..), MatchResult(..), DsWrapper, idDsWrapper,
        CanItFail(..), orFail
     ) where
 
 #include "HsVersions.h"
 
 import TcRnMonad
-import CoreSyn         ( CoreExpr )
-import HsSyn           ( HsExpr, HsMatchContext, Pat )
-import TcIface         ( tcIfaceGlobal )
-import RdrName         ( GlobalRdrEnv )
-import HscTypes                ( TyThing(..), TypeEnv, HscEnv(..), 
-                         tyThingId, tyThingTyCon, tyThingDataCon, mkPrintUnqualified )
-import Bag             ( emptyBag, snocBag )
-import DataCon         ( DataCon )
-import TyCon           ( TyCon )
-import Id              ( mkSysLocal, setIdUnique, Id )
-import Module          ( Module )
-import Var             ( TyVar, setTyVarUnique )
+import CoreSyn
+import HsSyn
+import TcIface
+import RdrName
+import HscTypes
+import Bag
+import DataCon
+import TyCon
+import Class
+import Id
+import Module
+import Var
 import Outputable
-import SrcLoc          ( noSrcSpan, SrcSpan )
-import Type             ( Type )
-import UniqSupply      ( UniqSupply, uniqsFromSupply )
-import Name            ( Name, nameOccName )
+import SrcLoc
+import Type
+import UniqSupply
+import Name
 import NameEnv
-import OccName          ( occNameFS )
-import DynFlags        ( DynFlags )
-import ErrUtils                ( Messages, mkWarnMsg, mkErrMsg, 
-                         printErrorsAndWarnings, errorsFound )
-import DATA_IOREF      ( newIORef, readIORef )
+import OccName
+import DynFlags
+import ErrUtils
+import MonadUtils
+import FastString
 
-infixr 9 `thenDs`
+import Data.IORef
 \end{code}
 
 %************************************************************************
@@ -73,12 +77,12 @@ data DsMatchContext
   deriving ()
 
 data EquationInfo
-  = EqnInfo { eqn_wrap :: DsWrapper,   -- Bindings
-             eqn_pats :: [Pat Id],     -- The patterns for an eqn
+  = EqnInfo { eqn_pats :: [Pat Id],            -- The patterns for an eqn
              eqn_rhs  :: MatchResult } -- What to do after match
 
 type DsWrapper = CoreExpr -> CoreExpr
-idWrapper e = e
+idDsWrapper :: DsWrapper
+idDsWrapper e = e
 
 -- The semantics of (match vs (EqnInfo wrap pats rhs)) is the MatchResult
 --     \fail. wrap (case vs of { pats -> rhs fail })
@@ -96,8 +100,9 @@ data MatchResult
 
 data CanItFail = CanFail | CantFail
 
+orFail :: CanItFail -> CanItFail -> CanItFail
 orFail CantFail CantFail = CantFail
-orFail _        _       = CanFail
+orFail _        _        = CanFail
 \end{code}
 
 
@@ -114,14 +119,8 @@ presumably include source-file location information:
 type DsM result = TcRnIf DsGblEnv DsLclEnv result
 
 -- Compatibility functions
+fixDs :: (a -> DsM a) -> DsM a
 fixDs    = fixM
-thenDs   = thenM
-returnDs = returnM
-listDs   = sequenceM
-foldlDs  = foldlM
-foldrDs  = foldrM
-mapAndUnzipDs = mapAndUnzipM
-
 
 type DsWarning = (SrcSpan, SDoc)
        -- Not quite the same as a WarnMsg, we have an SDoc here 
@@ -161,14 +160,14 @@ initDs  :: HscEnv
 
 initDs hsc_env mod rdr_env type_env thing_inside
   = do         { msg_var <- newIORef (emptyBag, emptyBag)
-       ; let (ds_gbl_env, ds_lcl_env) = mkDsEnvs mod rdr_env type_env msg_var
+       ; let dflags = hsc_dflags hsc_env
+        ; (ds_gbl_env, ds_lcl_env) <- mkDsEnvs dflags mod rdr_env type_env msg_var
 
        ; either_res <- initTcRnIf 'd' hsc_env ds_gbl_env ds_lcl_env $
                        tryM thing_inside       -- Catch exceptions (= errors during desugaring)
 
        -- Display any errors and warnings 
        -- Note: if -Werror is used, we don't signal an error here.
-       ; let dflags = hsc_dflags hsc_env
        ; msgs <- readIORef msg_var
         ; printErrorsAndWarnings dflags msgs 
 
@@ -187,23 +186,26 @@ initDsTc thing_inside
   = do { this_mod <- getModule
        ; tcg_env  <- getGblEnv
        ; msg_var  <- getErrsVar
+        ; dflags   <- getDOpts
        ; let type_env = tcg_type_env tcg_env
              rdr_env  = tcg_rdr_env tcg_env
-       ; setEnvs (mkDsEnvs this_mod rdr_env type_env msg_var) thing_inside }
-
-mkDsEnvs :: Module -> GlobalRdrEnv -> TypeEnv
-        -> IORef Messages -> (DsGblEnv, DsLclEnv)
-mkDsEnvs mod rdr_env type_env msg_var
-  = (gbl_env, lcl_env)
-  where
-    if_genv = IfGblEnv { if_rec_types = Just (mod, return type_env) }
-    if_lenv = mkIfLclEnv mod (ptext SLIT("GHC error in desugarer lookup in") <+> ppr mod)
-    gbl_env = DsGblEnv { ds_mod = mod, 
-                        ds_if_env = (if_genv, if_lenv),
-                        ds_unqual = mkPrintUnqualified rdr_env,
-                        ds_msgs = msg_var }
-    lcl_env = DsLclEnv { ds_meta = emptyNameEnv, 
-                        ds_loc = noSrcSpan }
+        ; ds_envs <- liftIO $ mkDsEnvs dflags this_mod rdr_env type_env msg_var
+       ; setEnvs ds_envs thing_inside }
+
+mkDsEnvs :: DynFlags -> Module -> GlobalRdrEnv -> TypeEnv -> IORef Messages -> IO (DsGblEnv, DsLclEnv)
+mkDsEnvs dflags mod rdr_env type_env msg_var
+  = do -- TODO: unnecessarily monadic
+       let     if_genv = IfGblEnv { if_rec_types = Just (mod, return type_env) }
+               if_lenv = mkIfLclEnv mod (ptext SLIT("GHC error in desugarer lookup in") <+> ppr mod)
+               gbl_env = DsGblEnv { ds_mod = mod, 
+                                   ds_if_env = (if_genv, if_lenv),
+                                   ds_unqual = mkPrintUnqualified dflags rdr_env,
+                                   ds_msgs = msg_var}
+               lcl_env = DsLclEnv { ds_meta = emptyNameEnv, 
+                                   ds_loc = noSrcSpan }
+
+       return (gbl_env, lcl_env)
+
 \end{code}
 
 %************************************************************************
@@ -220,33 +222,34 @@ it easier to read debugging output.
 \begin{code}
 -- Make a new Id with the same print name, but different type, and new unique
 newUniqueId :: Name -> Type -> DsM Id
-newUniqueId id ty
-  = newUnique  `thenDs` \ uniq ->
-    returnDs (mkSysLocal (occNameFS (nameOccName id)) uniq ty)
+newUniqueId id ty = do
+    uniq <- newUnique
+    return (mkSysLocal (occNameFS (nameOccName id)) uniq ty)
 
 duplicateLocalDs :: Id -> DsM Id
-duplicateLocalDs old_local 
-  = newUnique  `thenDs` \ uniq ->
-    returnDs (setIdUnique old_local uniq)
+duplicateLocalDs old_local = do
+    uniq <- newUnique
+    return (setIdUnique old_local uniq)
 
 newSysLocalDs, newFailLocalDs :: Type -> DsM Id
-newSysLocalDs ty
-  = newUnique  `thenDs` \ uniq ->
-    returnDs (mkSysLocal FSLIT("ds") uniq ty)
+newSysLocalDs ty = do
+    uniq <- newUnique
+    return (mkSysLocal FSLIT("ds") uniq ty)
 
-newSysLocalsDs tys = mappM newSysLocalDs tys
+newSysLocalsDs :: [Type] -> DsM [Id]
+newSysLocalsDs tys = mapM newSysLocalDs tys
 
-newFailLocalDs ty 
-  = newUnique  `thenDs` \ uniq ->
-    returnDs (mkSysLocal FSLIT("fail") uniq ty)
+newFailLocalDs ty = do
+    uniq <- newUnique
+    return (mkSysLocal FSLIT("fail") uniq ty)
        -- The UserLocal bit just helps make the code a little clearer
 \end{code}
 
 \begin{code}
 newTyVarsDs :: [TyVar] -> DsM [TyVar]
-newTyVarsDs tyvar_tmpls 
-  = newUniqueSupply    `thenDs` \ uniqs ->
-    returnDs (zipWith setTyVarUnique tyvar_tmpls (uniqsFromSupply uniqs))
+newTyVarsDs tyvar_tmpls = do
+    uniqs <- newUniqueSupply
+    return (zipWith setTyVarUnique tyvar_tmpls (uniqsFromSupply uniqs))
 \end{code}
 
 We can also reach out and either set/grab location information from
@@ -256,6 +259,12 @@ the @SrcSpan@ being carried around.
 getDOptsDs :: DsM DynFlags
 getDOptsDs = getDOpts
 
+doptDs :: DynFlag -> TcRnIf gbl lcl Bool
+doptDs = doptM
+
+getGhcModeDs :: DsM GhcMode
+getGhcModeDs =  getDOptsDs >>= return . ghcMode
+
 getModuleDs :: DsM Module
 getModuleDs = do { env <- getGblEnv; return (ds_mod env) }
 
@@ -293,18 +302,19 @@ dsLookupGlobal name
 
 dsLookupGlobalId :: Name -> DsM Id
 dsLookupGlobalId name 
-  = dsLookupGlobal name                `thenDs` \ thing ->
-    returnDs (tyThingId thing)
+  = tyThingId <$> dsLookupGlobal name
 
 dsLookupTyCon :: Name -> DsM TyCon
 dsLookupTyCon name
-  = dsLookupGlobal name                `thenDs` \ thing ->
-    returnDs (tyThingTyCon thing)
+  = tyThingTyCon <$> dsLookupGlobal name
 
 dsLookupDataCon :: Name -> DsM DataCon
 dsLookupDataCon name
-  = dsLookupGlobal name                `thenDs` \ thing ->
-    returnDs (tyThingDataCon thing)
+  = tyThingDataCon <$> dsLookupGlobal name
+
+dsLookupClass :: Name -> DsM Class
+dsLookupClass name
+  = tyThingClass <$> dsLookupGlobal name
 \end{code}
 
 \begin{code}
@@ -315,5 +325,3 @@ dsExtendMetaEnv :: DsMetaEnv -> DsM a -> DsM a
 dsExtendMetaEnv menv thing_inside
   = updLclEnv (\env -> env { ds_meta = ds_meta env `plusNameEnv` menv }) thing_inside
 \end{code}
-
-