[project @ 1998-01-08 18:03:08 by simonm]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcModule.lhs
index 8c57967..1855672 100644 (file)
@@ -4,67 +4,56 @@
 \section[TcModule]{Typechecking a whole module}
 
 \begin{code}
-#include "HsVersions.h"
-
 module TcModule (
        typecheckModule,
-       SYN_IE(TcResults),
-       SYN_IE(TcSpecialiseRequests),
-       SYN_IE(TcDDumpDeriv)
+       TcResults,
+       TcDDumpDeriv
     ) where
 
-IMP_Ubiq(){-uitous-}
+#include "HsVersions.h"
 
 import CmdLineOpts     ( opt_D_dump_tc, opt_D_dump_deriv )
-import HsSyn           ( HsDecl(..), HsModule(..), HsBinds(..), HsExpr, MonoBinds(..),
-                         TyDecl, SpecDataSig, ClassDecl, InstDecl, IfaceSig,
-                         SpecInstSig, DefaultDecl, Sig, Fake, InPat,
-                         SYN_IE(RecFlag), nonRecursive,  GRHSsAndBinds, Match,
-                         FixityDecl, IE, ImportDecl, OutPat
-                       )
-import RnHsSyn         ( SYN_IE(RenamedHsModule), RenamedFixityDecl(..) )
-import TcHsSyn         ( SYN_IE(TypecheckedHsBinds), SYN_IE(TypecheckedHsExpr),
-                         SYN_IE(TypecheckedDictBinds), SYN_IE(TcMonoBinds),
-                         SYN_IE(TypecheckedMonoBinds),
+import HsSyn           ( HsModule(..), HsBinds(..), MonoBinds(..), HsDecl(..) )
+import RnHsSyn         ( RenamedHsModule, RenamedFixityDecl(..) )
+import TcHsSyn         ( TypecheckedHsBinds, TypecheckedHsExpr,
+                         TypecheckedDictBinds, TcMonoBinds,
+                         TypecheckedMonoBinds,
                          zonkTopBinds )
 
 import TcMonad
 import Inst            ( Inst, emptyLIE, plusLIE )
-import TcBinds         ( tcBindsAndThen )
+import TcBinds         ( tcTopBindsAndThen )
 import TcClassDcl      ( tcClassDecls2 )
 import TcDefaults      ( tcDefaults )
-import TcEnv           ( tcExtendGlobalValEnv, getEnv_LocalIds,
+import TcEnv           ( TcIdOcc(..), tcExtendGlobalValEnv, tcExtendTyConEnv, getEnv_LocalIds,
                          getEnv_TyCons, getEnv_Classes, tcLookupLocalValue,
                          tcLookupLocalValueByKey, tcLookupTyCon,
                          tcLookupGlobalValueByKeyMaybe )
-import SpecEnv         ( SpecEnv )
 import TcExpr          ( tcId )
 import TcIfaceSig      ( tcInterfaceSigs )
 import TcInstDcls      ( tcInstDecls1, tcInstDecls2 )
-import TcInstUtil      ( buildInstanceEnvs, InstInfo )
+import TcInstUtil      ( buildInstanceEnvs, classDataCon, InstInfo )
 import TcSimplify      ( tcSimplifyTop )
 import TcTyClsDecls    ( tcTyAndClassDecls1 )
 import TcTyDecls       ( mkDataBinds )
-import TcType          ( TcIdOcc(..), SYN_IE(TcType), tcInstType )
-import TcKind          ( TcKind )
+import TcType          ( TcType, tcInstType )
+import TcKind          ( TcKind, kindToTcKind )
 
 import RnMonad         ( RnNameSupply(..) )
-import Bag             ( listToBag )
-import ErrUtils                ( SYN_IE(Warning), SYN_IE(Error), 
+import Bag             ( isEmptyBag )
+import ErrUtils                ( WarnMsg, ErrMsg, 
                          pprBagOfErrors, dumpIfSet, ghcExit
                        )
-import Id              ( idType, GenId, SYN_IE(IdEnv), nullIdEnv )
+import Id              ( idType, GenId, IdEnv, nullIdEnv )
 import Maybes          ( catMaybes, MaybeErr(..) )
-import Name            ( Name, isLocallyDefined, pprModule )
-import Pretty
-import TyCon           ( TyCon, isSynTyCon )
-import Class           ( GenClass, SYN_IE(Class), classSelIds )
-import Type            ( applyTyCon, mkSynTy, SYN_IE(Type) )
-import PprType         ( GenType, GenTyVar )
+import Name            ( Name, isLocallyDefined, pprModule, NamedThing(..) )
+import TyCon           ( TyCon, isSynTyCon, tyConKind )
+import Class           ( Class, classSelIds, classTyCon )
+import Type            ( mkTyConApp, mkSynTy, Type )
+import TyVar           ( emptyTyVarEnv )
 import TysWiredIn      ( unitTy )
 import PrelMods                ( gHC_MAIN, mAIN )
 import PrelInfo                ( main_NAME, ioTyCon_NAME )
-import TyVar           ( GenTyVar, SYN_IE(TyVarEnv), nullTyVarEnv )
 import Unify           ( unifyTauTy )
 import UniqFM          ( lookupUFM_Directly, lookupWithDefaultUFM_Directly,
                          filterUFM, eltsUFM )
@@ -72,38 +61,21 @@ import Unique               ( Unique  )
 import UniqSupply       ( UniqSupply )
 import Util
 import Bag             ( Bag, isEmptyBag )
-
 import FiniteMap       ( emptyFM, FiniteMap )
-
-import Outputable      ( Outputable(..), PprStyle, printErrs, pprDumpStyle, pprErrorsStyle )
-
-tycon_specs = emptyFM
+import Outputable
 \end{code}
 
 Outside-world interface:
 \begin{code}
---ToDo: put this in HsVersions
-#if __GLASGOW_HASKELL__ >= 200
-# define REAL_WORLD RealWorld
-#else
-# define REAL_WORLD _RealWorld
-#endif
-
 
 -- Convenient type synonyms first:
 type TcResults
   = (TypecheckedMonoBinds,
      [TyCon], [Class],
      Bag InstInfo,             -- Instance declaration information
-     TcSpecialiseRequests,
      TcDDumpDeriv)
 
-type TcSpecialiseRequests
-  = FiniteMap TyCon [(Bool, [Maybe Type])]
-    -- source tycon specialisation requests
-
-type TcDDumpDeriv
-  = PprStyle -> Doc
+type TcDDumpDeriv = SDoc
 
 ---------------
 typecheckModule
@@ -113,26 +85,30 @@ typecheckModule
        -> IO (Maybe TcResults)
 
 typecheckModule us rn_name_supply mod
-  = case initTc us (tcModule rn_name_supply mod) of
-       Failed (errs, warns) ->
-         print_errs warns      >>
-         print_errs errs       >>
-         return Nothing
-
-       Succeeded (results@(binds, _, _, _, _, dump_deriv), warns) -> 
-         print_errs warns                      >>
+  = let
+      (maybe_result, warns, errs) = initTc us (tcModule rn_name_supply mod)
+    in
+    print_errs warns   >>
+    print_errs errs    >>
 
-         dumpIfSet opt_D_dump_tc "Typechecked"
-               (ppr pprDumpStyle binds)                >>
+    dumpIfSet opt_D_dump_tc "Typechecked"
+       (case maybe_result of
+           Just (binds, _, _, _, _) -> ppr binds
+           Nothing                  -> text "Typecheck failed")        >>
 
-         dumpIfSet opt_D_dump_deriv "Derived instances"
-               (dump_deriv pprDumpStyle)               >>
+    dumpIfSet opt_D_dump_deriv "Derived instances"
+       (case maybe_result of
+           Just (_, _, _, _, dump_deriv) -> dump_deriv
+           Nothing                       -> empty)     >>
 
-         return (Just results)
+    return (if isEmptyBag errs then 
+               maybe_result 
+           else 
+               Nothing)
 
 print_errs errs
   | isEmptyBag errs = return ()
-  | otherwise       = printErrs (pprBagOfErrors pprErrorsStyle errs)
+  | otherwise       = printErrs (pprBagOfErrors errs)
 \end{code}
 
 The internal monster:
@@ -165,10 +141,10 @@ tcModule rn_name_supply
                tcSetEnv env (
                -- trace "tcInstDecls:" $
                tcInstDecls1 unf_env decls mod_name rn_name_supply
-               )                                       `thenTc` \ (inst_info, deriv_binds, ddump_deriv) ->
+               )                               `thenTc` \ (inst_info, deriv_binds, ddump_deriv) ->
     
                -- trace "tc4" $
-               buildInstanceEnvs inst_info     `thenTc` \ inst_mapper ->
+               buildInstanceEnvs inst_info     `thenNF_Tc` \ inst_mapper ->
     
                returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv)
     
@@ -185,8 +161,10 @@ tcModule rn_name_supply
        -- Create any necessary record selector Ids and their bindings
        -- "Necessary" includes data and newtype declarations
        let
-           tycons   = getEnv_TyCons env
-           classes  = getEnv_Classes env
+           tycons       = getEnv_TyCons env
+           classes      = getEnv_Classes env
+           local_tycons  = filter isLocallyDefined tycons
+           local_classes = filter isLocallyDefined classes
        in
        mkDataBinds tycons              `thenTc` \ (data_ids, data_binds) ->
        
@@ -198,6 +176,15 @@ tcModule rn_name_supply
        tcExtendGlobalValEnv data_ids                           $
        tcExtendGlobalValEnv (concat (map classSelIds classes)) $
 
+       -- Extend the TyCon envt with the tycons corresponding to
+       -- the classes, and the global value environment with the
+       -- corresponding data cons.
+       --  They are mentioned in types in interface files.
+       tcExtendGlobalValEnv (map classDataCon classes)         $
+        tcExtendTyConEnv [ (getName tycon, (kindToTcKind (tyConKind tycon), Nothing, tycon))
+                        | clas <- classes,
+                          let tycon = classTyCon clas
+                        ]                              $
 
            -- Interface type signatures
            -- We tie a knot so that the Ids read out of interfaces are in scope
@@ -212,7 +199,7 @@ tcModule rn_name_supply
        -- Value declarations next.
        -- We also typecheck any extra binds that came out of the "deriving" process
         -- trace "tcBinds:"                    $
-       tcBindsAndThen
+       tcTopBindsAndThen
            (\ is_rec binds1 (binds2, thing) -> (binds1 `AndMonoBinds` binds2, thing))
            (get_val_decls decls `ThenBinds` deriv_binds)
            (   tcGetEnv                `thenNF_Tc` \ env ->
@@ -256,27 +243,12 @@ tcModule rn_name_supply
        in
        zonkTopBinds all_binds  `thenNF_Tc` \ (all_binds', really_final_env)  ->
 
-       returnTc (really_final_env, (all_binds', inst_info, ddump_deriv))
+       returnTc (really_final_env, 
+                 (all_binds', local_tycons, local_classes, inst_info, ddump_deriv))
 
     -- End of outer fix loop
-    ) `thenTc` \ (final_env, (all_binds', inst_info, ddump_deriv)) ->
-
-
-    let
-       tycons   = getEnv_TyCons   final_env
-       classes  = getEnv_Classes  final_env
-
-       local_tycons  = filter isLocallyDefined tycons
-       local_classes = filter isLocallyDefined classes
-    in
-       -- FINISHED AT LAST
-    returnTc (
-       all_binds',
-
-       local_tycons, local_classes, inst_info, tycon_specs,
-
-       ddump_deriv
-    )
+    ) `thenTc` \ (final_env, stuff) ->
+    returnTc stuff
 
 get_val_decls decls = foldr ThenBinds EmptyBinds [binds | ValD binds <- decls]
 \end{code}
@@ -292,32 +264,34 @@ tcCheckMainSig mod_name
     tcLookupTyCon ioTyCon_NAME         `thenTc`    \ (_,_,ioTyCon) ->
     tcLookupLocalValue main_NAME       `thenNF_Tc` \ maybe_main_id ->
     case maybe_main_id of {
-       Nothing  -> failTc noMainErr;
+       Nothing  -> failWithTc noMainErr ;
        Just main_id   ->
 
        -- Check that it has the right type (or a more general one)
-    let expected_ty = applyTyCon ioTyCon [unitTy] in
-    tcInstType [] expected_ty          `thenNF_Tc` \ expected_tau ->
-    tcId main_NAME                     `thenNF_Tc` \ (_, lie, main_tau) ->
+    let 
+       expected_ty = mkTyConApp ioTyCon [unitTy]
+    in
+    tcInstType emptyTyVarEnv expected_ty       `thenNF_Tc` \ expected_tau ->
+    tcId main_NAME                             `thenNF_Tc` \ (_, lie, main_tau) ->
     tcSetErrCtxt mainTyCheckCtxt $
     unifyTauTy expected_tau
               main_tau                 `thenTc_`
     checkTc (isEmptyBag lie) (mainTyMisMatch expected_ty (idType main_id))
     }
 
-mainTyCheckCtxt sty
-  = hsep [ptext SLIT("When checking that"), ppr sty main_NAME, 
-         ptext SLIT("has the required type")]
 
-noMainErr sty
-  = hsep [ptext SLIT("Module"), pprModule sty mAIN, 
-          ptext SLIT("must include a definition for"), ppr sty main_NAME]
+mainTyCheckCtxt
+  = hsep [ptext SLIT("When checking that"), ppr main_NAME, ptext SLIT("has the required type")]
+
+noMainErr
+  = hsep [ptext SLIT("Module"), quotes (pprModule mAIN), 
+         ptext SLIT("must include a definition for"), quotes (ppr main_NAME)]
 
-mainTyMisMatch :: Type -> TcType s -> Error
-mainTyMisMatch expected actual sty
-  = hang (hsep [ppr sty main_NAME, ptext SLIT("has the wrong type")])
+mainTyMisMatch :: Type -> TcType s -> ErrMsg
+mainTyMisMatch expected actual
+  = hang (hsep [ppr main_NAME, ptext SLIT("has the wrong type")])
         4 (vcat [
-                       hsep [ptext SLIT("Expected:"), ppr sty expected],
-                       hsep [ptext SLIT("Inferred:"), ppr sty actual]
+                       hsep [ptext SLIT("Expected:"), ppr expected],
+                       hsep [ptext SLIT("Inferred:"), ppr actual]
                     ])
 \end{code}