Split the Id related functions out from Var into Id, document Var and some of Id
[ghc-hetmet.git] / compiler / main / GHC.hs
index 8bca662..5314407 100644 (file)
@@ -39,9 +39,10 @@ module GHC (
        depanal,
        load, LoadHowMuch(..), SuccessFlag(..), -- also does depanal
        workingDirectoryChanged,
-       checkModule, CheckedModule(..),
+       checkModule, checkAndLoadModule, CheckedModule(..),
        TypecheckedSource, ParsedSource, RenamedSource,
-        compileToCore, compileToCoreModule,
+        compileToCore, compileToCoreModule, compileToCoreSimplified,
+        compileCoreToObj,
 
        -- * Parsing Haddock comments
        parseHaddockComment,
@@ -74,6 +75,7 @@ module GHC (
        setContext, getContext, 
        getNamesInScope,
        getRdrNamesInScope,
+        getGRE,
        moduleIsInterpreted,
        getInfo,
        exprType,
@@ -92,7 +94,7 @@ module GHC (
         InteractiveEval.forward,
        showModule,
         isModuleInterpreted,
-       compileExpr, HValue, dynCompileExpr,
+       InteractiveEval.compileExpr, HValue, dynCompileExpr,
        lookupName,
         GHC.obtainTerm, GHC.obtainTerm1, GHC.obtainTermB, reconstructType,
         modInfoModBreaks,
@@ -211,15 +213,17 @@ import TcRnDriver
 #endif
 
 import TcIface
+import TcRnTypes        hiding (LIE)
 import TcRnMonad        ( initIfaceCheck )
 import Packages
 import NameSet
 import RdrName
-import HsSyn 
+import qualified HsSyn -- hack as we want to reexport the whole module
+import HsSyn hiding ((<.>))
 import Type             hiding (typeKind)
 import TcType           hiding (typeKind)
 import Id
-import Var              hiding (setIdType)
+import Var
 import TysPrim         ( alphaTyVars )
 import TyCon
 import Class
@@ -227,31 +231,31 @@ import FunDeps
 import DataCon
 import Name             hiding ( varName )
 import OccName         ( parenSymOcc )
-import InstEnv         ( Instance, instanceDFunId, pprInstance, pprInstanceHdr )
+import InstEnv         ( Instance, instanceDFunId, pprInstance, pprInstanceHdr,
+                          emptyInstEnv )
+import FamInstEnv       ( emptyFamInstEnv )
 import SrcLoc
 import CoreSyn
+import TidyPgm
 import DriverPipeline
 import DriverPhases    ( HscSource(..), Phase(..), isHaskellSrcFilename, startPhase )
-import HeaderInfo      ( getImports, getOptions )
+import HeaderInfo
 import Finder
-import HscMain          ( newHscEnv, hscFileCheck, HscChecked(..) )
+import HscMain
 import HscTypes
 import DynFlags
 import StaticFlags
 import SysTools     ( initSysTools, cleanTempFiles, cleanTempFilesExcept,
                       cleanTempDirs )
 import Module
-import UniqFM
+import LazyUniqFM
 import UniqSet
 import Unique
 import FiniteMap
 import Panic
 import Digraph
 import Bag             ( unitBag, listToBag )
-import ErrUtils                ( Severity(..), showPass, fatalErrorMsg, debugTraceMsg,
-                         mkPlainErrMsg, printBagOfErrors, printBagOfWarnings,
-                         WarnMsg )
-import qualified ErrUtils
+import ErrUtils
 import Util
 import StringBuffer    ( StringBuffer, hGetStringBuffer )
 import Outputable
@@ -259,19 +263,25 @@ import BasicTypes
 import Maybes          ( expectJust, mapCatMaybes )
 import HaddockParse
 import HaddockLex       ( tokenise )
+import FastString
 
 import Control.Concurrent
-import System.Directory ( getModificationTime, doesFileExist )
+import System.Directory ( getModificationTime, doesFileExist,
+                          getCurrentDirectory )
 import Data.Maybe
 import Data.List
 import qualified Data.List as List
 import Control.Monad
 import System.Exit     ( exitWith, ExitCode(..) )
-import System.Time     ( ClockTime )
-import Control.Exception as Exception hiding (handle)
+import System.Time     ( ClockTime, getClockTime )
+import Exception
 import Data.IORef
+import System.FilePath
 import System.IO
 import System.IO.Error ( try, isDoesNotExistError )
+#if __GLASGOW_HASKELL__ >= 609
+import Data.Typeable (cast)
+#endif
 import Prelude hiding (init)
 
 
@@ -283,33 +293,55 @@ import Prelude hiding (init)
 -- the top level of your program.  The default handlers output the error
 -- message(s) to stderr and exit cleanly.
 defaultErrorHandler :: DynFlags -> IO a -> IO a
-defaultErrorHandler dflags inner = 
+defaultErrorHandler dflags inner =
   -- top-level exception handler: any unrecognised exception is a compiler bug.
+#if __GLASGOW_HASKELL__ < 609
   handle (\exception -> do
-          hFlush stdout
-          case exception of
-               -- an IO exception probably isn't our fault, so don't panic
-               IOException _ ->
-                 fatalErrorMsg dflags (text (show exception))
-               AsyncException StackOverflow ->
-                 fatalErrorMsg dflags (text "stack overflow: use +RTS -K<size> to increase it")
-               _other ->
-                 fatalErrorMsg dflags (text (show (Panic (show exception))))
-          exitWith (ExitFailure 1)
+           hFlush stdout
+           case exception of
+                -- an IO exception probably isn't our fault, so don't panic
+                IOException _ ->
+                  fatalErrorMsg dflags (text (show exception))
+                AsyncException StackOverflow ->
+                  fatalErrorMsg dflags (text "stack overflow: use +RTS -K<size> to increase it")
+                ExitException _ -> throw exception
+                _ ->
+                  fatalErrorMsg dflags (text (show (Panic (show exception))))
+           exitWith (ExitFailure 1)
+         ) $
+#else
+  handle (\(SomeException exception) -> do
+           hFlush stdout
+           case cast exception of
+                -- an IO exception probably isn't our fault, so don't panic
+                Just (ioe :: IOException) ->
+                  fatalErrorMsg dflags (text (show ioe))
+                _ -> case cast exception of
+                     Just StackOverflow ->
+                         fatalErrorMsg dflags (text "stack overflow: use +RTS -K<size> to increase it")
+                     _ -> case cast exception of
+                          Just (ex :: ExitCode) -> throw ex
+                          _ ->
+                              fatalErrorMsg dflags
+                                  (text (show (Panic (show exception))))
+           exitWith (ExitFailure 1)
          ) $
+#endif
 
   -- program errors: messages with locations attached.  Sometimes it is
   -- convenient to just throw these as exceptions.
-  handleDyn (\dyn -> do printBagOfErrors dflags (unitBag dyn)
-                       exitWith (ExitFailure 1)) $
+  handleErrMsg
+            (\em -> do printBagOfErrors dflags (unitBag em)
+                       exitWith (ExitFailure 1)) $
 
   -- error messages propagated as exceptions
-  handleDyn (\dyn -> do
+  handleGhcException
+            (\ge -> do
                hFlush stdout
-               case dyn of
+               case ge of
                     PhaseFailed _ code -> exitWith code
                     Interrupted -> exitWith (ExitFailure 1)
-                    _ -> do fatalErrorMsg dflags (text (show (dyn :: GhcException)))
+                    _ -> do fatalErrorMsg dflags (text (show ge))
                             exitWith (ExitFailure 1)
            ) $
   inner
@@ -321,13 +353,13 @@ defaultErrorHandler dflags inner =
 defaultCleanupHandler :: DynFlags -> IO a -> IO a
 defaultCleanupHandler dflags inner = 
     -- make sure we clean up after ourselves
-    later (do cleanTempFiles dflags
+    inner `onException`
+          (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
@@ -341,8 +373,8 @@ newSession mb_top_dir = do
   installSignalHandlers
 
   initStaticOpts
-  dflags0 <- initSysTools mb_top_dir defaultDynFlags
-  dflags  <- initDynFlags dflags0
+  dflags0 <- initDynFlags defaultDynFlags
+  dflags <- initSysTools mb_top_dir dflags0
   env <- newHscEnv dflags
   ref <- newIORef env
   return (Session ref)
@@ -383,16 +415,25 @@ guessOutputFile :: Session -> IO ()
 guessOutputFile s = modifySession s $ \env ->
     let dflags = hsc_dflags env
         mod_graph = hsc_mod_graph env
-        mainModuleSrcPath, guessedName :: Maybe String
+        mainModuleSrcPath :: Maybe String
         mainModuleSrcPath = do
             let isMain = (== mainModIs dflags) . ms_mod
             [ms] <- return (filter isMain mod_graph)
             ml_hs_file (ms_location ms)
-        guessedName = fmap basenameOf mainModuleSrcPath
+        name = fmap dropExtension mainModuleSrcPath
+
+#if defined(mingw32_HOST_OS)
+        -- we must add the .exe extention unconditionally here, otherwise
+        -- when name has an extension of its own, the .exe extension will
+        -- not be added by DriverPipeline.exeFileName.  See #2248
+        name_exe = fmap (<.> "exe") name
+#else
+        name_exe = name
+#endif
     in
     case outputFile dflags of
         Just _ -> env
-        Nothing -> env { hsc_dflags = dflags { outputFile = guessedName } }
+        Nothing -> env { hsc_dflags = dflags { outputFile = name_exe } }
 
 -- -----------------------------------------------------------------------------
 -- Targets
@@ -438,6 +479,8 @@ guessTarget file (Just phase)
 guessTarget file Nothing
    | isHaskellSrcFilename file
    = return (Target (TargetFile file Nothing) Nothing)
+   | looksLikeModuleName file
+   = return (Target (TargetModule (mkModuleName file)) Nothing)
    | otherwise
    = do exists <- doesFileExist hs_file
        if exists
@@ -447,10 +490,13 @@ guessTarget file Nothing
        if exists
           then return (Target (TargetFile lhs_file Nothing) Nothing)
           else do
-       return (Target (TargetModule (mkModuleName file)) Nothing)
+        throwGhcException
+                 (ProgramError (showSDoc $
+                 text "target" <+> quotes (text file) <+> 
+                 text "is not a module name or a source file"))
      where 
-        hs_file  = file `joinFileExt` "hs"
-        lhs_file = file `joinFileExt` "lhs"
+        hs_file  = file <.> "hs"
+        lhs_file = file <.> "lhs"
 
 -- -----------------------------------------------------------------------------
 -- Extending the program scope
@@ -481,7 +527,10 @@ setGlobalTypeScope session ids
 -- Parsing Haddock comments
 
 parseHaddockComment :: String -> Either String (HsDoc RdrName)
-parseHaddockComment string = parseHaddockParagraphs (tokenise string)
+parseHaddockComment string = 
+  case parseHaddockParagraphs (tokenise string) of
+    MyLeft x  -> Left x
+    MyRight x -> Right x
 
 -- -----------------------------------------------------------------------------
 -- Loading the program
@@ -532,7 +581,7 @@ data LoadHowMuch
 -- attempt to load up to this target.  If no Module is supplied,
 -- then try to load all targets.
 load :: Session -> LoadHowMuch -> IO SuccessFlag
-load s@(Session ref) how_much
+load s how_much
    = do 
        -- Dependency analysis first.  Note that this fixes the module graph:
        -- even if we don't get a fully successful upsweep, the full module
@@ -540,15 +589,8 @@ load s@(Session ref) how_much
        -- were successfully loaded by inspecting the Session's HPT.
        mb_graph <- depanal s [] False
        case mb_graph of
-          Just mod_graph -> catchingFailure $ load2 s how_much mod_graph
+          Just mod_graph -> load2 s how_much mod_graph
           Nothing        -> return Failed
-    where catchingFailure f = f `Exception.catch` \e -> do
-              hsc_env <- readIORef ref
-              -- trac #1565 / test ghci021:
-              -- let bindings may explode if we try to use them after
-              -- failing to reload
-              writeIORef ref $! hsc_env{ hsc_IC = emptyInteractiveContext }
-              throw e
 
 load2 :: Session -> LoadHowMuch -> [ModSummary] -> IO SuccessFlag
 load2 s@(Session ref) how_much mod_graph = do
@@ -568,6 +610,21 @@ load2 s@(Session ref) how_much mod_graph = do
                                        not (ms_mod_name s `elem` all_home_mods)]
        ASSERT( null bad_boot_mods ) return ()
 
+        -- check that the module given in HowMuch actually exists, otherwise
+        -- topSortModuleGraph will bomb later.
+        let checkHowMuch (LoadUpTo m)           = checkMod m
+            checkHowMuch (LoadDependenciesOf m) = checkMod m
+            checkHowMuch _ = id
+
+            checkMod m and_then
+                | m `elem` all_home_mods = and_then
+                | otherwise = do 
+                        errorMsg dflags (text "no such module:" <+> 
+                                         quotes (ppr m))
+                        return Failed
+
+        checkHowMuch how_much $ do
+
         -- mg2_with_srcimps drops the hi-boot nodes, returning a 
        -- graph with cycles.  Among other things, it is used for
         -- backing out partially complete cycles following a failed
@@ -593,6 +650,12 @@ load2 s@(Session ref) how_much mod_graph = do
 
        evaluate pruned_hpt
 
+        -- before we unload anything, make sure we don't leave an old
+        -- interactive context around pointing to dead bindings.  Also,
+        -- write the pruned HPT to allow the old HPT to be GC'd.
+        writeIORef ref $! hsc_env{ hsc_IC = emptyInteractiveContext,
+                                   hsc_HPT = pruned_hpt }
+
        debugTraceMsg dflags 2 (text "Stable obj:" <+> ppr stable_obj $$
                                text "Stable BCO:" <+> ppr stable_bco)
 
@@ -772,7 +835,7 @@ data CheckedModule =
                  renamedSource     :: Maybe RenamedSource,
                  typecheckedSource :: Maybe TypecheckedSource,
                  checkedModuleInfo :: Maybe ModuleInfo,
-                  coreModule        :: Maybe CoreModule
+                  coreModule        :: Maybe ModGuts
                }
        -- ToDo: improvements that could be made here:
        --  if the module succeeded renaming but not typechecking,
@@ -804,28 +867,49 @@ type TypecheckedSource = LHsBinds Id
 -- If compileToCore is true, it also desugars the module and returns the 
 -- resulting Core bindings as a component of the CheckedModule.
 checkModule :: Session -> ModuleName -> Bool -> IO (Maybe CheckedModule)
-checkModule (Session ref) mod compileToCore = do
-       -- parse & typecheck the module
+checkModule (Session ref) mod compile_to_core
+ = do
    hsc_env <- readIORef ref   
    let mg  = hsc_mod_graph hsc_env
    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 compileToCore
-          case mbChecked of
+       (ms:_) -> checkModule_ ref ms compile_to_core False
+
+-- | parses and typechecks a module, optionally generates Core, and also
+-- loads the module into the 'Session' so that modules which depend on
+-- this one may subsequently be typechecked using 'checkModule' or
+-- 'checkAndLoadModule'.  If you need to check more than one module,
+-- you probably want to use 'checkAndLoadModule'.  Constructing the
+-- interface takes a little work, so it might be slightly slower than
+-- 'checkModule'.
+checkAndLoadModule :: Session -> ModSummary -> Bool -> IO (Maybe CheckedModule)
+checkAndLoadModule (Session ref) ms compile_to_core
+ = checkModule_ ref ms compile_to_core True
+
+checkModule_ :: IORef HscEnv -> ModSummary -> Bool -> Bool
+             -> IO (Maybe CheckedModule)
+checkModule_ ref ms compile_to_core load
+ = do
+   let mod = ms_mod_name ms
+   hsc_env0 <- readIORef ref   
+   let hsc_env = hsc_env0{hsc_dflags=ms_hspp_opts ms}
+   mb_parsed <- parseFile hsc_env ms
+   case mb_parsed of
              Nothing -> return Nothing
-             Just (HscChecked parsed renamed Nothing _) ->
-                  return (Just (CheckedModule {
-                                       parsedSource = parsed,
-                                       renamedSource = renamed,
-                                       typecheckedSource = Nothing,
-                                       checkedModuleInfo = Nothing,
-                                        coreModule = Nothing }))
-             Just (HscChecked parsed renamed
-                          (Just (tc_binds, rdr_env, details))
-                           maybeCoreBinds) -> do
+             Just rdr_module -> do
+               mb_typechecked <- typecheckRenameModule hsc_env ms rdr_module
+               case mb_typechecked of
+                 Nothing -> return (Just CheckedModule {
+                                              parsedSource = rdr_module,
+                                              renamedSource = Nothing,
+                                             typecheckedSource = Nothing,
+                                             checkedModuleInfo = Nothing,
+                                              coreModule = Nothing })
+                 Just (tcg, rn_info) -> do
+                   details <- makeSimpleDetails hsc_env tcg
+                   
+                   let tc_binds = tcg_binds tcg
+                   let rdr_env  = tcg_rdr_env tcg
                   let minf = ModuleInfo {
                                minf_type_env  = md_types details,
                                minf_exports   = availsToNameSet $
@@ -836,12 +920,29 @@ checkModule (Session ref) mod compileToCore = do
                                ,minf_modBreaks = emptyModBreaks 
 #endif
                              }
+
+                   mb_guts <- if compile_to_core
+                                 then deSugarModule hsc_env ms tcg
+                                 else return Nothing              
+
+                   -- If we are loading this module so that we can typecheck
+                   -- dependent modules, generate an interface and stuff it
+                   -- all in the HomePackageTable.
+                   when load $ do
+                    (iface,_) <- makeSimpleIface hsc_env Nothing tcg details
+                     let mod_info = HomeModInfo {
+                                        hm_iface = iface,
+                                        hm_details = details,
+                                        hm_linkable = Nothing }
+                     let hpt_new = addToUFM (hsc_HPT hsc_env) mod mod_info
+                     writeIORef ref hsc_env0{ hsc_HPT = hpt_new }
+
                   return (Just (CheckedModule {
-                                       parsedSource = parsed,
-                                       renamedSource = renamed,
+                                       parsedSource = rdr_module,
+                                       renamedSource = rn_info,
                                        typecheckedSource = Just tc_binds,
                                        checkedModuleInfo = Just minf,
-                                        coreModule = maybeCoreBinds}))
+                                        coreModule = mb_guts }))
 
 -- | This is the way to get access to the Core bindings corresponding
 -- to a module. 'compileToCore' invokes 'checkModule' to parse, typecheck, and
@@ -849,7 +950,90 @@ checkModule (Session ref) mod compileToCore = do
 -- the module name, type declarations, and function declarations) if
 -- successful.
 compileToCoreModule :: Session -> FilePath -> IO (Maybe CoreModule)
-compileToCoreModule session fn = do
+compileToCoreModule = compileCore False
+
+-- | Like compileToCoreModule, but invokes the simplifier, so
+-- as to return simplified and tidied Core.
+compileToCoreSimplified :: Session -> FilePath -> IO (Maybe CoreModule)
+compileToCoreSimplified = compileCore True
+
+-- | Provided for backwards-compatibility: compileToCore returns just the Core
+-- bindings, but for most purposes, you probably want to call
+-- compileToCoreModule.
+compileToCore :: Session -> FilePath -> IO (Maybe [CoreBind])
+compileToCore session fn = do
+   maybeCoreModule <- compileToCoreModule session fn
+   return $ fmap cm_binds maybeCoreModule
+
+-- | Takes a CoreModule and compiles the bindings therein
+-- to object code. The first argument is a bool flag indicating
+-- whether to run the simplifier.
+-- The resulting .o, .hi, and executable files, if any, are stored in the
+-- current directory, and named according to the module name.
+-- Returns True iff compilation succeeded.
+-- This has only so far been tested with a single self-contained module.
+compileCoreToObj :: Bool -> Session -> CoreModule -> IO Bool
+compileCoreToObj simplify session cm@(CoreModule{ cm_module = mName }) = do
+  hscEnv      <- sessionHscEnv session
+  dflags      <- getSessionDynFlags session
+  currentTime <- getClockTime
+  cwd         <- getCurrentDirectory
+  modLocation <- mkHiOnlyModLocation dflags (hiSuf dflags) cwd
+                   ((moduleNameSlashes . moduleName) mName)
+
+  let modSummary = ModSummary { ms_mod = mName,
+         ms_hsc_src = ExtCoreFile,
+         ms_location = modLocation,
+         -- By setting the object file timestamp to Nothing,
+         -- we always force recompilation, which is what we
+         -- want. (Thus it doesn't matter what the timestamp
+         -- for the (nonexistent) source file is.)
+         ms_hs_date = currentTime,
+         ms_obj_date = Nothing,
+         -- Only handling the single-module case for now, so no imports.
+         ms_srcimps = [],
+         ms_imps = [],
+         -- No source file
+         ms_hspp_file = "",
+         ms_hspp_opts = dflags,
+         ms_hspp_buf = Nothing
+      }
+
+  mbHscResult <- evalComp
+     ((if simplify then hscSimplify else return) (mkModGuts cm)
+     >>= hscNormalIface >>= hscWriteIface >>= hscOneShot)
+     (CompState{ compHscEnv=hscEnv,
+                 compModSummary=modSummary,
+                 compOldIface=Nothing})
+  return $ isJust mbHscResult
+
+-- Makes a "vanilla" ModGuts.
+mkModGuts :: CoreModule -> ModGuts
+mkModGuts coreModule = ModGuts {
+  mg_module = cm_module coreModule,
+  mg_boot = False,
+  mg_exports = [],
+  mg_deps = noDependencies,
+  mg_dir_imps = emptyModuleEnv,
+  mg_used_names = emptyNameSet,
+  mg_rdr_env = emptyGlobalRdrEnv,
+  mg_fix_env = emptyFixityEnv,
+  mg_types = emptyTypeEnv,
+  mg_insts = [],
+  mg_fam_insts = [],
+  mg_rules = [],
+  mg_binds = cm_binds coreModule,
+  mg_foreign = NoStubs,
+  mg_warns = NoWarnings,
+  mg_hpc_info = emptyHpcInfo False,
+  mg_modBreaks = emptyModBreaks,
+  mg_vect_info = noVectInfo,
+  mg_inst_env = emptyInstEnv,
+  mg_fam_inst_env = emptyFamInstEnv
+}
+
+compileCore :: Bool -> Session -> FilePath -> IO (Maybe CoreModule)
+compileCore simplify session fn = do
    -- First, set the target to the desired filename
    target <- guessTarget fn Nothing
    addTarget session target
@@ -867,17 +1051,34 @@ compileToCoreModule session fn = do
            maybeCheckedModule <- checkModule session mod True
            case maybeCheckedModule of
              Nothing -> return Nothing 
-             Just checkedMod -> return $ coreModule checkedMod
+             Just checkedMod -> (liftM $ fmap gutsToCoreModule) $
+                                case (coreModule checkedMod) of
+                                  Just mg | simplify -> (sessionHscEnv session)
+                                  -- If simplify is true: simplify (hscSimplify),
+                                  -- then tidy (tidyProgram).
+                                   >>= \ hscEnv -> evalComp (hscSimplify mg)
+                                         (CompState{ compHscEnv=hscEnv,
+                                                     compModSummary=modSummary,
+                                                     compOldIface=Nothing})
+                                          >>= (tidyProgram hscEnv)
+                                          >>= (return . Just . Left)
+                                  Just guts -> return $ Just $ Right guts
+                                  Nothing   -> return Nothing
          Nothing -> panic "compileToCoreModule: target FilePath not found in\
                            module dependency graph"
+  where -- two versions, based on whether we simplify (thus run tidyProgram,
+        -- which returns a (CgGuts, ModDetails) pair, or not (in which case
+        -- we just have a ModGuts.
+        gutsToCoreModule :: Either (CgGuts, ModDetails) ModGuts -> CoreModule
+        gutsToCoreModule (Left (cg, md))  = CoreModule {
+          cm_module = cg_module cg,    cm_types = md_types md,
+          cm_imports = cg_dir_imps cg, cm_binds = cg_binds cg
+        }
+        gutsToCoreModule (Right mg) = CoreModule {
+          cm_module  = mg_module mg,                   cm_types   = mg_types mg,
+          cm_imports = moduleEnvKeys (mg_dir_imps mg), cm_binds   = mg_binds mg
+         }
 
--- | Provided for backwards-compatibility: compileToCore returns just the Core
--- bindings, but for most purposes, you probably want to call
--- compileToCoreModule.
-compileToCore :: Session -> FilePath -> IO (Maybe [CoreBind])
-compileToCore session fn = do
-   maybeCoreModule <- compileToCoreModule session fn
-   return $ fmap cm_binds maybeCoreModule
 -- ---------------------------------------------------------------------------
 -- Unloading
 
@@ -1104,7 +1305,7 @@ upsweep hsc_env old_hpt stable_mods cleanup sccs = do
        cleanup         -- Remove unwanted tmp files between compilations
 
         case mb_mod_info of
-           Nothing -> return (Failed, hsc_env, [])
+           Nothing -> return (Failed, hsc_env, done)
            Just mod_info -> do 
                let this_mod = ms_mod_name mod
 
@@ -1379,7 +1580,7 @@ topSortModuleGraph drop_hs_boot_nodes summaries (Just mod)
        (graph, vertex_fn, key_fn) = graphFromEdges' nodes
        root 
          | Just key <- lookup_key HsSrcFile mod, Just v <- key_fn key = v
-         | otherwise  = throwDyn (ProgramError "module does not exist")
+         | otherwise  = ghcError (ProgramError "module does not exist")
 
 moduleGraphNodes :: Bool -> [ModSummary]
   -> ([(ModSummary, Int, [Int])], HscSource -> ModuleName -> Maybe Int)
@@ -1455,7 +1656,7 @@ warnUnnecessarySourceImports dflags sccs =
        warn :: Located ModuleName -> WarnMsg
        warn (L loc mod) = 
           mkPlainErrMsg loc
-               (ptext SLIT("Warning: {-# SOURCE #-} unnecessary in import of ")
+               (ptext (sLit "Warning: {-# SOURCE #-} unnecessary in import of ")
                 <+> quotes (ppr mod))
 
 -----------------------------------------------------------------------------
@@ -1486,7 +1687,8 @@ downsweep :: HscEnv
                -- in which case there can be repeats
 downsweep hsc_env old_summaries excl_mods allow_dup_roots
    = -- catch error messages and return them
-     handleDyn (\err_msg -> printBagOfErrors (hsc_dflags hsc_env) (unitBag err_msg) >> return Nothing) $ do
+     handleErrMsg
+               (\err_msg -> printBagOfErrors (hsc_dflags hsc_env) (unitBag err_msg) >> return Nothing) $ do
        rootSummaries <- mapM getRootSummary roots
        let root_map = mkRootMap rootSummaries
        checkDuplicates root_map
@@ -1503,7 +1705,7 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots
           = do exists <- doesFileExist file
                if exists 
                    then summariseFile hsc_env old_summaries file mb_phase maybe_buf
-                   else throwDyn $ mkPlainErrMsg noSrcSpan $
+                   else throwErrMsg $ mkPlainErrMsg noSrcSpan $
                           text "can't find file:" <+> text file
        getRootSummary (Target (TargetModule modl) maybe_buf)
           = do maybe_summary <- summariseModule hsc_env old_summary_map False 
@@ -1512,7 +1714,7 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots
                   Nothing -> packageModErr modl
                   Just s  -> return s
 
-       rootLoc = mkGeneralSrcSpan FSLIT("<command line>")
+       rootLoc = mkGeneralSrcSpan (fsLit "<command line>")
 
        -- In a root module, the filename is allowed to diverge from the module
        -- name, so we have to check that there aren't multiple root files
@@ -1609,7 +1811,10 @@ summariseFile hsc_env old_summaries file mb_phase maybe_buf
 
        if ms_hs_date old_summary == src_timestamp 
           then do -- update the object-file timestamp
-                 obj_timestamp <- getObjTimestamp location False
+                 obj_timestamp <-
+                    if isObjectTarget (hscTarget (hsc_dflags hsc_env)) -- bug #1205
+                        then getObjTimestamp location False
+                        else return Nothing
                  return old_summary{ ms_obj_date = obj_timestamp }
           else
                new_summary
@@ -1621,7 +1826,7 @@ summariseFile hsc_env old_summaries file mb_phase maybe_buf
        let dflags = hsc_dflags hsc_env
 
        (dflags', hspp_fn, buf)
-           <- preprocessFile dflags file mb_phase maybe_buf
+           <- preprocessFile hsc_env file mb_phase maybe_buf
 
         (srcimps,the_imps, L _ mod_name) <- getImports dflags' buf hspp_fn file
 
@@ -1637,7 +1842,12 @@ summariseFile hsc_env old_summaries file mb_phase maybe_buf
                           Nothing    -> getModificationTime file
                        -- getMofificationTime may fail
 
-       obj_timestamp <- modificationTimeIfExists (ml_obj_file location)
+        -- when the user asks to load a source file by name, we only
+        -- use an object file if -fobject-code is on.  See #1205.
+       obj_timestamp <-
+            if isObjectTarget (hscTarget (hsc_dflags hsc_env))
+                then modificationTimeIfExists (ml_obj_file location)
+                else return Nothing
 
         return (ModSummary { ms_mod = mod, ms_hsc_src = HsSrcFile,
                             ms_location = location,
@@ -1718,7 +1928,6 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
                        -- Drop external-pkg
                        ASSERT(modulePackageId mod /= thisPackage dflags)
                        return Nothing
-               where
                        
             err -> noModError dflags loc wanted_mod err
                        -- Not found
@@ -1742,13 +1951,14 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod) maybe_buf exc
       = do
        -- Preprocess the source file and get its imports
        -- The dflags' contains the OPTIONS pragmas
-       (dflags', hspp_fn, buf) <- preprocessFile dflags src_fn Nothing maybe_buf
+       (dflags', hspp_fn, buf) <- preprocessFile hsc_env src_fn Nothing maybe_buf
         (srcimps, the_imps, L mod_loc mod_name) <- getImports dflags' buf hspp_fn src_fn
 
        when (mod_name /= wanted_mod) $
-               throwDyn $ mkPlainErrMsg mod_loc $ 
-                             text "file name does not match module name"
-                             <+> quotes (ppr mod_name)
+               throwErrMsg $ mkPlainErrMsg mod_loc $ 
+                             text "File name does not match module name:" 
+                             $$ text "Saw:" <+> quotes (ppr mod_name)
+                              $$ text "Expected:" <+> quotes (ppr wanted_mod)
 
                -- Find the object timestamp, and return the summary
        obj_timestamp <- getObjTimestamp location is_boot
@@ -1771,22 +1981,24 @@ getObjTimestamp location is_boot
               else modificationTimeIfExists (ml_obj_file location)
 
 
-preprocessFile :: DynFlags -> FilePath -> Maybe Phase -> Maybe (StringBuffer,ClockTime)
+preprocessFile :: HscEnv -> FilePath -> Maybe Phase -> Maybe (StringBuffer,ClockTime)
   -> IO (DynFlags, FilePath, StringBuffer)
-preprocessFile dflags src_fn mb_phase Nothing
+preprocessFile hsc_env src_fn mb_phase Nothing
   = do
-       (dflags', hspp_fn) <- preprocess dflags (src_fn, mb_phase)
+       (dflags', hspp_fn) <- preprocess hsc_env (src_fn, mb_phase)
        buf <- hGetStringBuffer hspp_fn
        return (dflags', hspp_fn, buf)
 
-preprocessFile dflags src_fn mb_phase (Just (buf, _time))
+preprocessFile hsc_env src_fn mb_phase (Just (buf, _time))
   = do
+        let dflags = hsc_dflags hsc_env
        -- case we bypass the preprocessing stage?
        let 
-           local_opts = getOptions buf src_fn
+           local_opts = getOptions dflags buf src_fn
        --
-       (dflags', _errs) <- parseDynamicFlags dflags (map unLoc local_opts)
-        -- XXX: shouldn't we be reporting the errors?
+       (dflags', leftovers, warns) <- parseDynamicFlags dflags (map unLoc local_opts)
+        checkProcessArgsResult leftovers src_fn
+        handleFlagWarnings dflags' warns
 
        let
            needs_preprocessing
@@ -1810,21 +2022,21 @@ preprocessFile dflags src_fn mb_phase (Just (buf, _time))
 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 $ cannotFindModule dflags wanted_mod err
+  = throwErrMsg $ mkPlainErrMsg loc $ cannotFindModule dflags wanted_mod err
                                
 noHsFileErr :: SrcSpan -> String -> a
 noHsFileErr loc path
-  = throwDyn $ mkPlainErrMsg loc $ text "Can't find" <+> text path
+  = throwErrMsg $ mkPlainErrMsg loc $ text "Can't find" <+> text path
  
 packageModErr :: ModuleName -> a
 packageModErr mod
-  = throwDyn $ mkPlainErrMsg noSrcSpan $
+  = throwErrMsg $ mkPlainErrMsg noSrcSpan $
        text "module" <+> quotes (ppr mod) <+> text "is a package module"
 
 multiRootsErr :: [ModSummary] -> IO ()
 multiRootsErr [] = panic "multiRootsErr"
 multiRootsErr summs@(summ1:_)
-  = throwDyn $ mkPlainErrMsg noSrcSpan $
+  = throwErrMsg $ mkPlainErrMsg noSrcSpan $
        text "module" <+> quotes (ppr mod) <+> 
        text "is defined in multiple files:" <+>
        sep (map text files)
@@ -1834,11 +2046,11 @@ multiRootsErr summs@(summ1:_)
 
 cyclicModuleErr :: [ModSummary] -> SDoc
 cyclicModuleErr ms
-  = hang (ptext SLIT("Module imports form a cycle for modules:"))
+  = hang (ptext (sLit "Module imports form a cycle for modules:"))
        2 (vcat (map show_one ms))
   where
     show_one ms = sep [ show_mod (ms_hsc_src ms) (ms_mod ms),
-                       nest 2 $ ptext SLIT("imports:") <+> 
+                       nest 2 $ ptext (sLit "imports:") <+> 
                                   (pp_imps HsBootFile (ms_srcimps ms)
                                   $$ pp_imps HsSrcFile  (ms_imps ms))]
     show_mod hsc_src mod = ppr mod <> text (hscSourceString hsc_src)
@@ -2004,6 +2216,12 @@ lookupGlobalName s name = withSession s $ \hsc_env -> do
    return $! lookupType (hsc_dflags hsc_env) 
                        (hsc_HPT hsc_env) (eps_PTE eps) name
 
+#ifdef GHCI
+-- | get the GlobalRdrEnv for a session
+getGRE :: Session -> IO GlobalRdrEnv
+getGRE s = withSession s $ \hsc_env-> return $ ic_rn_gbl_env (hsc_IC hsc_env)
+#endif
+
 -- -----------------------------------------------------------------------------
 -- Misc exported utils
 
@@ -2055,11 +2273,11 @@ findModule s mod_name maybe_pkg = withSession s $ \hsc_env ->
          res <- findImportedModule hsc_env mod_name maybe_pkg
          case res of
            Found _ m | modulePackageId m /= this_pkg -> return m
-                     | otherwise -> throwDyn (CmdLineError (showSDoc $
-                                       text "module" <+> pprModule m <+>
+                     | otherwise -> ghcError (CmdLineError (showSDoc $
+                                       text "module" <+> quotes (ppr (moduleName m)) <+>
                                        text "is not loaded"))
            err -> let msg = cannotFindModule dflags mod_name err in
-                  throwDyn (CmdLineError (showSDoc msg))
+                  ghcError (CmdLineError (showSDoc msg))
 
 #ifdef GHCI
 getHistorySpan :: Session -> History -> IO SrcSpan