[project @ 2000-10-31 12:07:43 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / Rename.lhs
index 0b7449a..f080bd9 100644 (file)
@@ -4,46 +4,49 @@
 \section[Rename]{Renaming and dependency analysis passes}
 
 \begin{code}
-module Rename ( renameModule, closeIfaceDecls ) where
+module Rename ( renameModule, closeIfaceDecls, checkOldIface ) where
 
 #include "HsVersions.h"
 
 import HsSyn
 import RdrHsSyn                ( RdrNameHsModule, RdrNameHsDecl, RdrNameDeprecation, 
-                         RdrNameTyClDecl, RdrNameRuleDecl, RdrNameInstDecl
+                         RdrNameTyClDecl, RdrNameRuleDecl, RdrNameInstDecl, RdrNameImportDecl
                        )
 import RnHsSyn         ( RenamedHsDecl, RenamedTyClDecl, RenamedRuleDecl, RenamedInstDecl,
                          extractHsTyNames, 
                          instDeclFVs, tyClDeclFVs, ruleDeclFVs
                        )
 
-import CmdLineOpts     ( DynFlags, DynFlag(..) )
+import CmdLineOpts     ( DynFlags, DynFlag(..), dopt )
 import RnMonad
 import RnNames         ( getGlobalNames )
 import RnSource                ( rnSourceDecls, rnTyClDecl, rnIfaceRuleDecl, rnInstDecl )
 import RnIfaces                ( slurpImpDecls, mkImportInfo, 
                          getInterfaceExports, closeDecls,
-                         RecompileRequired, recompileRequired
+                         RecompileRequired, outOfDate, recompileRequired
                        )
-import RnHiFiles       ( findAndReadIface, removeContext, loadExports, loadFixDecls, loadDeprecs )
-import RnEnv           ( availName, availsToNameSet, 
-                         emptyAvailEnv, unitAvailEnv, availEnvElts, plusAvailEnv, sortAvails,
+import RnHiFiles       ( readIface, removeContext, 
+                         loadExports, loadFixDecls, loadDeprecs )
+import RnEnv           ( availName, 
+                         emptyAvailEnv, unitAvailEnv, availEnvElts, plusAvailEnv, groupAvails,
                          warnUnusedImports, warnUnusedLocalBinds, warnUnusedModules,
                          lookupOrigNames, lookupGlobalRn, newGlobalName
                        )
 import Module           ( Module, ModuleName, WhereFrom(..),
-                         moduleNameUserString, moduleName, 
-                         lookupModuleEnv
+                         moduleNameUserString, moduleName,
+                         mkModuleInThisPackage, mkModuleName, moduleEnvElts
                        )
-import Name            ( Name, isLocallyDefined, NamedThing(..), getSrcLoc,
+import Name            ( Name, NamedThing(..), getSrcLoc,
+                         nameIsLocalOrFrom,
                          nameOccName, nameModule,
-                         mkNameEnv, nameEnvElts, extendNameEnv
                        )
+import Name            ( mkNameEnv, nameEnvElts, extendNameEnv )
+import RdrName         ( elemRdrEnv )
 import OccName         ( occNameFlavour )
 import NameSet
 import TysWiredIn      ( unitTyCon, intTyCon, boolTyCon )
 import PrelNames       ( mAIN_Name, pREL_MAIN_Name, pRELUDE_Name,
-                         ioTyCon_RDR,
+                         ioTyCon_RDR, main_RDR,
                          unpackCString_RDR, unpackCStringFoldr_RDR, unpackCStringUtf8_RDR,
                          eqString_RDR
                        )
@@ -51,19 +54,19 @@ import PrelInfo             ( derivingOccurrences )
 import Type            ( funTyCon )
 import ErrUtils                ( dumpIfSet )
 import Bag             ( bagToList )
-import FiniteMap       ( FiniteMap, eltsFM, fmToList, emptyFM, lookupFM, 
+import FiniteMap       ( FiniteMap, fmToList, emptyFM, lookupFM, 
                          addToFM_C, elemFM, addToFM
                        )
 import UniqFM          ( lookupUFM )
 import Maybes          ( maybeToBool, catMaybes )
 import Outputable
 import IO              ( openFile, IOMode(..) )
-import HscTypes                ( Finder, PersistentCompilerState, HomeIfaceTable, HomeSymbolTable, 
+import HscTypes                ( PersistentCompilerState, HomeIfaceTable, HomeSymbolTable, 
                          ModIface(..), WhatsImported(..), 
                          VersionInfo(..), ImportVersion, IfaceDecls(..),
-                         GlobalRdrEnv, AvailEnv, Avails, GenAvailInfo(..), AvailInfo, 
+                         GlobalRdrEnv, AvailEnv, GenAvailInfo(..), AvailInfo, 
                          Provenance(..), ImportReason(..), initialVersionInfo,
-                         Deprecations(..), lookupDeprec
+                         Deprecations(..), lookupDeprec, lookupIface
                         )
 import List            ( partition, nub )
 \end{code}
@@ -77,18 +80,18 @@ import List         ( partition, nub )
 %*********************************************************
 
 \begin{code}
-renameModule :: DynFlags -> Finder 
+renameModule :: DynFlags
             -> HomeIfaceTable -> HomeSymbolTable
             -> PersistentCompilerState 
             -> Module -> RdrNameHsModule 
             -> IO (PersistentCompilerState, Maybe (ModIface, [RenamedHsDecl]))
        -- Nothing => some error occurred in the renamer
 
-renameModule dflags finder hit hst old_pcs this_module rdr_module
+renameModule dflags hit hst old_pcs this_module rdr_module
   =    -- Initialise the renamer monad
     do {
        (new_pcs, errors_found, maybe_rn_stuff) 
-          <- initRn dflags finder hit hst old_pcs this_module (rename this_module rdr_module) ;
+          <- initRn dflags hit hst old_pcs this_module (rename this_module rdr_module) ;
 
        -- Return results.  No harm in updating the PCS
        if errors_found then
@@ -100,18 +103,21 @@ renameModule dflags finder hit hst old_pcs this_module rdr_module
 
 \begin{code}
 rename :: Module -> RdrNameHsModule -> RnMG (Maybe (ModIface, [RenamedHsDecl]))
-rename this_module this_mod@(HsModule mod_name vers exports imports local_decls mod_deprec loc)
-  =    -- FIND THE GLOBAL NAME ENVIRONMENT
-    getGlobalNames this_mod                    `thenRn` \ maybe_stuff ->
+rename this_module contents@(HsModule _ _ _ imports local_decls mod_deprec loc)
+  = pushSrcLocRn loc           $
 
-       -- CHECK FOR EARLY EXIT
-    case maybe_stuff of {
-       Nothing ->      -- Everything is up to date; no need to recompile further
-               rnDump [] []            `thenRn_`
-               returnRn Nothing ;
-
-       Just (gbl_env, local_gbl_env, export_avails, global_avail_env) ->
+       -- FIND THE GLOBAL NAME ENVIRONMENT
+    getGlobalNames this_module contents        `thenRn` \ (gbl_env, local_gbl_env, 
+                                                           export_avails, global_avail_env) ->
 
+       -- Exit if we've found any errors
+    checkErrsRn                                `thenRn` \ no_errs_so_far ->
+    if not no_errs_so_far then
+       -- Found errors already, so exit now
+       rnDump [] []            `thenRn_`
+       returnRn Nothing 
+    else
+       
        -- DEAL WITH DEPRECATIONS
     rnDeprecs local_gbl_env mod_deprec 
              [d | DeprecD d <- local_decls]            `thenRn` \ my_deprecs ->
@@ -124,6 +130,9 @@ rename this_module this_mod@(HsModule mod_name vers exports imports local_decls
        rnSourceDecls local_decls
     )                                  `thenRn` \ (rn_local_decls, source_fvs) ->
 
+       -- CHECK THAT main IS DEFINED, IF REQUIRED
+    checkMain this_module local_gbl_env                `thenRn_`
+
        -- SLURP IN ALL THE NEEDED DECLARATIONS
     implicitFVs mod_name rn_local_decls        `thenRn` \ implicit_fvs -> 
     let
@@ -151,47 +160,53 @@ rename this_module this_mod@(HsModule mod_name vers exports imports local_decls
     else
 
        -- GENERATE THE VERSION/USAGE INFO
-    mkImportInfo mod_name imports      `thenRn` \ my_usages ->
+    mkImportInfo mod_name imports                      `thenRn` \ my_usages ->
 
-       -- RETURN THE RENAMED MODULE
-    getNameSupplyRn                    `thenRn` \ name_supply ->
-    getIfacesRn                        `thenRn` \ ifaces ->
+       -- BUILD THE MODULE INTERFACE
     let
-       direct_import_mods :: [ModuleName]
-       direct_import_mods = nub [m | ImportDecl m _ _ _ _ _ <- imports]
-
        -- We record fixities even for things that aren't exported,
        -- so that we can change into the context of this moodule easily
        fixities = mkNameEnv [ (name, fixity)
                             | FixitySig name fixity loc <- nameEnvElts local_fixity_env
                             ]
 
-
        -- Sort the exports to make them easier to compare for versions
-       my_exports = sortAvails export_avails
+       my_exports = groupAvails this_module export_avails
        
+       final_decls = rn_local_decls ++ rn_imp_decls
+       is_orphan   = any (isOrphanDecl this_module) rn_local_decls
+
        mod_iface = ModIface {  mi_module   = this_module,
                                mi_version  = initialVersionInfo,
-                               mi_orphan   = any isOrphanDecl rn_local_decls,
+                               mi_usages = my_usages,
+                               mi_boot     = False,
+                               mi_orphan   = is_orphan,
                                mi_exports  = my_exports,
                                mi_globals  = gbl_env,
-                               mi_usages   = my_usages,
                                mi_fixities = fixities,
                                mi_deprecs  = my_deprecs,
                                mi_decls    = panic "mi_decls"
                    }
-
-       final_decls = rn_local_decls ++ rn_imp_decls
     in
 
        -- REPORT UNUSED NAMES, AND DEBUG DUMP 
-    reportUnusedNames mod_name direct_import_mods
-                     gbl_env global_avail_env
-                     export_avails source_fvs
-                     rn_imp_decls                      `thenRn_`
+    reportUnusedNames mod_iface imports global_avail_env
+                     real_source_fvs rn_imp_decls      `thenRn_`
 
     returnRn (Just (mod_iface, final_decls))
-    }
+  where
+    mod_name = moduleName this_module
+\end{code}
+
+Checking that main is defined
+
+\begin{code}
+checkMain :: Module -> GlobalRdrEnv -> RnMG ()
+checkMain this_mod local_env
+  | moduleName this_mod == mAIN_Name 
+  = checkRn (main_RDR `elemRdrEnv` local_env) noMainErr
+  | otherwise
+  = returnRn ()
 \end{code}
 
 @implicitFVs@ forces the renamer to slurp in some things which aren't
@@ -237,20 +252,21 @@ implicitFVs mod_name decls
 \end{code}
 
 \begin{code}
-isOrphanDecl (InstD (InstDecl inst_ty _ _ _ _))
-  = not (foldNameSet ((||) . isLocallyDefined) False (extractHsTyNames (removeContext inst_ty)))
+isOrphanDecl this_mod (InstD (InstDecl inst_ty _ _ _ _))
+  = not (foldNameSet ((||) . nameIsLocalOrFrom this_mod) False 
+                    (extractHsTyNames (removeContext inst_ty)))
        -- The 'removeContext' is because of
        --      instance Foo a => Baz T where ...
        -- The decl is an orphan if Baz and T are both not locally defined,
        --      even if Foo *is* locally defined
 
-isOrphanDecl (RuleD (HsRule _ _ _ lhs _ _))
+isOrphanDecl this_mod (RuleD (HsRule _ _ _ lhs _ _))
   = check lhs
   where
        -- At the moment we just check for common LHS forms
        -- Expand as necessary.  Getting it wrong just means
        -- more orphans than necessary
-    check (HsVar v)      = not (isLocallyDefined v)
+    check (HsVar v)      = not (nameIsLocalOrFrom this_mod v)
     check (HsApp f a)    = check f && check a
     check (HsLit _)      = False
     check (HsOverLit _)          = False
@@ -262,7 +278,7 @@ isOrphanDecl (RuleD (HsRule _ _ _ lhs _ _))
 
     check other                  = True        -- Safe fall through
 
-isOrphanDecl other = False
+isOrphanDecl _ _  = False
 \end{code}
 
 
@@ -339,7 +355,7 @@ rnDeprecs gbl_env Nothing decls
      = pushSrcLocRn loc                        $
        lookupGlobalRn gbl_env rdr_name `thenRn` \ maybe_name ->
        case maybe_name of
-        Just n  -> returnRn (Just (n,txt))
+        Just n  -> returnRn (Just (n,(n,txt)))
         Nothing -> returnRn Nothing
 \end{code}
 
@@ -351,53 +367,64 @@ rnDeprecs gbl_env Nothing decls
 %************************************************************************
 
 \begin{code}
-checkOldIface :: DynFlags -> Finder
+checkOldIface :: DynFlags
              -> HomeIfaceTable -> HomeSymbolTable
              -> PersistentCompilerState
-             -> Module 
+             -> FilePath
              -> Bool                   -- Source unchanged
              -> Maybe ModIface         -- Old interface from compilation manager, if any
              -> IO (PersistentCompilerState, Bool, (RecompileRequired, Maybe ModIface))
                                -- True <=> errors happened
 
-checkOldIface dflags finder hit hst pcs mod source_unchanged maybe_iface
-  = initRn dflags finder hit hst pcs mod $
-       
-       -- Load the old interface file, if we havn't already got it
-    loadOldIface mod maybe_iface                       `thenRn` \ maybe_iface ->
-
-       -- Check versions
-    recompileRequired mod source_unchanged maybe_iface `thenRn` \ recompile ->
-
-    returnRn (recompile, maybe_iface)
+checkOldIface dflags hit hst pcs iface_path source_unchanged maybe_iface
+  = case maybe_iface of
+       Just old_iface -> -- Use the one we already have
+                         startRn (mi_module old_iface) $ 
+                         check_versions old_iface
+       Nothing -- try and read it from a file
+          -> do read_result <- readIface do_traceRn iface_path
+                case read_result of
+                   Left err -> -- Old interface file not found, or garbled; give up
+                               return (pcs, False, (outOfDate, Nothing))
+                   Right parsed_iface
+                      -> startRn (pi_mod parsed_iface) $
+                         loadOldIface parsed_iface `thenRn` \ m_iface ->
+                         check_versions m_iface
+    where
+       check_versions :: ModIface -> RnMG (RecompileRequired, Maybe ModIface)
+       check_versions iface
+          = -- Check versions
+            recompileRequired iface_path source_unchanged iface
+                                                       `thenRn` \ recompile ->
+            returnRn (recompile, Just iface)
+
+       do_traceRn     = dopt Opt_D_dump_rn_trace dflags
+       ioTraceRn sdoc = if do_traceRn then printErrs sdoc else return ()
+       startRn mod     = initRn dflags hit hst pcs mod
 \end{code}
 
+I think the following function should now have a more representative name,
+but what?
 
 \begin{code}
-loadOldIface :: Module -> Maybe ModIface -> RnMG (Maybe ModIface)
-loadOldIface mod (Just iface) 
-  = returnRn (Just iface)
-
-loadOldIface mod Nothing
-  =    -- LOAD THE OLD INTERFACE FILE
-    findAndReadIface doc_str (moduleName mod) False {- Not hi-boot -}  `thenRn` \ read_result ->
-    case read_result of {
-       Left err ->     -- Old interface file not found, or garbled, so we'd better bail out
-                   traceRn (vcat [ptext SLIT("No old interface file:"), err])  `thenRn_`
-                   returnRn Nothing ;
+loadOldIface :: ParsedIface -> RnMG ModIface
 
-       Right (_, iface) ->
-
-       -- RENAME IT
+loadOldIface parsed_iface
+  = let iface = parsed_iface 
+    in -- RENAME IT
+    let mod = pi_mod iface
+        doc_str = ptext SLIT("need usage info from") <+> ppr mod
+    in
     initIfaceRnMS mod (
        loadHomeDecls (pi_decls iface)  `thenRn` \ decls ->
        loadHomeRules (pi_rules iface)  `thenRn` \ rules -> 
        loadHomeInsts (pi_insts iface)  `thenRn` \ insts ->
        returnRn (decls, rules, insts)
-    )                          `thenRn` \ ((decls_vers, new_decls), (rule_vers, new_rules), new_insts) ->
+    )  
+       `thenRn` \ ((decls_vers, new_decls), (rule_vers, new_rules), new_insts) ->
 
     mapRn loadHomeUsage        (pi_usages iface)       `thenRn` \ usages ->
-    loadExports        (pi_exports iface)      `thenRn` \ (export_vers, avails) ->
+    loadExports         (pi_exports iface)     `thenRn` \ (export_vers, avails) ->
     loadFixDecls mod   (pi_fixity iface)       `thenRn` \ fix_env ->
     loadDeprecs mod    (pi_deprecs iface)      `thenRn` \ deprec_env ->
     let
@@ -411,19 +438,14 @@ loadOldIface mod Nothing
                             dcl_insts = new_insts }
 
        mod_iface = ModIface { mi_module = mod, mi_version = version,
-                              mi_exports = avails, mi_orphan = pi_orphan iface,
+                              mi_exports = avails, mi_usages  = usages,
+                              mi_boot = False, mi_orphan = pi_orphan iface, 
                               mi_fixities = fix_env, mi_deprecs = deprec_env,
-                              mi_usages  = usages,
                               mi_decls   = decls,
                               mi_globals = panic "No mi_globals in old interface"
                    }
     in
-    returnRn (Just mod_iface)
-    }
-
-    
-  where
-    doc_str = ptext SLIT("need usage info from") <+> ppr mod
+    returnRn mod_iface
 \end{code}
 
 \begin{code}
@@ -477,15 +499,15 @@ Suppose we discover we don't need to recompile.   Then we start from the
 IfaceDecls in the ModIface, and fluff them up by sucking in all the decls they need.
 
 \begin{code}
-closeIfaceDecls :: DynFlags -> Finder
+closeIfaceDecls :: DynFlags
                -> HomeIfaceTable -> HomeSymbolTable
                -> PersistentCompilerState
                -> ModIface     -- Get the decls from here
                -> IO (PersistentCompilerState, Bool, [RenamedHsDecl])
                                -- True <=> errors happened
-closeIfaceDecls dflags finder hit hst pcs
+closeIfaceDecls dflags hit hst pcs
                mod_iface@(ModIface { mi_module = mod, mi_decls = iface_decls })
-  = initRn dflags finder hit hst pcs mod $
+  = initRn dflags hit hst pcs mod $
 
     let
        rule_decls = dcl_rules iface_decls
@@ -508,23 +530,24 @@ closeIfaceDecls dflags finder hit hst pcs
 %*********************************************************
 
 \begin{code}
-reportUnusedNames :: ModuleName -> [ModuleName] 
-                 -> GlobalRdrEnv -> AvailEnv
-                 -> Avails -> NameSet -> [RenamedHsDecl] 
+reportUnusedNames :: ModIface -> [RdrNameImportDecl] 
+                 -> AvailEnv
+                 -> NameSet 
+                 -> [RenamedHsDecl] 
                  -> RnMG ()
-reportUnusedNames mod_name direct_import_mods 
-                 gbl_env avail_env 
-                 export_avails mentioned_names
-                 imported_decls
+reportUnusedNames my_mod_iface imports avail_env 
+                 used_names imported_decls
   = warnUnusedModules unused_imp_mods                          `thenRn_`
     warnUnusedLocalBinds bad_locals                            `thenRn_`
     warnUnusedImports bad_imp_names                            `thenRn_`
-    printMinimalImports mod_name minimal_imports               `thenRn_`
-    warnDeprecations really_used_names                         `thenRn_`
+    printMinimalImports this_mod minimal_imports               `thenRn_`
+    warnDeprecations this_mod my_deprecs really_used_names     `thenRn_`
     returnRn ()
 
   where
-    used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
+    this_mod   = mi_module my_mod_iface
+    gbl_env    = mi_globals my_mod_iface
+    my_deprecs = mi_deprecs my_mod_iface
     
     -- Now, a use of C implies a use of T,
     -- if C was brought into scope by T(..) or T(C)
@@ -603,7 +626,10 @@ reportUnusedNames mod_name direct_import_mods
       | otherwise      = addToFM acc m emptyAvailEnv
        -- Add an empty collection of imports for a module
        -- from which we have sucked only instance decls
-    
+   
+    direct_import_mods :: [ModuleName]
+    direct_import_mods = nub [m | ImportDecl m _ _ _ _ _ <- imports]
+
     -- unused_imp_mods are the directly-imported modules 
     -- that are not mentioned in minimal_imports
     unused_imp_mods = [m | m <- direct_import_mods,
@@ -614,7 +640,7 @@ reportUnusedNames mod_name direct_import_mods
     module_unused mod = moduleName mod `elem` unused_imp_mods
 
 
-warnDeprecations used_names
+warnDeprecations this_mod my_deprecs used_names
   = doptRn Opt_WarnDeprecations                                `thenRn` \ warn_drs ->
     if not warn_drs then returnRn () else
 
@@ -630,16 +656,15 @@ warnDeprecations used_names
 
   where
     lookup_deprec hit pit n
-       = case lookupModuleEnv hit mod of
-               Just iface -> lookupDeprec iface n
-               Nothing    -> case lookupModuleEnv pit mod of
-                               Just iface -> lookupDeprec iface n
-                               Nothing    -> pprPanic "warnDeprecations:" (ppr n)
-       where
-         mod = nameModule n
+       | nameIsLocalOrFrom this_mod n
+       = lookupDeprec my_deprecs n 
+       | otherwise
+       = case lookupIface hit pit this_mod n of
+               Just iface -> lookupDeprec (mi_deprecs iface) n
+               Nothing    -> pprPanic "warnDeprecations:" (ppr n)
 
 -- ToDo: deal with original imports with 'qualified' and 'as M' clauses
-printMinimalImports mod_name imps
+printMinimalImports this_mod imps
   = doptRn Opt_D_dump_minimal_imports          `thenRn` \ dump_minimal ->
     if not dump_minimal then returnRn () else
 
@@ -649,7 +674,7 @@ printMinimalImports mod_name imps
        })                                      `thenRn_`
     returnRn ()
   where
-    filename = moduleNameUserString mod_name ++ ".imports"
+    filename = moduleNameUserString (moduleName this_mod) ++ ".imports"
     ppr_mod_ie (mod_name, ies) 
        | mod_name == pRELUDE_Name 
        = empty
@@ -664,13 +689,18 @@ printMinimalImports mod_name imps
     to_ie (Avail n)       = returnRn (IEVar n)
     to_ie (AvailTC n [m]) = ASSERT( n==m ) 
                            returnRn (IEThingAbs n)
-    to_ie (AvailTC n ns)  = getInterfaceExports (moduleName (nameModule n)) 
-                                               ImportBySystem          `thenRn` \ (_, avails) ->
-                           case [ms | AvailTC m ms <- avails, m == n] of
-                             [ms] | all (`elem` ns) ms -> returnRn (IEThingAll n)
-                                  | otherwise          -> returnRn (IEThingWith n (filter (/= n) ns))
-                             other -> pprTrace "to_ie" (ppr n <+> ppr (nameModule n) <+> ppr other) $
-                                      returnRn (IEVar n)
+    to_ie (AvailTC n ns)  
+       = getInterfaceExports n_mod ImportBySystem              `thenRn` \ (_, avails_by_module) ->
+         case [xs | (m,as) <- avails_by_module,
+                    m == n_mod,
+                    AvailTC x xs <- as, 
+                    x == n] of
+             [xs] | all (`elem` ns) xs -> returnRn (IEThingAll n)
+                  | otherwise          -> returnRn (IEThingWith n (filter (/= n) ns))
+             other                     -> pprTrace "to_ie" (ppr n <+> ppr (nameModule n) <+> ppr other) $
+                                          returnRn (IEVar n)
+       where
+         n_mod = moduleName (nameModule n)
 
 rnDump  :: [RenamedHsDecl]     -- Renamed imported decls
        -> [RenamedHsDecl]      -- Renamed local decls
@@ -678,7 +708,7 @@ rnDump  :: [RenamedHsDecl]  -- Renamed imported decls
 rnDump imp_decls local_decls
   = doptRn Opt_D_dump_rn_trace         `thenRn` \ dump_rn_trace ->
     doptRn Opt_D_dump_rn_stats         `thenRn` \ dump_rn_stats ->
-    doptRn Opt_D_dump_rn               `thenRn` \ dump_rn ->
+    doptRn Opt_D_dump_rn       `thenRn` \ dump_rn ->
     getIfacesRn                        `thenRn` \ ifaces ->
 
     ioToRnM (do { dumpIfSet (dump_rn_trace || dump_rn_stats || dump_rn)
@@ -704,14 +734,14 @@ getRnStats :: [RenamedHsDecl] -> Ifaces -> SDoc
 getRnStats imported_decls ifaces
   = hcat [text "Renamer stats: ", stats]
   where
-    n_mods = length [() | (_, _, True) <- eltsFM (iImpModInfo ifaces)]
+    n_mods = length [() | _ <- moduleEnvElts (iPIT ifaces)]
+       -- This is really only right for a one-shot compile
     
-    decls_read     = [decl | (avail, True, (_,decl)) <- nameEnvElts (iDecls ifaces),
+    decls_read     = [decl | (avail, True, (_,decl)) <- nameEnvElts (iDecls ifaces)
                        -- Data, newtype, and class decls are in the decls_fm
                        -- under multiple names; the tycon/class, and each
                        -- constructor/class op too.
                        -- The 'True' selects just the 'main' decl
-                        not (isLocallyDefined (availName avail))
                     ]
     
     (cd_rd, dd_rd, nd_rd, sd_rd, vd_rd)        = countTyClDecls decls_read
@@ -781,6 +811,10 @@ dupFixityDecl rdr_name loc1 loc2
 badDeprec d
   = sep [ptext SLIT("Illegal deprecation when whole module is deprecated"),
         nest 4 (ppr d)]
+
+noMainErr
+  = hsep [ptext SLIT("Module"), quotes (ppr mAIN_Name), 
+         ptext SLIT("must include a definition for"), quotes (ptext SLIT("main"))]
 \end{code}