[project @ 2005-08-11 09:20:49 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcRnTypes.lhs
index 8edada3..e8b0b48 100644 (file)
@@ -26,6 +26,9 @@ module TcRnTypes(
        ThStage(..), topStage, topSpliceStage,
        ThLevel, impLevel, topLevel,
 
+       -- Arrows
+       ArrowCtxt(NoArrowCtxt), newArrowScope, escapeArrowScope,
+
        -- Insts
        Inst(..), InstOrigin(..), InstLoc(..), pprInstLoc, 
        instLocSrcLoc, instLocSrcSpan,
@@ -44,11 +47,11 @@ import HscTypes             ( FixityEnv,
                          HscEnv, TypeEnv, TyThing, 
                          GenAvailInfo(..), AvailInfo, HscSource(..),
                          availName, IsBootInterface, Deprecations )
-import Packages                ( PackageId )
+import Packages                ( PackageId, HomeModules )
 import Type            ( Type, TvSubstEnv, pprParendType, pprTyThingCategory )
 import TcType          ( TcTyVarSet, TcType, TcTauType, TcThetaType, SkolemInfo,
                          TcPredType, TcKind, tcCmpPred, tcCmpType, tcCmpTypes, pprSkolInfo )
-import InstEnv         ( DFunId, InstEnv )
+import InstEnv         ( Instance, InstEnv )
 import IOEnv
 import RdrName         ( GlobalRdrEnv, LocalRdrEnv )
 import Name            ( Name )
@@ -159,6 +162,10 @@ data TcGblEnv
                                        --    from where, including things bound
                                        --    in this module
 
+       tcg_home_mods :: HomeModules,
+                               -- Calculated from ImportAvails, allows us to
+                               -- call Packages.isHomeModule
+
        tcg_dus :: DefUses,     -- What is defined in this module and what is used.
                                -- The latter is used to generate 
                                --      (a) version tracking; no need to recompile if these
@@ -193,6 +200,17 @@ data TcGblEnv
                -- tcg_inst_uses; the reference is implicit rather than explicit,
                -- so we have to zap a mutable variable.
 
+       tcg_dfun_n  :: TcRef Int,       -- Allows us to number off the names of DFuns
+               -- It's convenient to allocate an External Name for a DFun, with
+               -- a permanently-fixed unique, just like other top-level functions
+               -- defined in this module.  But that means we need a canonical 
+               -- occurrence name, distinct from all other dfuns in this module,
+               -- and this name supply serves that purpose (df1, df2, etc).
+
+               -- The next fields accumulate the payload of the module
+               -- The binds, rules and foreign-decl fiels are collected
+               -- initially in un-zonked form and are finally zonked in tcRnSrcDecls
+
                -- The next fields accumulate the payload of the
                -- module The binds, rules and foreign-decl fiels are
                -- collected initially in un-zonked form and are
@@ -203,7 +221,7 @@ data TcGblEnv
 
        tcg_binds   :: LHsBinds Id,             -- Value bindings in this module
        tcg_deprecs :: Deprecations,            -- ...Deprecations 
-       tcg_insts   :: [DFunId],                -- ...Instances
+       tcg_insts   :: [Instance],              -- ...Instances
        tcg_rules   :: [LRuleDecl Id],          -- ...Rules
        tcg_fords   :: [LForeignDecl Id]        -- ...Foreign import & exports
     }
@@ -280,6 +298,7 @@ data TcLclEnv               -- Changes as we move inside an expression
        tcl_errs :: TcRef Messages,     -- Place to accumulate errors
 
        tcl_th_ctxt    :: ThStage,      -- Template Haskell context
+       tcl_arrow_ctxt :: ArrowCtxt,    -- Arrow-notation context
 
        tcl_rdr :: LocalRdrEnv,         -- Local name envt
                -- Maintained during renaming, of course, but also during
@@ -356,6 +375,45 @@ topStage, topSpliceStage :: ThStage
 topStage       = Comp
 topSpliceStage = Splice (topLevel - 1) -- Stage for the body of a top-level splice
 
+---------------------------
+-- Arrow-notation context
+---------------------------
+
+{-
+In arrow notation, a variable bound by a proc (or enclosed let/kappa)
+is not in scope to the left of an arrow tail (-<) or the head of (|..|).
+For example
+
+       proc x -> (e1 -< e2)
+
+Here, x is not in scope in e1, but it is in scope in e2.  This can get
+a bit complicated:
+
+       let x = 3 in
+       proc y -> (proc z -> e1) -< e2
+
+Here, x and z are in scope in e1, but y is not.  We implement this by
+recording the environment when passing a proc (using newArrowScope),
+and returning to that (using escapeArrowScope) on the left of -< and the
+head of (|..|).
+-}
+
+data ArrowCtxt
+  = NoArrowCtxt
+  | ArrowCtxt (Env TcGblEnv TcLclEnv)
+
+-- Record the current environment (outside a proc)
+newArrowScope :: TcM a -> TcM a
+newArrowScope
+  = updEnv $ \env ->
+       env { env_lcl = (env_lcl env) { tcl_arrow_ctxt = ArrowCtxt env } }
+
+-- Return to the stored environment (from the enclosing proc)
+escapeArrowScope :: TcM a -> TcM a
+escapeArrowScope
+  = updEnv $ \ env -> case tcl_arrow_ctxt (env_lcl env) of
+       NoArrowCtxt -> env
+       ArrowCtxt env' -> env'
 
 ---------------------------
 -- TcTyThing
@@ -429,22 +487,18 @@ data ImportAvails
                -- So the starting point is all things that are in scope as 'M.x',
                -- which is what this field tells us.
 
-       imp_mods :: ModuleEnv (Module, Maybe Bool, SrcSpan),
+       imp_mods :: ModuleEnv (Module, Bool, SrcSpan),
                -- Domain is all directly-imported modules
-               -- Maybe value answers the question "is the import restricted?"
-               --   Nothing    => unrestricted import (e.g., "import Foo")
-               --   Just True  => restricted import, at least one entity (e.g., "import Foo(x)")
-               --   Just False => fully restricted import (e.g., "import Foo ()")
-               --
-               --  A distinction is made between the first and the third in order
-               --  to more precisely emit warnings about unused imports.
+               -- Bool means:
+               --   True => import was "import Foo ()"
+               --   False  => import was some other form
                --
                -- We need the Module in the range because we can't get
                --      the keys of a ModuleEnv
                -- Used 
                --   (a) to help construct the usage information in 
-               --       the interface file; if we import everything we
-               --       need to recompile if the module version changes
+               --       the interface file; if we import somethign we
+               --       need to recompile if the export version changes
                --   (b) to specify what child modules to initialise
 
        imp_dep_mods :: ModuleEnv (Module, IsBootInterface),