[project @ 2005-03-31 10:16:33 by simonmar]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcRnDriver.lhs
index 5bd681a..8f9dad4 100644 (file)
@@ -7,7 +7,8 @@
 module TcRnDriver (
 #ifdef GHCI
        mkExportEnv, getModuleContents, tcRnStmt, 
-       tcRnGetInfo, tcRnExpr, tcRnType,
+       tcRnGetInfo, GetInfoResult,
+       tcRnExpr, tcRnType,
 #endif
        tcRnModule, 
        tcTopSrcDecls,
@@ -16,14 +17,15 @@ module TcRnDriver (
 
 #include "HsVersions.h"
 
+import IO
 #ifdef GHCI
 import {-# SOURCE #-} TcSplice ( tcSpliceDecls )
 #endif
 
-import CmdLineOpts     ( DynFlag(..), opt_PprStyle_Debug, dopt )
+import DynFlags                ( DynFlag(..), DynFlags(..), dopt, GhcMode(..) )
+import StaticFlags     ( opt_PprStyle_Debug )
 import Packages                ( moduleToPackageConfig, mkPackageId, package,
                          isHomeModule )
-import DriverState     ( v_MainModIs, v_MainFunIs )
 import HsSyn           ( HsModule(..), HsExtCore(..), HsGroup(..), LHsDecl, SpliceDecl(..), HsBind(..),
                          nlHsApp, nlHsVar, pprLHsBinds )
 import RdrHsSyn                ( findSplice )
@@ -59,7 +61,7 @@ import ErrUtils               ( Messages, mkDumpDoc, showPass )
 import Id              ( mkExportedLocalId, isLocalId, idName, idType )
 import Var             ( Var )
 import VarEnv          ( varEnvElts )
-import Module           ( Module, ModuleEnv, mkModule, moduleEnvElts )
+import Module           ( Module, ModuleEnv, mkModule, moduleEnvElts, lookupModuleEnv )
 import OccName         ( mkVarOcc )
 import Name            ( Name, isExternalName, getSrcLoc, getOccName, isWiredInName )
 import NameSet
@@ -67,7 +69,7 @@ import TyCon          ( tyConHasGenerics, isSynTyCon, getSynTyConDefn, tyConKind )
 import SrcLoc          ( srcLocSpan, Located(..), noLoc )
 import DriverPhases    ( HscSource(..), isHsBoot )
 import HscTypes                ( ModGuts(..), HscEnv(..), ExternalPackageState(..),
-                         GhciMode(..), IsBootInterface, noDependencies, 
+                         IsBootInterface, noDependencies, 
                          Deprecs( NoDeprecs ), plusDeprecs,
                          ForeignStubs(NoStubs), TyThing(..), 
                          TypeEnv, lookupTypeEnv, hptInstances, lookupType,
@@ -98,14 +100,15 @@ import TcType              ( Type, mkForAllTys, mkFunTys, mkTyConApp, tyVarsOfType,
 import TcEnv           ( tcLookupTyCon, tcLookupId, tcLookupGlobal )
 import RnTypes         ( rnLHsType )
 import Inst            ( tcStdSyntaxName, tcGetInstEnvs )
-import InstEnv         ( classInstances, instEnvElts )
+import InstEnv         ( DFunId, classInstances, instEnvElts )
 import RnExpr          ( rnStmts, rnLExpr )
 import RnNames         ( exportsToAvails )
 import LoadIface       ( loadSrcInterface, ifaceInstGates )
 import IfaceSyn                ( IfaceDecl(..), IfaceClassOp(..), IfaceConDecl(..), 
                          IfaceExtName(..), IfaceConDecls(..), IfaceInst(..),
                          tyThingToIfaceDecl, dfunToIfaceInst )
-import IfaceType       ( IfaceTyCon(..), ifPrintUnqual )
+import IfaceType       ( IfaceTyCon(..), IfaceType, toIfaceType, 
+                         interactiveExtNameFun, isLocalIfaceExtName )
 import IfaceEnv                ( lookupOrig )
 import RnEnv           ( lookupOccRn, dataTcOccs, lookupFixityRn )
 import Id              ( Id, isImplicitId, setIdType, globalIdDetails )
@@ -117,10 +120,10 @@ import IdInfo             ( GlobalIdDetails(..) )
 import SrcLoc          ( interactiveSrcLoc, unLoc )
 import Kind            ( Kind )
 import Var             ( globaliseId )
-import Name            ( nameOccName, nameModule )
+import Name            ( nameOccName )
+import OccName         ( occNameUserString )
 import NameEnv         ( delListFromNameEnv )
 import PrelNames       ( iNTERACTIVE, ioTyConName, printName, monadNames, itName, returnIOName )
-import Module          ( lookupModuleEnv )
 import HscTypes                ( InteractiveContext(..), HomeModInfo(..), typeEnvElts, typeEnvClasses,
                          availNames, availName, ModIface(..), icPrintUnqual,
                          ModDetails(..), Dependencies(..) )
@@ -169,16 +172,22 @@ tcRnModule hsc_env hsc_src (L loc (HsModule maybe_mod export_ies
                -- Deal with imports; sets tcg_rdr_env, tcg_imports
        (rdr_env, imports) <- rnImports import_decls ;
 
+       let { dep_mods :: ModuleEnv (Module, IsBootInterface)
+           ; dep_mods = imp_dep_mods imports
+
+           ; is_dep_mod :: Module -> Bool
+           ; is_dep_mod mod = case lookupModuleEnv dep_mods mod of
+                               Nothing           -> False
+                               Just (_, is_boot) -> not is_boot 
+           ; home_insts = hptInstances hsc_env is_dep_mod
+           } ;
+
                -- Record boot-file info in the EPS, so that it's 
                -- visible to loadHiBootInterface in tcRnSrcDecls,
                -- and any other incrementally-performed imports
-       let { dep_mods :: ModuleEnv (Module, IsBootInterface)
-           ; dep_mods = imp_dep_mods imports } ;
-
        updateEps_ (\eps -> eps { eps_is_boot = dep_mods }) ;
 
                -- Update the gbl env
-       let { home_insts = hptInstances hsc_env (moduleEnvElts dep_mods) } ;
        updGblEnv ( \ gbl -> 
                gbl { tcg_rdr_env  = rdr_env,
                      tcg_inst_env = extendInstEnvList (tcg_inst_env gbl) home_insts,
@@ -228,7 +237,7 @@ tcRnModule hsc_env hsc_src (L loc (HsModule maybe_mod export_ies
             } ;
 
                -- Report unused names
-       reportUnusedNames final_env ;
+       reportUnusedNames export_ies final_env ;
 
                -- Dump output and return
        tcDump final_env ;
@@ -469,16 +478,14 @@ tcRnHsBootDecls decls
 
                -- Typecheck value declarations
        ; traceTc (text "Tc5") 
-       ; (tc_val_binds, lcl_env) <- tcHsBootSigs (hs_valds rn_group)
+       ; new_ids <- tcHsBootSigs (hs_valds rn_group)
 
                -- Wrap up
                -- No simplification or zonking to do
        ; traceTc (text "Tc7a")
        ; gbl_env <- getGblEnv 
        
-       ; let { new_ids = [ id | ATcId id _ _ <- varEnvElts (tcl_env lcl_env) ]
-             ; final_type_env = extendTypeEnvWithIds (tcg_type_env gbl_env) new_ids }
-
+       ; let { final_type_env = extendTypeEnvWithIds (tcg_type_env gbl_env) new_ids }
        ; return (gbl_env { tcg_type_env = final_type_env }) 
    }}}}
 
@@ -692,13 +699,11 @@ tcTopSrcDecls boot_names
 checkMain 
   = do { ghci_mode <- getGhciMode ;
         tcg_env   <- getGblEnv ;
-
-        mb_main_mod <- readMutVar v_MainModIs ;
-        mb_main_fn  <- readMutVar v_MainFunIs ;
-        let { main_mod = case mb_main_mod of {
+        dflags    <- getDOpts ;
+        let { main_mod = case mainModIs dflags of {
                                Just mod -> mkModule mod ;
                                Nothing  -> mAIN } ;
-              main_fn  = case mb_main_fn of {
+              main_fn  = case mainFunIs dflags of {
                                Just fn -> mkRdrUnqual (mkVarOcc (mkFastString fn)) ;
                                Nothing -> main_RDR_Unqual } } ;
        
@@ -767,9 +772,10 @@ check_main ghci_mode tcg_env main_mod main_fn
 setInteractiveContext :: HscEnv -> InteractiveContext -> TcRn a -> TcRn a
 setInteractiveContext hsc_env icxt thing_inside 
   = let 
-       root_modules :: [(Module, IsBootInterface)]
-       root_modules = [(mkModule m, False) | m <- ic_toplev_scope icxt]
-       dfuns        = hptInstances hsc_env root_modules
+       -- Initialise the tcg_inst_env with instances 
+       -- from all home modules.  This mimics the more selective
+       -- call to hptInstances in tcRnModule
+       dfuns = hptInstances hsc_env (\mod -> True)
     in
     updGblEnv (\env -> env { 
        tcg_rdr_env  = ic_rn_gbl_env icxt,
@@ -1072,12 +1078,11 @@ vanillaProv mod = Imported [ImportSpec mod mod False
 \begin{code}
 getModuleContents
   :: HscEnv
-  -> InteractiveContext
   -> Module                    -- Module to inspect
   -> Bool                      -- Grab just the exports, or the whole toplev
   -> IO (Maybe [IfaceDecl])
 
-getModuleContents hsc_env ictxt mod exports_only
+getModuleContents hsc_env mod exports_only
  = initTcPrintErrors hsc_env iNTERACTIVE (get_mod_contents exports_only)
  where
    get_mod_contents exports_only
@@ -1085,7 +1090,7 @@ getModuleContents hsc_env ictxt mod exports_only
                          -- so it had better be a home module
       = do { hpt <- getHpt
           ; case lookupModuleEnv hpt mod of
-              Just mod_info -> return (map toIfaceDecl $
+              Just mod_info -> return (map (toIfaceDecl ext_nm) $
                                        filter wantToSee $
                                        typeEnvElts $
                                        md_types (hm_details mod_info))
@@ -1102,7 +1107,9 @@ getModuleContents hsc_env ictxt mod exports_only
    get_decl (mod, avail)
        = do { main_name <- lookupOrig mod (availName avail) 
             ; thing     <- tcLookupGlobal main_name
-            ; return (filter_decl (availNames avail) (toIfaceDecl thing)) }
+            ; return (filter_decl (availNames avail) (toIfaceDecl ext_nm thing)) }
+
+   ext_nm = interactiveExtNameFun (icPrintUnqual (hsc_IC hsc_env))
 
 ---------------------
 filter_decl occs decl@(IfaceClass {ifSigs = sigs})
@@ -1133,18 +1140,21 @@ noRdrEnvErr mod = ptext SLIT("No top-level environment available for module")
 \end{code}
 
 \begin{code}
+type GetInfoResult = (String, IfaceDecl, Fixity, SrcLoc, 
+                             [(IfaceType,SrcLoc)]      -- Instances
+                    )
+
 tcRnGetInfo :: HscEnv
            -> InteractiveContext
            -> RdrName
-           -> IO (Maybe [(IfaceDecl, 
-                          Fixity, SrcLoc, 
-                          [(IfaceInst, SrcLoc)])])
+           -> IO (Maybe [GetInfoResult])
+
 -- Used to implemnent :info in GHCi
 --
 -- Look up a RdrName and return all the TyThings it might be
 -- A capitalised RdrName is given to us in the DataName namespace,
 -- but we want to treat it as *both* a data constructor 
--- *and* as a type or class constructor; 
+--  *and* as a type or class constructor; 
 -- hence the call to dataTcOccs, and we return up to two results
 tcRnGetInfo hsc_env ictxt rdr_name
   = initTcPrintErrors hsc_env iNTERACTIVE $ 
@@ -1180,9 +1190,17 @@ tcRnGetInfo hsc_env ictxt rdr_name
        -- their parent declaration
     let { do_one name = do { thing  <- tcLookupGlobal name
                           ; fixity <- lookupFixityRn name
-                          ; insts  <- lookupInsts print_unqual thing
-                          ; return (toIfaceDecl thing, fixity, 
-                                    getSrcLoc thing, insts) } } ;
+                          ; dfuns  <- lookupInsts ext_nm thing
+                          ; return (str, toIfaceDecl ext_nm thing, fixity, 
+                                    getSrcLoc thing, 
+                                    [(toIfaceType ext_nm (idType dfun), getSrcLoc dfun) | dfun <- dfuns]
+                            ) } 
+               where
+                       -- str is the the naked occurrence name
+                       -- after stripping off qualification and parens (+)
+                 str = occNameUserString (nameOccName name)
+       } ;
+
                -- For the SrcLoc, the 'thing' has better info than
                -- the 'name' because getting the former forced the
                -- declaration to be loaded into the cache
@@ -1191,56 +1209,51 @@ tcRnGetInfo hsc_env ictxt rdr_name
     return (fst (removeDups cmp results))
     }
   where
-    cmp (d1,_,_,_) (d2,_,_,_) = ifName d1 `compare` ifName d2
+    cmp (_,d1,_,_,_) (_,d2,_,_,_) = ifName d1 `compare` ifName d2
+    ext_nm = interactiveExtNameFun (icPrintUnqual ictxt)
 
-    print_unqual :: PrintUnqualified
-    print_unqual = icPrintUnqual ictxt
 
-
-lookupInsts :: PrintUnqualified -> TyThing -> TcM [(IfaceInst, SrcLoc)]
+lookupInsts :: (Name -> IfaceExtName) -> TyThing -> TcM [DFunId]
 -- Filter the instances by the ones whose tycons (or clases resp) 
 -- are in scope unqualified.  Otherwise we list a whole lot too many!
-lookupInsts print_unqual (AClass cls)
+lookupInsts ext_nm (AClass cls)
   = do { loadImportedInsts cls []      -- [] means load all instances for cls
        ; inst_envs <- tcGetInstEnvs
-       ; return [ (inst, getSrcLoc dfun)
+       ; return [ dfun
                 | (_,_,dfun) <- classInstances inst_envs cls
-                , let inst = dfunToIfaceInst dfun
-                      (_, tycons) = ifaceInstGates (ifInstHead inst)
+                , let (_, tycons) = ifaceInstGates (ifInstHead (dfunToIfaceInst ext_nm dfun))
+                       -- Rather an indirect/inefficient test, but there we go
                 , all print_tycon_unqual tycons ] }
   where
-    print_tycon_unqual (IfaceTc ext_nm) = ifPrintUnqual print_unqual ext_nm
+    print_tycon_unqual (IfaceTc nm) = isLocalIfaceExtName nm
     print_tycon_unqual other           = True  -- Int etc
    
 
-lookupInsts print_unqual (ATyCon tc)
+lookupInsts ext_nm (ATyCon tc)
   = do         { eps <- getEps -- Load all instances for all classes that are
                        -- in the type environment (which are all the ones
                        -- we've seen in any interface file so far)
        ; mapM_ (\c -> loadImportedInsts c [])
                (typeEnvClasses (eps_PTE eps))
        ; (pkg_ie, home_ie) <- tcGetInstEnvs    -- Search all
-       ; return [ (inst, getSrcLoc dfun)
+       ; return [ dfun
                 | (_, _, dfun) <- instEnvElts home_ie ++ instEnvElts pkg_ie
                 , relevant dfun
-                , let inst     = dfunToIfaceInst dfun
-                      (cls, _) = ifaceInstGates (ifInstHead inst)
-                , ifPrintUnqual print_unqual cls ]  }
+                , let (cls, _) = ifaceInstGates (ifInstHead (dfunToIfaceInst ext_nm dfun))
+                , isLocalIfaceExtName cls ]  }
   where
     relevant df = tc_name `elemNameSet` tyClsNamesOfDFunHead (idType df)
     tc_name     = tyConName tc           
 
-lookupInsts print_unqual other = return []
+lookupInsts ext_nm other = return []
 
 
-toIfaceDecl :: TyThing -> IfaceDecl
-toIfaceDecl thing
+toIfaceDecl :: (Name -> IfaceExtName) -> TyThing -> IfaceDecl
+toIfaceDecl ext_nm thing
   = tyThingToIfaceDecl True            -- Discard IdInfo
                       emptyNameSet     -- Show data cons
                       ext_nm (munge thing)
   where
-    ext_nm n = ExtPkg (nameModule n) (nameOccName n)
-
        -- munge transforms a thing to its "parent" thing
     munge (ADataCon dc) = ATyCon (dataConTyCon dc)
     munge (AnId id) = case globalIdDetails id of
@@ -1248,7 +1261,6 @@ toIfaceDecl thing
                        ClassOpId cls      -> AClass cls
                        other              -> AnId id
     munge other_thing = other_thing
-
 #endif /* GHCI */
 \end{code}