[project @ 2000-10-31 09:58:13 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcModule.lhs
index d0e1993..53de077 100644 (file)
@@ -12,9 +12,9 @@ module TcModule (
 #include "HsVersions.h"
 
 import CmdLineOpts     ( DynFlag(..), DynFlags, opt_PprStyle_Debug )
-import HsSyn           ( HsModule(..), HsBinds(..), MonoBinds(..), HsDecl(..) )
+import HsSyn           ( HsBinds(..), MonoBinds(..), HsDecl(..) )
 import HsTypes         ( toHsType )
-import RnHsSyn         ( RenamedHsModule, RenamedHsDecl )
+import RnHsSyn         ( RenamedHsDecl )
 import TcHsSyn         ( TypecheckedMonoBinds, 
                          TypecheckedForeignDecl, TypecheckedRuleDecl,
                          zonkTopBinds, zonkForeignExports, zonkRules
@@ -25,15 +25,14 @@ import Inst         ( plusLIE )
 import TcBinds         ( tcTopBinds )
 import TcClassDcl      ( tcClassDecls2, mkImplicitClassBinds )
 import TcDefaults      ( tcDefaults )
-import TcEnv           ( TcEnv, tcExtendGlobalValEnv, tcLookupGlobal_maybe,
-                         tcEnvTyCons, tcEnvClasses, 
-                         tcSetEnv, tcSetInstEnv, initTcEnv, getTcGEnv
+import TcEnv           ( TcEnv, InstInfo(iDFunId), tcExtendGlobalValEnv, 
+                         tcEnvTyCons, tcEnvClasses,  isLocalThing,
+                         RecTcEnv, tcSetEnv, tcSetInstEnv, initTcEnv, getTcGEnv
                        )
 import TcRules         ( tcRules )
 import TcForeign       ( tcForeignImports, tcForeignExports )
 import TcIfaceSig      ( tcInterfaceSigs )
 import TcInstDcls      ( tcInstDecls1, tcInstDecls2 )
-import InstEnv         ( InstInfo(..) )
 import TcSimplify      ( tcSimplifyTop )
 import TcTyClsDecls    ( tcTyAndClassDecls )
 import TcTyDecls       ( mkImplicitDataBinds )
@@ -42,24 +41,22 @@ import CoreUnfold   ( unfoldingTemplate )
 import Type            ( funResultTy, splitForAllTys )
 import Bag             ( isEmptyBag )
 import ErrUtils                ( printErrorsAndWarnings, dumpIfSet_dyn )
-import Id              ( idType, idName, idUnfolding )
-import Module           ( Module, moduleName, plusModuleEnv )
-import Name            ( Name, nameOccName, isLocallyDefined, isGlobalName,
-                         toRdrName, nameEnvElts, emptyNameEnv, lookupNameEnv
+import Id              ( idType, idUnfolding )
+import Module           ( Module )
+import Name            ( Name, isLocallyDefined, 
+                         toRdrName, nameEnvElts, lookupNameEnv, 
                        )
 import TyCon           ( tyConGenInfo, isClassTyCon )
-import OccName         ( isSysOcc )
-import PrelNames       ( mAIN_Name, mainName )
 import Maybes          ( thenMaybe )
 import Util
 import BasicTypes       ( EP(..), Fixity )
 import Bag             ( isEmptyBag )
 import Outputable
 import HscTypes                ( PersistentCompilerState(..), HomeSymbolTable, HomeIfaceTable,
-                         PackageSymbolTable, PackageIfaceTable, DFunId, ModIface(..),
-                         TypeEnv, extendTypeEnv, lookupTable,
-                         TyThing(..), groupTyThings )
-import FiniteMap       ( FiniteMap, delFromFM, lookupWithDefaultFM )
+                         PackageTypeEnv, DFunId, ModIface(..),
+                         TypeEnv, extendTypeEnvList, lookupIface,
+                         TyThing(..), mkTypeEnv )
+import List            ( partition )
 \end{code}
 
 Outside-world interface:
@@ -70,9 +67,11 @@ data TcResults
   = TcResults {
        tc_pcs     :: PersistentCompilerState,  -- Augmented with imported information,
                                                -- (but not stuff from this module)
-       tc_env     :: TypeEnv,                  -- The TypeEnv just for the stuff from this module
-       tc_insts   :: [DFunId],                 -- Instances, just for this module
-       tc_binds   :: TypecheckedMonoBinds,
+
+       -- All these fields have info *just for this module*
+       tc_env     :: TypeEnv,                  -- The top level TypeEnv
+       tc_insts   :: [DFunId],                 -- Instances
+       tc_binds   :: TypecheckedMonoBinds,     -- Bindings
        tc_fords   :: [TypecheckedForeignDecl], -- Foreign import & exports.
        tc_rules   :: [TypecheckedRuleDecl]     -- Transformation rules
     }
@@ -82,29 +81,35 @@ typecheckModule
        :: DynFlags
        -> Module
        -> PersistentCompilerState
-       -> HomeSymbolTable
-       -> HomeIfaceTable
-       -> PackageIfaceTable
-       -> RenamedHsModule
-       -> IO (Maybe (TcEnv, TcResults))
-
-typecheckModule dflags this_mod pcs hst hit pit (HsModule mod_name _ _ _ decls _ src_loc)
-  = do env <- initTcEnv global_symbol_table
-       (maybe_result, (errs,warns)) <- initTc dflags env src_loc tc_module
-       printErrorsAndWarnings (errs,warns)
-       printTcDump dflags maybe_result
-       if isEmptyBag errs then 
-          return Nothing 
-         else 
-          return maybe_result
+       -> HomeSymbolTable -> HomeIfaceTable
+       -> [RenamedHsDecl]
+       -> IO (Maybe TcResults)
+
+typecheckModule dflags this_mod pcs hst hit decls
+  = do env <- initTcEnv hst (pcs_PTE pcs)
+
+        (maybe_result, (warns,errs)) <- initTc dflags env tc_module
+
+       let { maybe_tc_result :: Maybe TcResults ;
+             maybe_tc_result = case maybe_result of
+                                 Nothing    -> Nothing
+                                 Just (_,r) -> Just r }
+
+        printErrorsAndWarnings (errs,warns)
+        printTcDump dflags maybe_tc_result
+
+        if isEmptyBag errs then 
+             return maybe_tc_result
+           else 
+             return Nothing 
   where
-    global_symbol_table = pcs_PST pcs `plusModuleEnv` hst
+    tc_module :: TcM (RecTcEnv, TcResults)
+    tc_module = fixTc (\ ~(unf_env ,_) -> tcModule pcs hst get_fixity this_mod decls unf_env)
 
-    tc_module = fixTc (\ ~(unf_env ,_) 
-                        -> tcModule pcs hst get_fixity this_mod decls unf_env)
+    pit = pcs_PIT pcs
 
     get_fixity :: Name -> Maybe Fixity
-    get_fixity nm = lookupTable hit pit nm     `thenMaybe` \ iface ->
+    get_fixity nm = lookupIface hit pit this_mod nm    `thenMaybe` \ iface ->
                    lookupNameEnv (mi_fixities iface) nm
 \end{code}
 
@@ -115,10 +120,10 @@ tcModule :: PersistentCompilerState
         -> (Name -> Maybe Fixity)
         -> Module
         -> [RenamedHsDecl]
-        -> TcEnv               -- The knot-tied environment
+        -> RecTcEnv            -- The knot-tied environment
         -> TcM (TcEnv, TcResults)
 
-  -- (unf_env :: TcEnv) is used for type-checking interface pragmas
+  -- (unf_env :: RecTcEnv) is used for type-checking interface pragmas
   -- which is done lazily [ie failure just drops the pragma
   -- without having any global-failure effect].
   -- 
@@ -130,24 +135,19 @@ tcModule pcs hst get_fixity this_mod decls unf_env
     tcTyAndClassDecls unf_env decls            `thenTc` \ env ->
     tcSetEnv env                               $
     let
-        classes       = tcEnvClasses env
-        tycons        = tcEnvTyCons env        -- INCLUDES tycons derived from classes
-        local_tycons  = [ tc | tc <- tycons,
-                              isLocallyDefined tc,
-                              not (isClassTyCon tc)
-                       ]
-                       -- For local_tycons, filter out the ones derived from classes
-                       -- Otherwise the latter show up in interface files
+        classes = tcEnvClasses env
+        tycons  = tcEnvTyCons env      -- INCLUDES tycons derived from classes
     in
     
        -- Typecheck the instance decls, includes deriving
-    tcInstDecls1 pcs hst unf_env get_fixity this_mod 
-                local_tycons decls             `thenTc` \ (pcs_with_insts, inst_env, inst_info, deriv_binds) ->
+    tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs) 
+                hst unf_env get_fixity this_mod 
+                tycons decls           `thenTc` \ (new_pcs_insts, inst_env, local_inst_info, deriv_binds) ->
     tcSetInstEnv inst_env                      $
     
         -- Default declarations
-    tcDefaults decls                   `thenTc` \ defaulting_tys ->
-    tcSetDefaultTys defaulting_tys     $
+    tcDefaults decls                           `thenTc` \ defaulting_tys ->
+    tcSetDefaultTys defaulting_tys             $
     
     -- Interface type signatures
     -- We tie a knot so that the Ids read out of interfaces are in scope
@@ -160,14 +160,15 @@ tcModule pcs hst get_fixity this_mod decls unf_env
     -- imported
     tcInterfaceSigs unf_env decls              `thenTc` \ sig_ids ->
     tcExtendGlobalValEnv sig_ids               $
+    tcGetEnv                                   `thenTc` \ unf_env ->
     
     -- Create any necessary record selector Ids and their bindings
     -- "Necessary" includes data and newtype declarations
     -- We don't create bindings for dictionary constructors;
     -- they are always fully applied, and the bindings are just there
     -- to support partial applications
-    mkImplicitDataBinds tycons                 `thenTc`    \ (data_ids, imp_data_binds) ->
-    mkImplicitClassBinds classes               `thenNF_Tc` \ (cls_ids,  imp_cls_binds) ->
+    mkImplicitDataBinds  this_mod tycons       `thenTc`    \ (data_ids, imp_data_binds) ->
+    mkImplicitClassBinds this_mod classes      `thenNF_Tc` \ (cls_ids,  imp_cls_binds) ->
     
     -- Extend the global value environment with 
     -- (a) constructors
@@ -193,9 +194,9 @@ tcModule pcs hst get_fixity this_mod decls unf_env
     
        -- Second pass over class and instance declarations,
        -- to compile the bindings themselves.
-    tcInstDecls2  inst_info            `thenNF_Tc` \ (lie_instdecls, inst_binds) ->
-    tcClassDecls2 decls                        `thenNF_Tc` \ (lie_clasdecls, cls_dm_binds) ->
-    tcRules decls                      `thenNF_Tc` \ (lie_rules,     rules) ->
+    tcInstDecls2  local_inst_info              `thenNF_Tc` \ (lie_instdecls, inst_binds) ->
+    tcClassDecls2 this_mod decls               `thenNF_Tc` \ (lie_clasdecls, cls_dm_binds) ->
+    tcRules (pcs_rules pcs) this_mod decls     `thenNF_Tc` \ (new_pcs_rules, lie_rules, local_rules) ->
     
          -- Deal with constant or ambiguous InstIds.  How could
          -- there be ambiguous ones?  They can only arise if a
@@ -212,9 +213,6 @@ tcModule pcs hst get_fixity this_mod decls unf_env
     in
     tcSimplifyTop lie_alldecls                 `thenTc` \ const_inst_binds ->
     
-       -- Check that Main defines main
-    checkMain this_mod                         `thenTc_`
-    
         -- Backsubstitution.    This must be done last.
         -- Even tcSimplifyTop may do some unification.
     let
@@ -230,50 +228,37 @@ tcModule pcs hst get_fixity this_mod decls unf_env
     tcSetEnv final_env                 $
        -- zonkTopBinds puts all the top-level Ids into the tcGEnv
     zonkForeignExports foe_decls       `thenNF_Tc` \ foe_decls' ->
-    zonkRules rules                    `thenNF_Tc` \ rules' ->
-    
+    zonkRules local_rules              `thenNF_Tc` \ local_rules' ->
     
-    let        groups :: FiniteMap Module TypeEnv
-       groups = groupTyThings (nameEnvElts (getTcGEnv final_env))
     
+    let        (local_things, imported_things) = partition (isLocalThing this_mod) 
+                                                   (nameEnvElts (getTcGEnv final_env))
+
        local_type_env :: TypeEnv
-       local_type_env = lookupWithDefaultFM groups emptyNameEnv this_mod 
+       local_type_env = mkTypeEnv local_things
     
-       new_pst :: PackageSymbolTable
-       new_pst = extendTypeEnv (pcs_PST pcs) (delFromFM groups this_mod)
+       new_pte :: PackageTypeEnv
+       new_pte = extendTypeEnvList (pcs_PTE pcs) imported_things
 
        final_pcs :: PersistentCompilerState
-       final_pcs = pcs_with_insts {pcs_PST = new_pst}
+       final_pcs = pcs { pcs_PTE   = new_pte,
+                         pcs_insts = new_pcs_insts,
+                         pcs_rules = new_pcs_rules
+                   }
     in  
-    returnTc (final_env, -- WAS: really_final_env, 
+    returnTc (unf_env,
              TcResults { tc_pcs     = final_pcs,
                          tc_env     = local_type_env,
                          tc_binds   = all_binds', 
-                         tc_insts   = map iDFunId inst_info,
+                         tc_insts   = map iDFunId local_inst_info,
                          tc_fords   = foi_decls ++ foe_decls',
-                         tc_rules   = rules'
+                         tc_rules   = local_rules'
                         })
 
 get_binds decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls]
 \end{code}
 
 
-\begin{code}
-checkMain :: Module -> TcM ()
-checkMain this_mod 
-  | moduleName this_mod == mAIN_Name 
-  = tcLookupGlobal_maybe mainName              `thenNF_Tc` \ maybe_main ->
-    case maybe_main of
-       Just (AnId _) -> returnTc ()
-       other         -> addErrTc noMainErr
-
-  | otherwise = returnTc ()
-
-noMainErr
-  = hsep [ptext SLIT("Module"), quotes (ppr mAIN_Name), 
-         ptext SLIT("must include a definition for"), quotes (ptext SLIT("main"))]
-\end{code}
-
 
 %************************************************************************
 %*                                                                     *
@@ -283,7 +268,7 @@ noMainErr
 
 \begin{code}
 printTcDump dflags Nothing = return ()
-printTcDump dflags (Just (_,results))
+printTcDump dflags (Just results)
   = do dumpIfSet_dyn dflags Opt_D_dump_types 
                      "Type signatures" (dump_sigs results)
        dumpIfSet_dyn dflags Opt_D_dump_tc    
@@ -308,11 +293,7 @@ dump_sigs results  -- Print type signatures
     ppr_sig (n,t)        = ppr n <+> dcolon <+> ppr t
 
     want_sig id | opt_PprStyle_Debug = True
-               | otherwise          = isLocallyDefined n && 
-                                      isGlobalName n && 
-                                      not (isSysOcc (nameOccName n))
-                                    where
-                                      n = idName id
+               | otherwise          = isLocallyDefined id
 
 ppr_gen_tycons tcs = vcat [ptext SLIT("{-# Generic type constructor details"),
                           vcat (map ppr_gen_tycon (filter isLocallyDefined tcs)),