Massive patch for the first months work adding System FC to GHC #34
[ghc-hetmet.git] / compiler / typecheck / TcRnMonad.lhs
index f515334..af75fe6 100644 (file)
@@ -50,7 +50,8 @@ import Outputable
 import UniqSupply      ( UniqSupply, mkSplitUniqSupply, uniqFromSupply, splitUniqSupply )
 import UniqFM          ( unitUFM )
 import Unique          ( Unique )
-import DynFlags                ( DynFlags(..), DynFlag(..), dopt, dopt_set, GhcMode )
+import DynFlags                ( DynFlags(..), DynFlag(..), dopt, dopt_set,
+                         dopt_unset, GhcMode ) 
 import StaticFlags     ( opt_PprStyle_Debug )
 import Bag             ( snocBag, unionBags )
 import Panic           ( showException )
@@ -131,33 +132,8 @@ initTc hsc_env hsc_src mod do_this
    
        -- OK, here's the business end!
        maybe_res <- initTcRnIf 'a' hsc_env gbl_env lcl_env $
-                    do {
-#if defined(GHCI) && defined(BREAKPOINT)
-                          unique <- newUnique ;
-                          let { var = mkInternalName unique (mkOccName tvName "a") noSrcLoc;
-                                tyvar = mkTyVar var liftedTypeKind;
-                                basicType extra = (FunTy intTy
-                                                   (FunTy (mkListTy unitTy)
-                                                    (FunTy stringTy
-                                                     (ForAllTy tyvar
-                                                      (extra
-                                                       (FunTy (TyVarTy tyvar)
-                                                        (TyVarTy tyvar)))))));
-                                breakpointJumpType
-                                    = mkGlobalId VanillaGlobal breakpointJumpName
-                                                 (basicType id) vanillaIdInfo;
-                                breakpointCondJumpType
-                                    = mkGlobalId VanillaGlobal breakpointCondJumpName
-                                                 (basicType (FunTy boolTy)) vanillaIdInfo;
-                                new_env = mkNameEnv [(breakpointJumpName
-                                                     , ATcId breakpointJumpType topLevel False)
-                                                     ,(breakpointCondJumpName
-                                                     , ATcId breakpointCondJumpType topLevel False)];
-                              };
-                          r <- tryM (updLclEnv (\gbl -> gbl{tcl_env=new_env}) do_this)
-#else
-                          r <- tryM do_this
-#endif
+                    addBreakpointBindings $
+                    do { r <- tryM do_this
                        ; case r of
                          Right res -> return (Just res)
                          Left _    -> return Nothing } ;
@@ -190,6 +166,32 @@ initTcPrintErrors env mod todo = do
   return res
 \end{code}
 
+\begin{code}
+addBreakpointBindings :: TcM a -> TcM a
+addBreakpointBindings thing_inside
+#if defined(GHCI) && defined(BREAKPOINT)
+  = do { unique <- newUnique
+        ; let { var = mkInternalName unique (mkOccName tvName "a") noSrcLoc;
+                tyvar = mkTyVar var liftedTypeKind;
+                basicType extra = (FunTy intTy
+                                   (FunTy (mkListTy unitTy)
+                                    (FunTy stringTy
+                                     (ForAllTy tyvar
+                                      (extra
+                                       (FunTy (TyVarTy tyvar)
+                                        (TyVarTy tyvar)))))));
+                breakpointJumpId
+                    = mkGlobalId VanillaGlobal breakpointJumpName
+                                 (basicType id) vanillaIdInfo;
+                breakpointCondJumpId
+                    = mkGlobalId VanillaGlobal breakpointCondJumpName
+                                 (basicType (FunTy boolTy)) vanillaIdInfo
+         }
+       ; extendIdEnv [breakpoingJumpId, breakpointCondJumpId] thing_inside}
+#else
+   = thing_inside
+#endif
+\end{code}
 
 %************************************************************************
 %*                                                                     *
@@ -268,6 +270,10 @@ setOptM :: DynFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
 setOptM flag = updEnv (\ env@(Env { env_top = top }) ->
                         env { env_top = top { hsc_dflags = dopt_set (hsc_dflags top) flag}} )
 
+unsetOptM :: DynFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+unsetOptM flag = updEnv (\ env@(Env { env_top = top }) ->
+                        env { env_top = top { hsc_dflags = dopt_unset (hsc_dflags top) flag}} )
+
 ifOptM :: DynFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl ()    -- Do it flag is true
 ifOptM flag thing_inside = do { b <- doptM flag; 
                                if b then thing_inside else return () }
@@ -323,17 +329,28 @@ getEpsAndHpt = do { env <- getTopEnv; eps <- readMutVar (hsc_EPS env)
 
 \begin{code}
 newUnique :: TcRnIf gbl lcl Unique
-newUnique = do { us <- newUniqueSupply ; 
-                return (uniqFromSupply us) }
+newUnique
+ = do { env <- getEnv ;
+       let { u_var = env_us env } ;
+       us <- readMutVar u_var ;
+        case splitUniqSupply us of { (us1,_) -> do {
+       writeMutVar u_var us1 ;
+       return $! uniqFromSupply us }}}
+   -- NOTE 1: we strictly split the supply, to avoid the possibility of leaving
+   -- a chain of unevaluated supplies behind.
+   -- NOTE 2: we use the uniq in the supply from the MutVar directly, and
+   -- throw away one half of the new split supply.  This is safe because this
+   -- is the only place we use that unique.  Using the other half of the split
+   -- supply is safer, but slower.
 
 newUniqueSupply :: TcRnIf gbl lcl UniqSupply
 newUniqueSupply
  = do { env <- getEnv ;
        let { u_var = env_us env } ;
        us <- readMutVar u_var ;
-       let { (us1, us2) = splitUniqSupply us } ;
+        case splitUniqSupply us of { (us1,us2) -> do {
        writeMutVar u_var us1 ;
-       return us2 }
+       return us2 }}}
 
 newLocalName :: Name -> TcRnIf gbl lcl Name
 newLocalName name      -- Make a clone