[project @ 2000-11-14 10:46:39 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcModule.lhs
index ab16194..ff885c7 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, 
+import TcEnv           ( TcEnv, InstInfo(iDFunId), tcExtendGlobalValEnv, 
+                         tcEnvTyCons, tcEnvClasses,  isLocalThing,
                          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 )
@@ -41,25 +40,21 @@ import TcTyDecls    ( mkImplicitDataBinds )
 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 TyCon           ( tyConGenInfo, isClassTyCon )
-import OccName         ( isSysOcc )
-import PrelNames       ( mAIN_Name, mainName )
-import Maybes          ( thenMaybe )
+import ErrUtils                ( printErrorsAndWarnings, dumpIfSet_dyn, showPass )
+import Id              ( idType, idUnfolding )
+import Module           ( Module )
+import Name            ( Name, toRdrName )
+import Name            ( nameEnvElts, lookupNameEnv )
+import TyCon           ( tyConGenInfo )
 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 )
+import HscTypes                ( PersistentCompilerState(..), HomeSymbolTable, 
+                         PackageTypeEnv, DFunId, ModIface(..),
+                         TypeEnv, extendTypeEnvList, 
+                         TyThing(..), mkTypeEnv )
+import List            ( partition )
 \end{code}
 
 Outside-world interface:
@@ -70,9 +65,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
     }
@@ -83,35 +80,30 @@ typecheckModule
        -> Module
        -> PersistentCompilerState
        -> HomeSymbolTable
-       -> HomeIfaceTable
-       -> PackageIfaceTable
+       -> ModIface             -- Iface for this module
+       -> PrintUnqualified     -- For error printing
        -> [RenamedHsDecl]
        -> IO (Maybe TcResults)
 
-typecheckModule dflags this_mod pcs hst hit pit decls
-  = do env <- initTcEnv global_symbol_table
-
-        (maybe_result, (errs,warns)) <- initTc dflags env tc_module
+typecheckModule dflags this_mod pcs hst mod_iface unqual decls
+  = do { showPass dflags "Typechecker";
+       ; env <- initTcEnv hst (pcs_PTE pcs)
 
-       let maybe_tc_result :: Maybe TcResults
-           maybe_tc_result = mapMaybe snd maybe_result
+       ; (maybe_tc_result, (warns,errs)) <- initTc dflags env (tcModule pcs hst get_fixity this_mod decls)
 
-       printErrorsAndWarnings (errs,warns)
-       printTcDump dflags maybe_tc_result
+       ; printErrorsAndWarnings unqual (errs,warns)
+       ; printTcDump dflags maybe_tc_result
 
-       if isEmptyBag errs then 
-          return Nothing 
-         else 
-          return 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 (TcEnv, TcResults)
-    tc_module = fixTc (\ ~(unf_env ,_) -> tcModule pcs hst get_fixity this_mod decls unf_env)
+    fixity_env = mi_fixities mod_iface
 
     get_fixity :: Name -> Maybe Fixity
-    get_fixity nm = lookupTable hit pit nm     `thenMaybe` \ iface ->
-                   lookupNameEnv (mi_fixities iface) nm
+    get_fixity nm = lookupNameEnv fixity_env nm
 \end{code}
 
 The internal monster:
@@ -121,87 +113,96 @@ tcModule :: PersistentCompilerState
         -> (Name -> Maybe Fixity)
         -> Module
         -> [RenamedHsDecl]
-        -> TcEnv               -- The knot-tied environment
-        -> TcM (TcEnv, TcResults)
-
-  -- (unf_env :: TcEnv) is used for type-checking interface pragmas
-  -- which is done lazily [ie failure just drops the pragma
-  -- without having any global-failure effect].
-  -- 
-  -- unf_env is also used to get the pragama info
-  -- for imported dfuns and default methods
+        -> TcM TcResults
 
-tcModule pcs hst get_fixity this_mod decls unf_env
+tcModule pcs hst get_fixity this_mod decls
   =             -- Type-check the type and class decls
-    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
-    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) ->
-    tcSetInstEnv inst_env                      $
-    
-        -- Default declarations
-    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
-    --   when we read their pragmas.
-    -- What we rely on is that pragmas are typechecked lazily; if
-    --   any type errors are found (ie there's an inconsistency)
-    --   we silently discard the pragma
-    -- We must do this before mkImplicitDataBinds (which comes next), since
-    -- the latter looks up unpackCStringId, for example, which is usually 
-    -- imported
-    tcInterfaceSigs unf_env decls              `thenTc` \ sig_ids ->
-    tcExtendGlobalValEnv sig_ids               $
-    
-    -- 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) ->
-    
-    -- Extend the global value environment with 
-    -- (a) constructors
-    -- (b) record selectors
-    -- (c) class op selectors
-    --         (d) default-method ids... where? I can't see where these are
-    --     put into the envt, and I'm worried that the zonking phase
-    --     will find they aren't there and complain.
-    tcExtendGlobalValEnv data_ids              $
-    tcExtendGlobalValEnv cls_ids               $
+    fixTc (\ ~(unf_env, _, _, _, _) -> 
+         -- (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].
+         -- 
+         -- unf_env is also used to get the pragama info
+         -- for imported dfuns and default methods
+               
+--     traceTc (text "Tc1")                    `thenNF_Tc_`
+       tcTyAndClassDecls unf_env decls         `thenTc` \ env ->
+       tcSetEnv env                            $
+       let
+           classes = tcEnvClasses env
+           tycons  = tcEnvTyCons env   -- INCLUDES tycons derived from classes
+       in
+       
+               -- Typecheck the instance decls, includes deriving
+--     traceTc (text "Tc2")    `thenNF_Tc_`
+       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                   $
+       
+       -- Interface type signatures
+       -- We tie a knot so that the Ids read out of interfaces are in scope
+       --   when we read their pragmas.
+       -- What we rely on is that pragmas are typechecked lazily; if
+       --   any type errors are found (ie there's an inconsistency)
+       --   we silently discard the pragma
+       -- We must do this before mkImplicitDataBinds (which comes next), since
+       -- the latter looks up unpackCStringId, for example, which is usually 
+       -- imported
+--     traceTc (text "Tc3")                    `thenNF_Tc_`
+       tcInterfaceSigs unf_env decls           `thenTc` \ sig_ids ->
+       tcExtendGlobalValEnv sig_ids            $
+       
+       -- 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  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
+       --      (b) record selectors
+       --      (c) class op selectors
+       --      (d) default-method ids... where? I can't see where these are
+       --          put into the envt, and I'm worried that the zonking phase
+       --          will find they aren't there and complain.
+       tcExtendGlobalValEnv data_ids           $
+       tcExtendGlobalValEnv cls_ids            $
+       tcGetEnv                                        `thenTc` \ unf_env ->
+       returnTc (unf_env, new_pcs_insts, local_inst_info, deriv_binds,
+                          imp_data_binds `AndMonoBinds` imp_cls_binds)
+    )          `thenTc` \ (env, new_pcs_insts, local_inst_info, deriv_binds, data_cls_binds) ->
     
+    tcSetEnv env                               $
+
         -- Foreign import declarations next
+--  traceTc (text "Tc4")                       `thenNF_Tc_`
     tcForeignImports decls                     `thenTc`    \ (fo_ids, foi_decls) ->
     tcExtendGlobalValEnv fo_ids                        $
     
-    -- Value declarations next.
-    -- We also typecheck any extra binds that came out of the "deriving" process
+       -- Default declarations
+    tcDefaults decls                           `thenTc` \ defaulting_tys ->
+    tcSetDefaultTys defaulting_tys             $
+       
+       -- Value declarations next.
+       -- We also typecheck any extra binds that came out of the "deriving" process
+--  traceTc (text "Tc5")                                       `thenNF_Tc_`
     tcTopBinds (get_binds decls `ThenBinds` deriv_binds)       `thenTc` \ ((val_binds, env), lie_valdecls) ->
     tcSetEnv env $
     
-        -- Foreign export declarations next
+       -- Foreign export declarations next
+--  traceTc (text "Tc6")               `thenNF_Tc_`
     tcForeignExports decls             `thenTc`    \ (lie_fodecls, foe_binds, foe_decls) ->
     
        -- 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) ->
+--  traceTc (text "Tc7")                       `thenNF_Tc_`
+    tcInstDecls2  local_inst_info              `thenNF_Tc` \ (lie_instdecls, inst_binds) ->
+--  traceTc (text "Tc8")                       `thenNF_Tc_`
+    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
@@ -218,68 +219,53 @@ 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
-        all_binds = imp_data_binds     `AndMonoBinds` 
-                   imp_cls_binds       `AndMonoBinds` 
+        all_binds = data_cls_binds     `AndMonoBinds` 
                    val_binds           `AndMonoBinds`
                    inst_binds          `AndMonoBinds`
                    cls_dm_binds        `AndMonoBinds`
                    const_inst_binds    `AndMonoBinds`
                    foe_binds
     in
+--  traceTc (text "Tc9")               `thenNF_Tc_`
     zonkTopBinds all_binds             `thenNF_Tc` \ (all_binds', final_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, 
-             TcResults { tc_pcs     = final_pcs,
+--  traceTc (text "Tc10")              `thenNF_Tc_`
+    returnTc (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}
-
 
 %************************************************************************
 %*                                                                     *
@@ -305,23 +291,19 @@ dump_sigs results -- Print type signatures
   =    -- Convert to HsType so that we get source-language style printing
        -- And sort by RdrName
     vcat $ map ppr_sig $ sortLt lt_sig $
-    [(toRdrName id, toHsType (idType id))
-        | AnId id <- nameEnvElts (tc_env results), 
-          want_sig id
+    [ (toRdrName id, toHsType (idType id))
+    | AnId id <- nameEnvElts (tc_env results),
+      want_sig id
     ]
   where
     lt_sig (n1,_) (n2,_) = n1 < n2
     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          = True     -- For now
 
 ppr_gen_tycons tcs = vcat [ptext SLIT("{-# Generic type constructor details"),
-                          vcat (map ppr_gen_tycon (filter isLocallyDefined tcs)),
+                          vcat (map ppr_gen_tycon tcs),
                           ptext SLIT("#-}")
                     ]