Merge Haddock comment support from ghc.haddock -- big patch
[ghc-hetmet.git] / compiler / main / GHC.hs
index 3f91af6..dab148a 100644 (file)
@@ -11,13 +11,11 @@ module GHC (
        Session,
        defaultErrorHandler,
        defaultCleanupHandler,
-       init, initFromArgs,
        newSession,
 
        -- * Flags and settings
        DynFlags(..), DynFlag(..), Severity(..), GhcMode(..), HscTarget(..), dopt,
        parseDynamicFlags,
-       initPackages,
        getSessionDynFlags,
        setSessionDynFlags,
 
@@ -29,6 +27,12 @@ module GHC (
        removeTarget,
        guessTarget,
        
+        -- * Extending the program scope 
+        extendGlobalRdrScope,  -- :: Session -> [GlobalRdrElt] -> IO ()
+        setGlobalRdrScope,     -- :: Session -> [GlobalRdrElt] -> IO ()
+        extendGlobalTypeScope, -- :: Session -> [Id] -> IO ()
+        setGlobalTypeScope,    -- :: Session -> [Id] -> IO ()
+
        -- * Loading\/compiling the program
        depanal,
        load, LoadHowMuch(..), SuccessFlag(..), -- also does depanal
@@ -36,8 +40,11 @@ module GHC (
        checkModule, CheckedModule(..),
        TypecheckedSource, ParsedSource, RenamedSource,
 
+       -- * Parsing Haddock comments
+       parseHaddockComment,
+
        -- * Inspecting the module structure of the program
-       ModuleGraph, ModSummary(..), ModLocation(..),
+       ModuleGraph, ModSummary(..), ms_mod_name, ModLocation(..),
        getModuleGraph,
        isLoaded,
        topSortModuleGraph,
@@ -59,6 +66,7 @@ module GHC (
 
        -- * Interactive evaluation
        getBindings, getPrintUnqual,
+        findModule,
 #ifdef GHCI
        setContext, getContext, 
        getNamesInScope,
@@ -71,14 +79,18 @@ module GHC (
        RunResult(..),
        runStmt,
        showModule,
-       compileExpr, HValue,
+       compileExpr, HValue, dynCompileExpr,
        lookupName,
 #endif
 
        -- * Abstract syntax elements
 
+        -- ** Packages
+        PackageId,
+
        -- ** Modules
-       Module, mkModule, pprModule,
+       Module, mkModule, pprModule, moduleName, modulePackageId,
+        ModuleName, mkModuleName, moduleNameString,
 
        -- ** Names
        Name, 
@@ -100,7 +112,8 @@ module GHC (
        TyCon, 
        tyConTyVars, tyConDataCons, tyConArity,
        isClassTyCon, isSynTyCon, isNewTyCon, isPrimTyCon, isFunTyCon,
-       synTyConDefn, synTyConRhs,
+       isOpenTyCon,
+       synTyConDefn, synTyConType, synTyConResKind,
 
        -- ** Type variables
        TyVar,
@@ -155,8 +168,6 @@ module GHC (
  ToDo:
 
   * inline bits of HscMain here to simplify layering: hscTcExpr, hscStmt.
-  * we need to expose DynFlags, so should parseDynamicFlags really be
-    part of this interface?
   * what StaticFlags should we expose, if any?
 -}
 
@@ -164,13 +175,15 @@ module GHC (
 
 #ifdef GHCI
 import qualified Linker
+import Data.Dynamic     ( Dynamic )
 import Linker          ( HValue, extendLinkEnv )
 import TcRnDriver      ( tcRnLookupRdrName, tcRnGetInfo,
                          tcRnLookupName, getModuleExports )
 import RdrName         ( plusGlobalRdrEnv, Provenance(..), 
                          ImportSpec(..), ImpDeclSpec(..), ImpItemSpec(..),
-                         emptyGlobalRdrEnv, mkGlobalRdrEnv )
+                         mkGlobalRdrEnv )
 import HscMain         ( hscParseIdentifier, hscStmt, hscTcExpr, hscKcType )
+import Name            ( nameOccName )
 import Type            ( tidyType )
 import VarEnv          ( emptyTidyEnv )
 import GHC.Exts                ( unsafeCoerce# )
@@ -179,8 +192,9 @@ import GHC.Exts             ( unsafeCoerce# )
 import Packages                ( initPackages )
 import NameSet         ( NameSet, nameSetToList, elemNameSet )
 import RdrName         ( GlobalRdrEnv, GlobalRdrElt(..), RdrName(..), 
-                         globalRdrEnvElts )
-import HsSyn
+                         globalRdrEnvElts, extendGlobalRdrEnv,
+                          emptyGlobalRdrEnv )
+import HsSyn 
 import Type            ( Kind, Type, dropForAlls, PredType, ThetaType,
                          pprThetaArrow, pprParendType, splitForAllTys,
                          funResultTy )
@@ -193,15 +207,16 @@ import Id         ( Id, idType, isImplicitId, isDeadBinder,
 import Var             ( TyVar )
 import TysPrim         ( alphaTyVars )
 import TyCon           ( TyCon, isClassTyCon, isSynTyCon, isNewTyCon,
-                         isPrimTyCon, isFunTyCon, tyConArity,
-                         tyConTyVars, tyConDataCons, synTyConDefn, synTyConRhs )
+                         isPrimTyCon, isFunTyCon, isOpenTyCon, tyConArity,
+                         tyConTyVars, tyConDataCons, synTyConDefn,
+                         synTyConType, synTyConResKind )
 import Class           ( Class, classSCTheta, classTvsFds, classMethods )
 import FunDeps         ( pprFundeps )
 import DataCon         ( DataCon, dataConWrapId, dataConSig, dataConTyCon,
                          dataConFieldLabels, dataConStrictMarks, 
                          dataConIsInfix, isVanillaDataCon )
 import Name            ( Name, nameModule, NamedThing(..), nameParent_maybe,
-                         nameSrcLoc, nameOccName )
+                         nameSrcLoc )
 import OccName         ( parenSymOcc )
 import NameEnv         ( nameEnvElts )
 import InstEnv         ( Instance, instanceDFunId, pprInstance, pprInstanceHdr )
@@ -209,27 +224,31 @@ import SrcLoc
 import DriverPipeline
 import DriverPhases    ( Phase(..), isHaskellSrcFilename, startPhase )
 import HeaderInfo      ( getImports, getOptions )
-import Packages                ( isHomePackage )
 import Finder
 import HscMain         ( newHscEnv, hscFileCheck, HscChecked(..) )
 import HscTypes
 import DynFlags
-import SysTools                ( initSysTools, cleanTempFiles )
+import SysTools     ( initSysTools, cleanTempFiles, cleanTempFilesExcept,
+                      cleanTempDirs )
 import Module
+import UniqFM
+import PackageConfig    ( PackageId, stringToPackageId )
 import FiniteMap
 import Panic
 import Digraph
-import Bag             ( unitBag )
+import Bag             ( unitBag, listToBag )
 import ErrUtils                ( Severity(..), showPass, fatalErrorMsg, debugTraceMsg,
-                         mkPlainErrMsg, printBagOfErrors, printErrorsAndWarnings )
+                         mkPlainErrMsg, printBagOfErrors, printBagOfWarnings,
+                         WarnMsg )
 import qualified ErrUtils
 import Util
 import StringBuffer    ( StringBuffer, hGetStringBuffer )
 import Outputable
-import SysTools                ( cleanTempFilesExcept )
 import BasicTypes
 import TcType           ( tcSplitSigmaTy, isDictTy )
 import Maybes          ( expectJust, mapCatMaybes )
+import HaddockParse     ( parseHaddockParagraphs, parseHaddockString )
+import HaddockLex       ( tokenise )
 
 import Control.Concurrent
 import System.Directory ( getModificationTime, doesFileExist )
@@ -296,55 +315,30 @@ defaultErrorHandler dflags inner =
 -- handling, but still get the ordinary cleanup behaviour.
 defaultCleanupHandler :: DynFlags -> IO a -> IO a
 defaultCleanupHandler dflags inner = 
-   -- make sure we clean up after ourselves
-   later (unless (dopt Opt_KeepTmpFiles dflags) $ 
-           cleanTempFiles dflags) 
-       -- exceptions will be blocked while we clean the temporary files,
-       -- so there shouldn't be any difficulty if we receive further
-       -- signals.
-   inner
-
-
--- | Initialises GHC.  This must be done /once/ only.  Takes the
--- TopDir path without the '-B' prefix.
-
-init :: Maybe String -> IO ()
-init mbMinusB = do
-   -- catch ^C
-   main_thread <- myThreadId
-   putMVar interruptTargetThread [main_thread]
-   installSignalHandlers
-
-   dflags0 <- initSysTools mbMinusB defaultDynFlags
-   writeIORef v_initDynFlags dflags0
-
--- | Initialises GHC. This must be done /once/ only. Takes the
--- command-line arguments.  All command-line arguments which aren't
--- understood by GHC will be returned.
-
-initFromArgs :: [String] -> IO [String]
-initFromArgs args
-    = do init mbMinusB
-         return argv1
-    where -- Grab the -B option if there is one
-          (minusB_args, argv1) = partition (prefixMatch "-B") args
-          mbMinusB | null minusB_args
-                       = Nothing
-                   | otherwise
-                       = Just (drop 2 (last minusB_args))
-
-GLOBAL_VAR(v_initDynFlags, error "initDynFlags", DynFlags)
-       -- stores the DynFlags between the call to init and subsequent
-       -- calls to newSession.
+    -- make sure we clean up after ourselves
+    later (unless (dopt Opt_KeepTmpFiles dflags) $
+               do cleanTempFiles dflags
+                  cleanTempDirs dflags
+          )
+          -- exceptions will be blocked while we clean the temporary files,
+          -- so there shouldn't be any difficulty if we receive further
+          -- signals.
+    inner
+
 
 -- | Starts a new session.  A session consists of a set of loaded
 -- modules, a set of options (DynFlags), and an interactive context.
 -- ToDo: GhcMode should say "keep typechecked code" and\/or "keep renamed
 -- code".
-newSession :: GhcMode -> IO Session
-newSession mode = do
-  dflags0 <- readIORef v_initDynFlags
-  dflags <- initDynFlags dflags0
+newSession :: GhcMode -> Maybe FilePath -> IO Session
+newSession mode mb_top_dir = do
+  -- catch ^C
+  main_thread <- myThreadId
+  putMVar interruptTargetThread [main_thread]
+  installSignalHandlers
+
+  dflags0 <- initSysTools mb_top_dir defaultDynFlags
+  dflags  <- initDynFlags dflags0
   env <- newHscEnv dflags{ ghcMode=mode }
   ref <- newIORef env
   return (Session ref)
@@ -367,9 +361,23 @@ modifySession (Session ref) f = do h <- readIORef ref; writeIORef ref $! f h
 getSessionDynFlags :: Session -> IO DynFlags
 getSessionDynFlags s = withSession s (return . hsc_dflags)
 
--- | Updates the DynFlags in a Session
-setSessionDynFlags :: Session -> DynFlags -> IO ()
-setSessionDynFlags s dflags = modifySession s (\h -> h{ hsc_dflags = dflags })
+-- | Updates the DynFlags in a Session.  This also reads
+-- the package database (unless it has already been read),
+-- and prepares the compilers knowledge about packages.  It
+-- can be called again to load new packages: just add new
+-- package flags to (packageFlags dflags).
+--
+-- Returns a list of new packages that may need to be linked in using
+-- the dynamic linker (see 'linkPackages') as a result of new package
+-- flags.  If you are not doing linking or doing static linking, you
+-- can ignore the list of packages returned.
+--
+setSessionDynFlags :: Session -> DynFlags -> IO [PackageId]
+setSessionDynFlags (Session ref) dflags = do
+  hsc_env <- readIORef ref
+  (dflags', preload) <- initPackages dflags
+  writeIORef ref $! hsc_env{ hsc_dflags = dflags' }
+  return preload
 
 -- | If there is no -o option, guess the name of target executable
 -- by using top-level source file name as a base.
@@ -441,17 +449,48 @@ guessTarget file Nothing
        if exists
           then return (Target (TargetFile lhs_file Nothing) Nothing)
           else do
-       return (Target (TargetModule (mkModule file)) Nothing)
+       return (Target (TargetModule (mkModuleName file)) Nothing)
      where 
         hs_file  = file `joinFileExt` "hs"
         lhs_file = file `joinFileExt` "lhs"
 
 -- -----------------------------------------------------------------------------
+-- Extending the program scope
+
+extendGlobalRdrScope :: Session -> [GlobalRdrElt] -> IO ()
+extendGlobalRdrScope session rdrElts
+    = modifySession session $ \hscEnv ->
+      let global_rdr = hsc_global_rdr_env hscEnv
+      in hscEnv{ hsc_global_rdr_env = foldl extendGlobalRdrEnv global_rdr rdrElts }
+
+setGlobalRdrScope :: Session -> [GlobalRdrElt] -> IO ()
+setGlobalRdrScope session rdrElts
+    = modifySession session $ \hscEnv ->
+      hscEnv{ hsc_global_rdr_env = foldl extendGlobalRdrEnv emptyGlobalRdrEnv rdrElts }
+
+extendGlobalTypeScope :: Session -> [Id] -> IO ()
+extendGlobalTypeScope session ids
+    = modifySession session $ \hscEnv ->
+      let global_type = hsc_global_type_env hscEnv
+      in hscEnv{ hsc_global_type_env = extendTypeEnvWithIds global_type ids }
+
+setGlobalTypeScope :: Session -> [Id] -> IO ()
+setGlobalTypeScope session ids
+    = modifySession session $ \hscEnv ->
+      hscEnv{ hsc_global_type_env = extendTypeEnvWithIds emptyTypeEnv ids }
+
+-- -----------------------------------------------------------------------------
+-- Parsing Haddock comments
+
+parseHaddockComment :: String -> Either String (HsDoc RdrName)
+parseHaddockComment string = parseHaddockParagraphs (tokenise string)
+
+-- -----------------------------------------------------------------------------
 -- Loading the program
 
 -- Perform a dependency analysis starting from the current targets
 -- and update the session with the new module graph.
-depanal :: Session -> [Module] -> Bool -> IO (Maybe ModuleGraph)
+depanal :: Session -> [ModuleName] -> Bool -> IO (Maybe ModuleGraph)
 depanal (Session ref) excluded_mods allow_dup_roots = do
   hsc_env <- readIORef ref
   let
@@ -462,7 +501,7 @@ depanal (Session ref) excluded_mods allow_dup_roots = do
        
   showPass dflags "Chasing dependencies"
   when (gmode == BatchCompile) $
-       debugTraceMsg dflags 1 (hcat [
+       debugTraceMsg dflags 2 (hcat [
                     text "Chasing modules from: ",
                        hcat (punctuate comma (map pprTarget targets))])
 
@@ -490,8 +529,8 @@ data ErrMsg = ErrMsg {
 
 data LoadHowMuch
    = LoadAllTargets
-   | LoadUpTo Module
-   | LoadDependenciesOf Module
+   | LoadUpTo ModuleName
+   | LoadDependenciesOf ModuleName
 
 -- | Try to load the program.  If a Module is supplied, then just
 -- attempt to load up to this target.  If no Module is supplied,
@@ -520,10 +559,11 @@ load2 s@(Session ref) how_much mod_graph = do
        -- B.hs-boot in the module graph, but no B.hs
        -- The downsweep should have ensured this does not happen
        -- (see msDeps)
-        let all_home_mods = [ms_mod s | s <- mod_graph, not (isBootSummary s)]
+        let all_home_mods = [ms_mod_name s 
+                           | s <- mod_graph, not (isBootSummary s)]
 #ifdef DEBUG
            bad_boot_mods = [s        | s <- mod_graph, isBootSummary s,
-                                       not (ms_mod s `elem` all_home_mods)]
+                                       not (ms_mod_name s `elem` all_home_mods)]
 #endif
        ASSERT( null bad_boot_mods ) return ()
 
@@ -535,6 +575,11 @@ load2 s@(Session ref) how_much mod_graph = do
         let mg2_with_srcimps :: [SCC ModSummary]
            mg2_with_srcimps = topSortModuleGraph True mod_graph Nothing
 
+       -- If we can determine that any of the {-# SOURCE #-} imports
+       -- are definitely unnecessary, then emit a warning.
+       warnUnnecessarySourceImports dflags mg2_with_srcimps
+
+       let
            -- check the stability property for each module.
            stable_mods@(stable_obj,stable_bco)
                | BatchCompile <- ghci_mode = ([],[])
@@ -554,7 +599,7 @@ load2 s@(Session ref) how_much mod_graph = do
        -- Unload any modules which are going to be re-linked this time around.
        let stable_linkables = [ linkable
                               | m <- stable_obj++stable_bco,
-                                Just hmi <- [lookupModuleEnv pruned_hpt m],
+                                Just hmi <- [lookupUFM pruned_hpt m],
                                 Just linkable <- [hm_linkable hmi] ]
        unload hsc_env stable_linkables
 
@@ -591,7 +636,7 @@ load2 s@(Session ref) how_much mod_graph = do
            partial_mg
                | LoadDependenciesOf mod <- how_much
                = ASSERT( case last partial_mg0 of 
-                           AcyclicSCC ms -> ms_mod ms == mod; _ -> False )
+                           AcyclicSCC ms -> ms_mod_name ms == mod; _ -> False )
                  List.init partial_mg0
                | otherwise
                = partial_mg0
@@ -599,9 +644,9 @@ load2 s@(Session ref) how_much mod_graph = do
            stable_mg = 
                [ AcyclicSCC ms
                | AcyclicSCC ms <- full_mg,
-                 ms_mod ms `elem` stable_obj++stable_bco,
-                 ms_mod ms `notElem` [ ms_mod ms' | 
-                                       AcyclicSCC ms' <- partial_mg ] ]
+                 ms_mod_name ms `elem` stable_obj++stable_bco,
+                 ms_mod_name ms `notElem` [ ms_mod_name ms' | 
+                                               AcyclicSCC ms' <- partial_mg ] ]
 
            mg = stable_mg ++ partial_mg
 
@@ -647,7 +692,7 @@ load2 s@(Session ref) how_much mod_graph = do
              when (ghci_mode == BatchCompile && isJust ofile && not do_linking) $
                debugTraceMsg dflags 1 (text ("Warning: output was redirected with -o, " ++
                                              "but no output will be generated\n" ++
-                                             "because there is no " ++ moduleString main_mod ++ " module."))
+                                             "because there is no " ++ moduleNameString (moduleName main_mod) ++ " module."))
 
              -- link everything together
               linkresult <- link ghci_mode dflags do_linking (hsc_HPT hsc_env1)
@@ -669,7 +714,7 @@ load2 s@(Session ref) how_much mod_graph = do
                      = filter ((`notElem` mods_to_zap_names).ms_mod) 
                          modsDone
 
-              let hpt4 = retainInTopLevelEnvs (map ms_mod mods_to_keep) 
+              let hpt4 = retainInTopLevelEnvs (map ms_mod_name mods_to_keep) 
                                              (hsc_HPT hsc_env1)
 
              -- Clean up after ourselves
@@ -677,7 +722,7 @@ load2 s@(Session ref) how_much mod_graph = do
 
              -- there should be no Nothings where linkables should be, now
              ASSERT(all (isJust.hm_linkable) 
-                       (moduleEnvElts (hsc_HPT hsc_env))) do
+                       (eltsUFM (hsc_HPT hsc_env))) do
        
              -- Link everything together
               linkresult <- link ghci_mode dflags False hpt4
@@ -728,7 +773,8 @@ data CheckedModule =
        --  fields within CheckedModule.
 
 type ParsedSource      = Located (HsModule RdrName)
-type RenamedSource     = (HsGroup Name, [LImportDecl Name], Maybe [LIE Name])
+type RenamedSource     = (HsGroup Name, [LImportDecl Name], Maybe [LIE Name],
+                          Maybe (HsDoc Name), HaddockModInfo Name)
 type TypecheckedSource = LHsBinds Id
 
 -- NOTE:
@@ -748,7 +794,7 @@ type TypecheckedSource = LHsBinds Id
 -- for a module.  'checkModule' loads all the dependencies of the specified
 -- module in the Session, and then attempts to typecheck the module.  If
 -- successful, it returns the abstract syntax for the module.
-checkModule :: Session -> Module -> IO (Maybe CheckedModule)
+checkModule :: Session -> ModuleName -> IO (Maybe CheckedModule)
 checkModule session@(Session ref) mod = do
        -- load up the dependencies first
    r <- load session (LoadDependenciesOf mod)
@@ -757,7 +803,7 @@ checkModule session@(Session ref) mod = do
        -- now parse & typecheck the module
    hsc_env <- readIORef ref   
    let mg  = hsc_mod_graph hsc_env
-   case [ ms | ms <- mg, ms_mod ms == mod ] of
+   case [ ms | ms <- mg, ms_mod_name ms == mod ] of
        [] -> return Nothing
        (ms:_) -> do 
           mbChecked <- hscFileCheck hsc_env{hsc_dflags=ms_hspp_opts ms} ms
@@ -853,9 +899,9 @@ unload hsc_env stable_linkables     -- Unload everthing *except* 'stable_linkables'
 checkStability
        :: HomePackageTable             -- HPT from last compilation
        -> [SCC ModSummary]             -- current module graph (cyclic)
-       -> [Module]                     -- all home modules
-       -> ([Module],                   -- stableObject
-           [Module])                   -- stableBCO
+       -> [ModuleName]                 -- all home modules
+       -> ([ModuleName],               -- stableObject
+           [ModuleName])               -- stableBCO
 
 checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
   where
@@ -865,7 +911,7 @@ checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
      | otherwise     = (stable_obj, stable_bco)
      where
        scc = flattenSCC scc0
-       scc_mods = map ms_mod scc
+       scc_mods = map ms_mod_name scc
        home_module m   = m `elem` all_home_mods && m `notElem` scc_mods
 
         scc_allimps = nub (filter home_module (concatMap ms_allimps scc))
@@ -887,7 +933,7 @@ checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
                                         && same_as_prev t
          | otherwise = False
          where
-            same_as_prev t = case lookupModuleEnv hpt (ms_mod ms) of
+            same_as_prev t = case lookupUFM hpt (ms_mod_name ms) of
                                Just hmi  | Just l <- hm_linkable hmi
                                 -> isObjectLinkable l && t == linkableTime l
                                _other  -> True
@@ -899,13 +945,13 @@ checkStability hpt sccs all_home_mods = foldl checkSCC ([],[]) sccs
                -- make's behaviour.
 
        bco_ok ms
-         = case lookupModuleEnv hpt (ms_mod ms) of
+         = case lookupUFM hpt (ms_mod_name ms) of
                Just hmi  | Just l <- hm_linkable hmi ->
                        not (isObjectLinkable l) && 
                        linkableTime l >= ms_hs_date ms
                _other  -> False
 
-ms_allimps :: ModSummary -> [Module]
+ms_allimps :: ModSummary -> [ModuleName]
 ms_allimps ms = map unLoc (ms_srcimps ms ++ ms_imps ms)
 
 -- -----------------------------------------------------------------------------
@@ -926,23 +972,23 @@ ms_allimps ms = map unLoc (ms_srcimps ms ++ ms_imps ms)
 pruneHomePackageTable
    :: HomePackageTable
    -> [ModSummary]
-   -> ([Module],[Module])
+   -> ([ModuleName],[ModuleName])
    -> HomePackageTable
 
 pruneHomePackageTable hpt summ (stable_obj, stable_bco)
-  = mapModuleEnv prune hpt
+  = mapUFM prune hpt
   where prune hmi
          | is_stable modl = hmi'
          | otherwise      = hmi'{ hm_details = emptyModDetails }
          where
-          modl = mi_module (hm_iface hmi)
+          modl = moduleName (mi_module (hm_iface hmi))
           hmi' | Just l <- hm_linkable hmi, linkableTime l < ms_hs_date ms
                = hmi{ hm_linkable = Nothing }
                | otherwise
                = hmi
-               where ms = expectJust "prune" (lookupModuleEnv ms_map modl)
+               where ms = expectJust "prune" (lookupUFM ms_map modl)
 
-        ms_map = mkModuleEnv [(ms_mod ms, ms) | ms <- summ]
+        ms_map = listToUFM [(ms_mod_name ms, ms) | ms <- summ]
 
        is_stable m = m `elem` stable_obj || m `elem` stable_bco
 
@@ -979,7 +1025,7 @@ findPartiallyCompletedCycles modsDone theGraph
 upsweep
     :: HscEnv                  -- Includes initially-empty HPT
     -> HomePackageTable                -- HPT from last time round (pruned)
-    -> ([Module],[Module])     -- stable modules (see checkStability)
+    -> ([ModuleName],[ModuleName]) -- stable modules (see checkStability)
     -> IO ()                   -- How to clean up unwanted tmp files
     -> [SCC ModSummary]                -- Mods to do (the worklist)
     -> IO (SuccessFlag,
@@ -1012,11 +1058,10 @@ upsweep' hsc_env old_hpt stable_mods cleanup
         case mb_mod_info of
            Nothing -> return (Failed, hsc_env, [])
            Just mod_info -> do 
-               { let this_mod = ms_mod mod
+               { let this_mod = ms_mod_name mod
 
                        -- Add new info to hsc_env
-                     hpt1     = extendModuleEnv (hsc_HPT hsc_env) 
-                                       this_mod mod_info
+                     hpt1     = addToUFM (hsc_HPT hsc_env) this_mod mod_info
                      hsc_env1 = hsc_env { hsc_HPT = hpt1 }
 
                        -- Space-saving: delete the old HPT entry
@@ -1026,7 +1071,7 @@ upsweep' hsc_env old_hpt stable_mods cleanup
                        -- main Haskell source file.  Deleting it
                        -- would force .. (what?? --SDM)
                      old_hpt1 | isBootSummary mod = old_hpt
-                              | otherwise = delModuleEnv old_hpt this_mod
+                              | otherwise = delFromUFM old_hpt this_mod
 
                ; (restOK, hsc_env2, modOKs) 
                        <- upsweep' hsc_env1 old_hpt1 stable_mods cleanup 
@@ -1039,7 +1084,7 @@ upsweep' hsc_env old_hpt stable_mods cleanup
 -- successful.  If no compilation happened, return the old Linkable.
 upsweep_mod :: HscEnv
             -> HomePackageTable
-           -> ([Module],[Module])
+           -> ([ModuleName],[ModuleName])
             -> ModSummary
             -> Int  -- index of module
             -> Int  -- total number of modules
@@ -1048,13 +1093,14 @@ upsweep_mod :: HscEnv
 upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
    = do 
         let 
+           this_mod_name = ms_mod_name summary
            this_mod    = ms_mod summary
            mb_obj_date = ms_obj_date summary
            obj_fn      = ml_obj_file (ms_location summary)
            hs_date     = ms_hs_date summary
 
            compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
-           compile_it  = upsweep_compile hsc_env old_hpt this_mod 
+           compile_it  = upsweep_compile hsc_env old_hpt this_mod_name 
                                summary mod_index nmods
 
        case ghcMode (hsc_dflags hsc_env) of
@@ -1102,10 +1148,10 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
                          compile_it Nothing
                        -- no existing code at all: we must recompile.
                   where
-                   is_stable_obj = this_mod `elem` stable_obj
-                   is_stable_bco = this_mod `elem` stable_bco
+                   is_stable_obj = this_mod_name `elem` stable_obj
+                   is_stable_bco = this_mod_name `elem` stable_bco
 
-                   old_hmi = lookupModuleEnv old_hpt this_mod
+                   old_hmi = lookupUFM old_hpt this_mod_name
 
 -- Run hsc to compile a module
 upsweep_compile hsc_env old_hpt this_mod summary
@@ -1122,7 +1168,7 @@ upsweep_compile hsc_env old_hpt this_mod summary
        -- will always be recompiled
 
         mb_old_iface 
-               = case lookupModuleEnv old_hpt this_mod of
+               = case lookupUFM old_hpt this_mod of
                     Nothing                              -> Nothing
                     Just hm_info | isBootSummary summary -> Just iface
                                  | not (mi_boot iface)   -> Just iface
@@ -1148,11 +1194,11 @@ upsweep_compile hsc_env old_hpt this_mod summary
 
 
 -- Filter modules in the HPT
-retainInTopLevelEnvs :: [Module] -> HomePackageTable -> HomePackageTable
+retainInTopLevelEnvs :: [ModuleName] -> HomePackageTable -> HomePackageTable
 retainInTopLevelEnvs keep_these hpt
-   = mkModuleEnv [ (mod, expectJust "retain" mb_mod_info)
+   = listToUFM   [ (mod, expectJust "retain" mb_mod_info)
                 | mod <- keep_these
-                , let mb_mod_info = lookupModuleEnv hpt mod
+                , let mb_mod_info = lookupUFM hpt mod
                 , isJust mb_mod_info ]
 
 -- ---------------------------------------------------------------------------
@@ -1161,7 +1207,7 @@ retainInTopLevelEnvs keep_these hpt
 topSortModuleGraph
          :: Bool               -- Drop hi-boot nodes? (see below)
          -> [ModSummary]
-         -> Maybe Module
+         -> Maybe ModuleName
          -> [SCC ModSummary]
 -- Calculate SCCs of the module graph, possibly dropping the hi-boot nodes
 -- The resulting list of strongly-connected-components is in topologically
@@ -1194,7 +1240,7 @@ topSortModuleGraph drop_hs_boot_nodes summaries (Just mod)
          | otherwise  = throwDyn (ProgramError "module does not exist")
 
 moduleGraphNodes :: Bool -> [ModSummary]
-  -> ([(ModSummary, Int, [Int])], HscSource -> Module -> Maybe Int)
+  -> ([(ModSummary, Int, [Int])], HscSource -> ModuleName -> Maybe Int)
 moduleGraphNodes drop_hs_boot_nodes summaries = (nodes, lookup_key)
    where
        -- Drop hs-boot nodes by using HsSrcFile as the key
@@ -1203,31 +1249,48 @@ moduleGraphNodes drop_hs_boot_nodes summaries = (nodes, lookup_key)
 
        -- We use integers as the keys for the SCC algorithm
        nodes :: [(ModSummary, Int, [Int])]     
-       nodes = [(s, expectJust "topSort" (lookup_key (ms_hsc_src s) (ms_mod s)), 
+       nodes = [(s, expectJust "topSort" $ 
+                       lookup_key (ms_hsc_src s) (ms_mod_name s),
                     out_edge_keys hs_boot_key (map unLoc (ms_srcimps s)) ++
-                    out_edge_keys HsSrcFile   (map unLoc (ms_imps s))    )
+                    out_edge_keys HsSrcFile   (map unLoc (ms_imps s)) ++
+                    (-- see [boot-edges] below
+                     if drop_hs_boot_nodes || ms_hsc_src s == HsBootFile 
+                       then [] 
+                       else case lookup_key HsBootFile (ms_mod_name s) of
+                               Nothing -> []
+                               Just k  -> [k])
+                )
                | s <- summaries
                , not (isBootSummary s && drop_hs_boot_nodes) ]
                -- Drop the hi-boot ones if told to do so
 
+       -- [boot-edges] if this is a .hs and there is an equivalent
+       -- .hs-boot, add a link from the former to the latter.  This
+       -- has the effect of detecting bogus cases where the .hs-boot
+       -- depends on the .hs, by introducing a cycle.  Additionally,
+       -- it ensures that we will always process the .hs-boot before
+       -- the .hs, and so the HomePackageTable will always have the
+       -- most up to date information.
+
        key_map :: NodeMap Int
-       key_map = listToFM ([(ms_mod s, ms_hsc_src s) | s <- summaries]
+       key_map = listToFM ([(moduleName (ms_mod s), ms_hsc_src s)
+                           | s <- summaries]
                           `zip` [1..])
 
-       lookup_key :: HscSource -> Module -> Maybe Int
+       lookup_key :: HscSource -> ModuleName -> Maybe Int
        lookup_key hs_src mod = lookupFM key_map (mod, hs_src)
 
-       out_edge_keys :: HscSource -> [Module] -> [Int]
+       out_edge_keys :: HscSource -> [ModuleName] -> [Int]
         out_edge_keys hi_boot ms = mapCatMaybes (lookup_key hi_boot) ms
                -- If we want keep_hi_boot_nodes, then we do lookup_key with
                -- the IsBootInterface parameter True; else False
 
 
-type NodeKey   = (Module, HscSource)     -- The nodes of the graph are 
+type NodeKey   = (ModuleName, HscSource)  -- The nodes of the graph are 
 type NodeMap a = FiniteMap NodeKey a     -- keyed by (mod, src_file_type) pairs
 
 msKey :: ModSummary -> NodeKey
-msKey (ModSummary { ms_mod = mod, ms_hsc_src = boot }) = (mod,boot)
+msKey (ModSummary { ms_mod = mod, ms_hsc_src = boot }) = (moduleName mod,boot)
 
 mkNodeMap :: [ModSummary] -> NodeMap ModSummary
 mkNodeMap summaries = listToFM [ (msKey s, s) | s <- summaries]
@@ -1235,6 +1298,27 @@ mkNodeMap summaries = listToFM [ (msKey s, s) | s <- summaries]
 nodeMapElts :: NodeMap a -> [a]
 nodeMapElts = eltsFM
 
+ms_mod_name :: ModSummary -> ModuleName
+ms_mod_name = moduleName . ms_mod
+
+-- If there are {-# SOURCE #-} imports between strongly connected
+-- components in the topological sort, then those imports can
+-- definitely be replaced by ordinary non-SOURCE imports: if SOURCE
+-- were necessary, then the edge would be part of a cycle.
+warnUnnecessarySourceImports :: DynFlags -> [SCC ModSummary] -> IO ()
+warnUnnecessarySourceImports dflags sccs = 
+  printBagOfWarnings dflags (listToBag (concat (map (check.flattenSCC) sccs)))
+  where check ms =
+          let mods_in_this_cycle = map ms_mod_name ms in
+          [ warn m i | m <- ms, i <- ms_srcimps m,
+                       unLoc i `notElem`  mods_in_this_cycle ]
+
+       warn :: ModSummary -> Located ModuleName -> WarnMsg
+       warn ms (L loc mod) = 
+          mkPlainErrMsg loc
+               (ptext SLIT("Warning: {-# SOURCE #-} unnecessary in import of ")
+                <+> quotes (ppr mod))
+
 -----------------------------------------------------------------------------
 -- Downsweep (dependency analysis)
 
@@ -1252,7 +1336,7 @@ nodeMapElts = eltsFM
 
 downsweep :: HscEnv
          -> [ModSummary]       -- Old summaries
-         -> [Module]           -- Ignore dependencies on these; treat
+         -> [ModuleName]       -- Ignore dependencies on these; treat
                                -- them as if they were package modules
          -> Bool               -- True <=> allow multiple targets to have 
                                --          the same module name; this is 
@@ -1304,7 +1388,7 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots
             dup_roots :: [[ModSummary]]        -- Each at least of length 2
             dup_roots = filterOut isSingleton (nodeMapElts root_map)
 
-       loop :: [(Located Module,IsBootInterface)]
+       loop :: [(Located ModuleName,IsBootInterface)]
                        -- Work list: process these modules
             -> NodeMap [ModSummary]
                        -- Visited set; the range is a list because
@@ -1333,7 +1417,7 @@ mkRootMap :: [ModSummary] -> NodeMap [ModSummary]
 mkRootMap summaries = addListToFM_C (++) emptyFM 
                        [ (msKey s, [s]) | s <- summaries ]
 
-msDeps :: ModSummary -> [(Located Module, IsBootInterface)]
+msDeps :: ModSummary -> [(Located ModuleName, IsBootInterface)]
 -- (msDeps s) returns the dependencies of the ModSummary s.
 -- A wrinkle is that for a {-# SOURCE #-} import we return
 --     *both* the hs-boot file
@@ -1400,14 +1484,14 @@ summariseFile hsc_env old_summaries file mb_phase maybe_buf
        (dflags', hspp_fn, buf)
            <- preprocessFile dflags file mb_phase maybe_buf
 
-        (srcimps,the_imps, L _ mod) <- getImports dflags' buf hspp_fn
+        (srcimps,the_imps, L _ mod_name) <- getImports dflags' buf hspp_fn
 
        -- Make a ModLocation for this file
-       location <- mkHomeModLocation dflags mod file
+       location <- mkHomeModLocation dflags mod_name file
 
        -- Tell the Finder cache where it is, so that subsequent calls
        -- to findModule will find it, even if it's not on any search path
-       addHomeModuleToFinder hsc_env mod location
+       mod <- addHomeModuleToFinder hsc_env mod_name location
 
         src_timestamp <- case maybe_buf of
                           Just (_,t) -> return t
@@ -1437,9 +1521,9 @@ summariseModule
          :: HscEnv
          -> NodeMap ModSummary -- Map of old summaries
          -> IsBootInterface    -- True <=> a {-# SOURCE #-} import
-         -> Located Module     -- Imported module to be summarised
+         -> Located ModuleName -- Imported module to be summarised
          -> Maybe (StringBuffer, ClockTime)
-         -> [Module]           -- Modules to exclude
+         -> [ModuleName]               -- Modules to exclude
          -> IO (Maybe ModSummary)      -- Its new summary
 
 summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf excl_mods
@@ -1476,9 +1560,8 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
                obj_timestamp <- getObjTimestamp location is_boot
                return (Just old_summary{ ms_obj_date = obj_timestamp })
        | otherwise = 
-               -- source changed: find and re-summarise.  We call the finder
-               -- again, because the user may have moved the source file.
-               new_summary location src_fn src_timestamp
+               -- source changed: re-summarise.
+               new_summary location (ms_mod old_summary) src_fn src_timestamp
 
     find_it = do
        -- Don't use the Finder's cache this time.  If the module was
@@ -1486,17 +1569,22 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
        -- search path, so we want to consider it to be a home module.  If
        -- the module was previously a home module, it may have moved.
        uncacheModule hsc_env wanted_mod
-       found <- findModule hsc_env wanted_mod True {-explicit-}
+       found <- findImportedModule hsc_env wanted_mod Nothing
        case found of
-            Found location pkg 
-               | not (isHomePackage pkg) -> return Nothing
-                       -- Drop external-pkg
-               | isJust (ml_hs_file location) -> just_found location
+            Found location mod 
+               | isJust (ml_hs_file location) ->
                        -- Home package
+                        just_found location mod
+               | otherwise -> 
+                       -- Drop external-pkg
+                       ASSERT(modulePackageId mod /= thisPackage dflags)
+                       return Nothing
+               where
+                       
             err -> noModError dflags loc wanted_mod err
                        -- Not found
 
-    just_found location = do
+    just_found location mod = do
                -- Adjust location to point to the hs-boot source file, 
                -- hi file, object file, when is_boot says so
        let location' | is_boot   = addBootSuffixLocn location
@@ -1508,10 +1596,10 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
        maybe_t <- modificationTimeIfExists src_fn
        case maybe_t of
          Nothing -> noHsFileErr loc src_fn
-         Just t  -> new_summary location' src_fn t
+         Just t  -> new_summary location' mod src_fn t
 
 
-    new_summary location src_fn src_timestamp
+    new_summary location mod src_fn src_timestamp
       = do
        -- Preprocess the source file and get its imports
        -- The dflags' contains the OPTIONS pragmas
@@ -1526,7 +1614,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
                -- Find the object timestamp, and return the summary
        obj_timestamp <- getObjTimestamp location is_boot
 
-       return (Just ( ModSummary { ms_mod       = wanted_mod, 
+       return (Just ( ModSummary { ms_mod       = mod, 
                                    ms_hsc_src   = hsc_src,
                                    ms_location  = location,
                                    ms_hspp_file = hspp_fn,
@@ -1578,10 +1666,10 @@ preprocessFile dflags src_fn mb_phase (Just (buf, time))
 --                     Error messages
 -----------------------------------------------------------------------------
 
-noModError :: DynFlags -> SrcSpan -> Module -> FindResult -> IO ab
+noModError :: DynFlags -> SrcSpan -> ModuleName -> FindResult -> IO ab
 -- ToDo: we don't have a proper line number for this error
 noModError dflags loc wanted_mod err
-  = throwDyn $ mkPlainErrMsg loc $ cantFindError dflags wanted_mod err
+  = throwDyn $ mkPlainErrMsg loc $ cannotFindModule dflags wanted_mod err
                                
 noHsFileErr loc path
   = throwDyn $ mkPlainErrMsg loc $ text "Can't find" <+> text path
@@ -1618,8 +1706,7 @@ cyclicModuleErr ms
 -- Note: if you change the working directory, you should also unload
 -- the current program (set targets to empty, followed by load).
 workingDirectoryChanged :: Session -> IO ()
-workingDirectoryChanged s = withSession s $ \hsc_env ->
-  flushFinderCache (hsc_FC hsc_env)
+workingDirectoryChanged s = withSession s $ flushFinderCaches
 
 -- -----------------------------------------------------------------------------
 -- inspecting the session
@@ -1628,9 +1715,9 @@ workingDirectoryChanged s = withSession s $ \hsc_env ->
 getModuleGraph :: Session -> IO ModuleGraph -- ToDo: DiGraph ModSummary
 getModuleGraph s = withSession s (return . hsc_mod_graph)
 
-isLoaded :: Session -> Module -> IO Bool
+isLoaded :: Session -> ModuleName -> IO Bool
 isLoaded s m = withSession s $ \hsc_env ->
-  return $! isJust (lookupModuleEnv (hsc_HPT hsc_env) m)
+  return $! isJust (lookupUFM (hsc_HPT hsc_env) m)
 
 getBindings :: Session -> IO [TyThing]
 getBindings s = withSession s (return . nameEnvElts . ic_type_env . hsc_IC)
@@ -1654,7 +1741,7 @@ getModuleInfo :: Session -> Module -> IO (Maybe ModuleInfo)
 getModuleInfo s mdl = withSession s $ \hsc_env -> do
   let mg = hsc_mod_graph hsc_env
   if mdl `elem` map ms_mod mg
-       then getHomeModuleInfo hsc_env mdl
+       then getHomeModuleInfo hsc_env (moduleName mdl)
        else do
   {- if isHomeModule (hsc_dflags hsc_env) mdl
        then return Nothing
@@ -1681,7 +1768,7 @@ getPackageModuleInfo hsc_env mdl = do
        return (Just (ModuleInfo {
                        minf_type_env  = mkTypeEnv tys,
                        minf_exports   = names,
-                       minf_rdr_env   = Just $! nameSetToGlobalRdrEnv names mdl,
+                       minf_rdr_env   = Just $! nameSetToGlobalRdrEnv names (moduleName mdl),
                        minf_instances = error "getModuleInfo: instances for package module unimplemented"
                }))
 #else
@@ -1690,7 +1777,7 @@ getPackageModuleInfo hsc_env mdl = do
 #endif
 
 getHomeModuleInfo hsc_env mdl = 
-  case lookupModuleEnv (hsc_HPT hsc_env) mdl of
+  case lookupUFM (hsc_HPT hsc_env) mdl of
     Nothing  -> return Nothing
     Just hmi -> do
       let details = hm_details hmi
@@ -1721,7 +1808,7 @@ modInfoIsExportedName :: ModuleInfo -> Name -> Bool
 modInfoIsExportedName minf name = elemNameSet name (minf_exports minf)
 
 modInfoPrintUnqualified :: ModuleInfo -> Maybe PrintUnqualified
-modInfoPrintUnqualified minf = fmap unQualInScope (minf_rdr_env minf)
+modInfoPrintUnqualified minf = fmap mkPrintUnqualified (minf_rdr_env minf)
 
 modInfoLookupName :: Session -> ModuleInfo -> Name -> IO (Maybe TyThing)
 modInfoLookupName s minf name = withSession s $ \hsc_env -> do
@@ -1729,7 +1816,8 @@ modInfoLookupName s minf name = withSession s $ \hsc_env -> do
      Just tyThing -> return (Just tyThing)
      Nothing      -> do
        eps <- readIORef (hsc_EPS hsc_env)
-       return $! lookupType (hsc_HPT hsc_env) (eps_PTE eps) name
+       return $! lookupType (hsc_dflags hsc_env) 
+                           (hsc_HPT hsc_env) (eps_PTE eps) name
 
 isDictonaryId :: Id -> Bool
 isDictonaryId id
@@ -1742,7 +1830,8 @@ isDictonaryId id
 lookupGlobalName :: Session -> Name -> IO (Maybe TyThing)
 lookupGlobalName s name = withSession s $ \hsc_env -> do
    eps <- readIORef (hsc_EPS hsc_env)
-   return $! lookupType (hsc_HPT hsc_env) (eps_PTE eps) name
+   return $! lookupType (hsc_dflags hsc_env) 
+                       (hsc_HPT hsc_env) (eps_PTE eps) name
 
 -- -----------------------------------------------------------------------------
 -- Misc exported utils
@@ -1779,6 +1868,31 @@ getTokenStream :: Session -> Module -> IO [Located Token]
 -- -----------------------------------------------------------------------------
 -- Interactive evaluation
 
+-- | Takes a 'ModuleName' and possibly a 'PackageId', and consults the
+-- filesystem and package database to find the corresponding 'Module', 
+-- using the algorithm that is used for an @import@ declaration.
+findModule :: Session -> ModuleName -> Maybe PackageId -> IO Module
+findModule s mod_name maybe_pkg = withSession s $ \hsc_env ->
+  findModule' hsc_env mod_name maybe_pkg
+
+findModule' hsc_env mod_name maybe_pkg =
+  let
+        dflags = hsc_dflags hsc_env
+        hpt    = hsc_HPT hsc_env
+        this_pkg = thisPackage dflags
+  in
+  case lookupUFM hpt mod_name of
+    Just mod_info -> return (mi_module (hm_iface mod_info))
+    _not_a_home_module -> do
+         res <- findImportedModule hsc_env mod_name Nothing
+         case res of
+           Found _ m | modulePackageId m /= this_pkg -> return m
+                     | otherwise -> throwDyn (CmdLineError (showSDoc $
+                                       text "module" <+> pprModule m <+>
+                                       text "is not loaded"))
+           err -> let msg = cannotFindModule dflags mod_name err in
+                  throwDyn (CmdLineError (showSDoc msg))
+
 #ifdef GHCI
 
 -- | Set the interactive evaluation context.
@@ -1790,17 +1904,16 @@ setContext :: Session
           -> [Module]  -- entire top level scope of these modules
           -> [Module]  -- exports only of these modules
           -> IO ()
-setContext (Session ref) toplevs exports = do 
+setContext (Session ref) toplev_mods export_mods = do 
   hsc_env <- readIORef ref
   let old_ic  = hsc_IC     hsc_env
       hpt     = hsc_HPT    hsc_env
-
-  mapM_ (checkModuleExists hsc_env hpt) exports
-  export_env  <- mkExportEnv hsc_env exports
-  toplev_envs <- mapM (mkTopLevEnv hpt) toplevs
+  --
+  export_env  <- mkExportEnv hsc_env export_mods
+  toplev_envs <- mapM (mkTopLevEnv hpt) toplev_mods
   let all_env = foldr plusGlobalRdrEnv export_env toplev_envs
-  writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplevs,
-                                           ic_exports      = exports,
+  writeIORef ref hsc_env{ hsc_IC = old_ic { ic_toplev_scope = toplev_mods,
+                                           ic_exports      = export_mods,
                                            ic_rn_gbl_env   = all_env }}
 
 
@@ -1810,47 +1923,35 @@ mkExportEnv hsc_env mods = do
   stuff <- mapM (getModuleExports hsc_env) mods
   let 
        (_msgs, mb_name_sets) = unzip stuff
-       gres = [ nameSetToGlobalRdrEnv name_set mod
+       gres = [ nameSetToGlobalRdrEnv name_set (moduleName mod)
               | (Just name_set, mod) <- zip mb_name_sets mods ]
   --
   return $! foldr plusGlobalRdrEnv emptyGlobalRdrEnv gres
 
-nameSetToGlobalRdrEnv :: NameSet -> Module -> GlobalRdrEnv
+nameSetToGlobalRdrEnv :: NameSet -> ModuleName -> GlobalRdrEnv
 nameSetToGlobalRdrEnv names mod =
   mkGlobalRdrEnv [ GRE  { gre_name = name, gre_prov = vanillaProv mod }
                 | name <- nameSetToList names ]
 
-vanillaProv :: Module -> Provenance
+vanillaProv :: ModuleName -> Provenance
 -- We're building a GlobalRdrEnv as if the user imported
 -- all the specified modules into the global interactive module
-vanillaProv mod = Imported [ImpSpec { is_decl = decl, is_item = ImpAll}]
+vanillaProv mod_name = Imported [ImpSpec { is_decl = decl, is_item = ImpAll}]
   where
-    decl = ImpDeclSpec { is_mod = mod, is_as = mod, 
+    decl = ImpDeclSpec { is_mod = mod_name, is_as = mod_name, 
                         is_qual = False, 
                         is_dloc = srcLocSpan interactiveSrcLoc }
 
-checkModuleExists :: HscEnv -> HomePackageTable -> Module -> IO ()
-checkModuleExists hsc_env hpt mod = 
-  case lookupModuleEnv hpt mod of
-    Just mod_info -> return ()
-    _not_a_home_module -> do
-         res <- findPackageModule hsc_env mod True
-         case res of
-           Found _ _ -> return  ()
-           err -> let msg = cantFindError (hsc_dflags hsc_env) mod err in
-                  throwDyn (CmdLineError (showSDoc msg))
-
 mkTopLevEnv :: HomePackageTable -> Module -> IO GlobalRdrEnv
 mkTopLevEnv hpt modl
- = case lookupModuleEnv hpt modl of
-      Nothing ->       
-        throwDyn (ProgramError ("mkTopLevEnv: not a home module " 
-                       ++ showSDoc (pprModule modl)))
+  = case lookupUFM hpt (moduleName modl) of
+      Nothing -> throwDyn (ProgramError ("mkTopLevEnv: not a home module " ++ 
+                                                showSDoc (ppr modl)))
       Just details ->
         case mi_globals (hm_iface details) of
                Nothing  -> 
                   throwDyn (ProgramError ("mkTopLevEnv: not interpreted " 
-                                               ++ showSDoc (pprModule modl)))
+                                               ++ showSDoc (ppr modl)))
                Just env -> return env
 
 -- | Get the interactive evaluation context, consisting of a pair of the
@@ -1864,9 +1965,11 @@ getContext s = withSession s (\HscEnv{ hsc_IC=ic } ->
 -- its full top-level scope available.
 moduleIsInterpreted :: Session -> Module -> IO Bool
 moduleIsInterpreted s modl = withSession s $ \h ->
- case lookupModuleEnv (hsc_HPT h) modl of
-      Just details       -> return (isJust (mi_globals (hm_iface details)))
-      _not_a_home_module -> return False
+ if modulePackageId modl /= thisPackage (hsc_dflags h)
+        then return False
+        else case lookupUFM (hsc_HPT h) (moduleName modl) of
+                Just details       -> return (isJust (mi_globals (hm_iface details)))
+                _not_a_home_module -> return False
 
 -- | Looks up an identifier in the current interactive context (for :info)
 getInfo :: Session -> Name -> IO (Maybe (TyThing,Fixity,[Instance]))
@@ -1956,6 +2059,27 @@ compileExpr s expr = withSession s $ \hsc_env -> do
                  _          -> panic "compileExpr"
 
 -- -----------------------------------------------------------------------------
+-- Compile an expression into a dynamic
+
+dynCompileExpr :: Session -> String -> IO (Maybe Dynamic)
+dynCompileExpr ses expr = do
+    (full,exports) <- getContext ses
+    setContext ses full $
+        (mkModule
+            (stringToPackageId "base") (mkModuleName "Data.Dynamic")
+        ):exports
+    let stmt = "let __dynCompileExpr = Data.Dynamic.toDyn (" ++ expr ++ ")"
+    res <- withSession ses (flip hscStmt stmt)
+    setContext ses full exports
+    case res of
+        Nothing -> return Nothing
+        Just (_, names, hvals) -> do
+            vals <- (unsafeCoerce# hvals :: IO [Dynamic])
+            case (names,vals) of
+                (_:[], v:[])    -> return (Just v)
+                _               -> panic "dynCompileExpr"
+
+-- -----------------------------------------------------------------------------
 -- running a statement interactively
 
 data RunResult
@@ -2044,7 +2168,7 @@ foreign import "rts_evalStableIO"  {- safe -}
 
 showModule :: Session -> ModSummary -> IO String
 showModule s mod_summary = withSession s $ \hsc_env -> do
-  case lookupModuleEnv (hsc_HPT hsc_env) (ms_mod mod_summary) of
+  case lookupUFM (hsc_HPT hsc_env) (ms_mod_name mod_summary) of
        Nothing       -> panic "missing linkable"
        Just mod_info -> return (showModMsg (hscTarget (hsc_dflags hsc_env)) (not obj_linkable) mod_summary)
                      where