[project @ 1996-07-19 18:36:04 by partain]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcMonad.lhs
index 5614273..e595a83 100644 (file)
@@ -1,6 +1,8 @@
 \begin{code}
+#include "HsVersions.h"
+
 module TcMonad(
-       TcM(..), NF_TcM(..), TcDown, TcEnv, 
+       SYN_IE(TcM), SYN_IE(NF_TcM), TcDown, TcEnv, 
        SST_R, FSST_R,
 
        initTc,
@@ -8,7 +10,7 @@ module TcMonad(
        foldrTc, foldlTc, mapAndUnzipTc, mapAndUnzip3Tc,
        mapBagTc, fixTc, tryTc,
 
-       returnNF_Tc, thenNF_Tc, thenNF_Tc_, mapNF_Tc, 
+       returnNF_Tc, thenNF_Tc, thenNF_Tc_, mapNF_Tc, fixNF_Tc,
        listNF_Tc, mapAndUnzipNF_Tc, mapBagNF_Tc,
 
        checkTc, checkTcM, checkMaybeTc, checkMaybeTcM, 
@@ -24,34 +26,39 @@ module TcMonad(
 
        tcNewMutVar, tcReadMutVar, tcWriteMutVar,
 
-       rn4MtoTcM,
+       rnMtoTcM,
 
-       TcError(..), TcWarning(..),
+       SYN_IE(TcError), SYN_IE(TcWarning),
        mkTcErr, arityErr,
 
        -- For closure
-       MutableVar(..), _MutableArray
+       SYN_IE(MutableVar),
+#if __GLASGOW_HASKELL__ >= 200
+       GHCbase.MutableArray
+#else
+       _MutableArray
+#endif
   ) where
 
-import Ubiq{-uitous-}
+IMP_Ubiq(){-uitous-}
 
-import TcMLoop         ( TcEnv, initEnv, TcMaybe )  -- We need the type TcEnv and an initial Env
+IMPORT_DELOOPER(TcMLoop) ( TcEnv, initEnv, TcMaybe )  -- We need the type TcEnv and an initial Env
 
-import Type            ( Type(..), GenType )
-import TyVar           ( TyVar(..), GenTyVar )
-import Usage           ( Usage(..), GenUsage )
-import ErrUtils                ( Error(..), Message(..), ErrCtxt(..),
-                         Warning(..) )
+import Type            ( SYN_IE(Type), GenType )
+import TyVar           ( SYN_IE(TyVar), GenTyVar )
+import Usage           ( SYN_IE(Usage), GenUsage )
+import ErrUtils                ( SYN_IE(Error), SYN_IE(Message), SYN_IE(Warning) )
 
 import SST
---import RnMonad4
---LATER:import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
+import RnMonad         ( SYN_IE(RnM), RnDown, initRn, setExtraRn,
+                         returnRn, thenRn, getImplicitUpRn
+                       )
+import RnUtils         ( SYN_IE(RnEnv) )
 
 import Bag             ( Bag, emptyBag, isEmptyBag,
                          foldBag, unitBag, unionBags, snocBag )
-import FiniteMap       ( FiniteMap, emptyFM )
-import Outputable      ( Outputable(..), NamedThing(..), ExportFlag )
-import ErrUtils                ( Error(..) )
+import FiniteMap       ( FiniteMap, emptyFM, isEmptyFM{-, keysFM ToDo:rm-} )
+--import Outputable    ( Outputable(..), NamedThing(..), ExportFlag )
 import Maybes          ( MaybeErr(..) )
 --import Name          ( Name )
 import SrcLoc          ( SrcLoc, mkUnknownSrcLoc )
@@ -75,16 +82,22 @@ type TcM    s r =  TcDown s -> TcEnv s -> FSST s r ()
 \end{code}
 
 \begin{code}
--- With a builtin polymorphic type for _runSST the type for
--- initTc should use  TcM s r  instead of  TcM _RealWorld r 
+#if __GLASGOW_HASKELL__ >= 200
+# define REAL_WORLD RealWorld
+#else
+# define REAL_WORLD _RealWorld
+#endif
+
+-- With a builtin polymorphic type for runSST the type for
+-- initTc should use  TcM s r  instead of  TcM RealWorld r 
 
 initTc :: UniqSupply
-       -> TcM _RealWorld r
+       -> TcM REAL_WORLD r
        -> MaybeErr (r, Bag Warning)
                   (Bag Error, Bag  Warning)
 
 initTc us do_this
-  = _runSST (
+  = runSST (
       newMutVarSST us                  `thenSST` \ us_var ->
       newMutVarSST (emptyBag,emptyBag) `thenSST` \ errs_var ->
       newMutVarSST emptyUFM            `thenSST` \ tvs_var ->
@@ -127,6 +140,9 @@ thenNF_Tc_ m k down env
 returnNF_Tc :: a -> NF_TcM s a
 returnNF_Tc v down env = returnSST v
 
+fixNF_Tc :: (a -> NF_TcM s a) -> NF_TcM s a
+fixNF_Tc m env down = fixSST (\ loop -> m loop env down)
+
 mapNF_Tc    :: (a -> NF_TcM s b) -> [a] -> NF_TcM s [b]
 mapNF_Tc f []     = returnNF_Tc []
 mapNF_Tc f (x:xs) = f x                        `thenNF_Tc` \ r ->
@@ -226,7 +242,7 @@ forkNF_Tc m (TcDown deflts u_var src_loc err_cxt err_var) env
        (us1, us2) = splitUniqSupply us
     in
     writeMutVarSST u_var us1   `thenSST_`
-    returnSST (_runSST (
+    returnSST ( runSST (
        newMutVarSST us2                        `thenSST` \ u_var'   ->
        newMutVarSST (emptyBag,emptyBag)        `thenSST` \ err_var' ->
        newMutVarSST emptyUFM                   `thenSST` \ tv_var'  ->
@@ -303,8 +319,20 @@ recoverNF_Tc recover m down env
 tryTc :: TcM s r -> TcM s r -> TcM s r
 tryTc recover m down env
   = recoverFSST (\ _ -> recover down env) $
+
     newMutVarSST (emptyBag,emptyBag)   `thenSST` \ new_errs_var ->
-    m (setTcErrs down new_errs_var) env
+
+    m (setTcErrs down new_errs_var) env        `thenFSST` \ result ->
+
+       -- Check that m has no errors; if it has internal recovery
+       -- mechanisms it might "succeed" but having found a bunch of
+       -- errors along the way. If so we want tryTc to use 
+       -- "recover" instead
+    readMutVarSST new_errs_var         `thenSST` \ (_,errs) ->
+    if isEmptyBag errs then
+       returnFSST result
+    else
+       recover down env
 
 checkTc :: Bool -> Message -> TcM s ()         -- Check that the boolean is true
 checkTc True  err = returnTc ()
@@ -446,24 +474,34 @@ getErrCtxt (TcDown def us loc ctxt errs)     = ctxt
 %~~~~~~~~~~~~~~~~~~
 
 \begin{code}
-rn4MtoTcM = panic "TcMonad.rn4MtoTcM (ToDo LATER)"
-{- LATER:
-rn4MtoTcM :: GlobalNameMappers -> Rn4M a -> NF_TcM s (a, Bag Error)
+rnMtoTcM :: RnEnv -> RnM REAL_WORLD a -> NF_TcM s (a, Bag Error)
 
-rn4MtoTcM name_funs rn_action down env
+rnMtoTcM rn_env rn_action down env
   = readMutVarSST u_var                                `thenSST` \ uniq_supply ->
     let
       (new_uniq_supply, uniq_s) = splitUniqSupply uniq_supply
     in
     writeMutVarSST u_var new_uniq_supply       `thenSST_`
     let
-       (rn_result, rn_errs)
-         = rn_action name_funs emptyFM emptyBag uniq_s mkUnknownSrcLoc
+       (rn_result, rn_errs, rn_warns)
+         = initRn False{-*interface* mode! so we can see the builtins-}
+                  (panic "rnMtoTcM:module")
+                  rn_env uniq_s (
+               rn_action       `thenRn` \ result ->
+
+               -- Though we are in "interface mode", we must
+               -- not have added anything to the ImplicitEnv!
+               getImplicitUpRn `thenRn` \ implicit_env@(v_env,tc_env) ->
+               if (isEmptyFM v_env && isEmptyFM tc_env)
+               then returnRn result
+               else panic "rnMtoTcM: non-empty ImplicitEnv!"
+--                     (ppAboves ([ ppCat [ppPStr m, ppPStr n] | (OrigName m n) <- keysFM v_env]
+--                             ++ [ ppCat [ppPStr m, ppPStr n] | (OrigName m n) <- keysFM tc_env]))
+           )
     in
     returnSST (rn_result, rn_errs)
   where
     u_var = getUniqSupplyVar down
--}
 \end{code}