summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-07-04 10:34:48 +0100
committerSimon Marlow <marlowsd@gmail.com>2012-07-04 10:34:48 +0100
commit99fd2469fba1a38b2a65b4694f337d92e559df01 (patch)
tree20491590ccb07223afd9d1f6a6546213b0f43577 /ghc
parentd260d919eef22654b1af61334feed0545f64cea5 (diff)
parent0d19922acd724991b7b97871b1404f3db5058b49 (diff)
downloadhaskell-99fd2469fba1a38b2a65b4694f337d92e559df01.tar.gz
Merge remote-tracking branch 'origin/master' into newcg
* origin/master: (756 commits) don't crash if argv[0] == NULL (#7037) -package P was loading all versions of P in GHCi (#7030) Add a Note, copying text from #2437 improve the --help docs a bit (#7008) Copy Data.HashTable's hashString into our Util module Build fix Build fixes Parse error: suggest brackets and indentation. Don't build the ghc DLL on Windows; works around trac #5987 On Windows, detect if DLLs have too many symbols; trac #5987 Add some more Integer rules; fixes #6111 Fix PA dfun construction with silent superclass args Add silent superclass parameters to the vectoriser Add silent superclass parameters (again) Mention Generic1 in the user's guide Make the GHC API a little more powerful. tweak llvm version warning message New version of the patch for #5461. Fix Word64ToInteger conversion rule. Implemented feature request on reconfigurable pretty-printing in GHCi (#5461) ... Conflicts: compiler/basicTypes/UniqSupply.lhs compiler/cmm/CmmBuildInfoTables.hs compiler/cmm/CmmLint.hs compiler/cmm/CmmOpt.hs compiler/cmm/CmmPipeline.hs compiler/cmm/CmmStackLayout.hs compiler/cmm/MkGraph.hs compiler/cmm/OldPprCmm.hs compiler/codeGen/CodeGen.lhs compiler/codeGen/StgCmm.hs compiler/codeGen/StgCmmBind.hs compiler/codeGen/StgCmmLayout.hs compiler/codeGen/StgCmmUtils.hs compiler/main/CodeOutput.lhs compiler/main/HscMain.hs compiler/nativeGen/AsmCodeGen.lhs compiler/simplStg/SimplStg.lhs
Diffstat (limited to 'ghc')
-rw-r--r--ghc/GhciMonad.hs48
-rw-r--r--ghc/GhciTags.hs42
-rw-r--r--ghc/InteractiveUI.hs616
-rw-r--r--ghc/Main.hs19
-rw-r--r--ghc/ghc-bin.cabal.in4
-rw-r--r--ghc/ghc.mk11
-rw-r--r--ghc/hschooks.c5
7 files changed, 471 insertions, 274 deletions
diff --git a/ghc/GhciMonad.hs b/ghc/GhciMonad.hs
index f1767c3ea5..f68d0b9a55 100644
--- a/ghc/GhciMonad.hs
+++ b/ghc/GhciMonad.hs
@@ -16,13 +16,12 @@ module GhciMonad (
Command,
BreakLocation(..),
TickArray,
- setDynFlags,
+ getDynFlags,
runStmt, runDecls, resume, timeIt, recordBreak, revertCAFs,
printForUser, printForUserPartWay, prettyLocations,
initInterpBuffering, turnOffBuffering, flushInterpBuffers,
- ghciHandleGhcException,
) where
#include "HsVersions.h"
@@ -31,7 +30,6 @@ import qualified GHC
import GhcMonad hiding (liftIO)
import Outputable hiding (printForUser, printForUserPartWay)
import qualified Outputable
-import Panic hiding (showException)
import Util
import DynFlags
import HscTypes
@@ -39,7 +37,6 @@ import SrcLoc
import Module
import ObjLink
import Linker
-import StaticFlags
import qualified MonadUtils
import Exception
@@ -55,7 +52,8 @@ import GHC.Exts
import System.Console.Haskeline (CompletionFunc, InputT)
import qualified System.Console.Haskeline as Haskeline
-import Control.Monad.Trans as Trans
+import Control.Monad.Trans.Class as Trans
+import Control.Monad.IO.Class as Trans
-----------------------------------------------------------------------------
-- GHCi monad
@@ -171,9 +169,6 @@ instance Monad GHCi where
instance Functor GHCi where
fmap f m = m >>= return . f
-ghciHandleGhcException :: (GhcException -> GHCi a) -> GHCi a -> GHCi a
-ghciHandleGhcException = handleGhcException
-
getGHCiState :: GHCi GHCiState
getGHCiState = GHCi $ \r -> liftIO $ readIORef r
setGHCiState :: GHCiState -> GHCi ()
@@ -221,22 +216,22 @@ instance ExceptionMonad GHCi where
instance MonadIO GHCi where
liftIO = MonadUtils.liftIO
+instance Haskeline.MonadException Ghc where
+ controlIO f = Ghc $ \s -> Haskeline.controlIO $ \(Haskeline.RunIO run) -> let
+ run' = Haskeline.RunIO (fmap (Ghc . const) . run . flip unGhc s)
+ in fmap (flip unGhc s) $ f run'
+
instance Haskeline.MonadException GHCi where
- catch = gcatch
- block = gblock
- unblock = gunblock
- -- XXX when Haskeline's MonadException changes, we can drop our
- -- deprecated block/unblock methods
+ controlIO f = GHCi $ \s -> Haskeline.controlIO $ \(Haskeline.RunIO run) -> let
+ run' = Haskeline.RunIO (fmap (GHCi . const) . run . flip unGHCi s)
+ in fmap (flip unGHCi s) $ f run'
instance ExceptionMonad (InputT GHCi) where
gcatch = Haskeline.catch
- gmask f = Haskeline.block (f Haskeline.unblock) -- slightly wrong
- gblock = Haskeline.block
- gunblock = Haskeline.unblock
+ gmask f = Haskeline.liftIOOp gmask (f . Haskeline.liftIOOp_)
-setDynFlags :: DynFlags -> GHCi [PackageId]
-setDynFlags dflags = do
- GHC.setSessionDynFlags dflags
+ gblock = Haskeline.liftIOOp_ gblock
+ gunblock = Haskeline.liftIOOp_ gunblock
isOptionSet :: GHCiOption -> GHCi Bool
isOptionSet opt
@@ -256,12 +251,14 @@ unsetOption opt
printForUser :: GhcMonad m => SDoc -> m ()
printForUser doc = do
unqual <- GHC.getPrintUnqual
- MonadUtils.liftIO $ Outputable.printForUser stdout unqual doc
+ dflags <- getDynFlags
+ MonadUtils.liftIO $ Outputable.printForUser dflags stdout unqual doc
printForUserPartWay :: SDoc -> GHCi ()
printForUserPartWay doc = do
unqual <- GHC.getPrintUnqual
- liftIO $ Outputable.printForUserPartWay stdout opt_PprUserLength unqual doc
+ dflags <- getDynFlags
+ liftIO $ Outputable.printForUserPartWay dflags stdout (pprUserLength dflags) unqual doc
-- | Run a single Haskell expression
runStmt :: String -> GHC.SingleStep -> GHCi (Maybe GHC.RunResult)
@@ -308,18 +305,19 @@ timeIt action
a <- action
allocs2 <- liftIO $ getAllocations
time2 <- liftIO $ getCPUTime
- liftIO $ printTimes (fromIntegral (allocs2 - allocs1))
+ dflags <- getDynFlags
+ liftIO $ printTimes dflags (fromIntegral (allocs2 - allocs1))
(time2 - time1)
return a
foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64
-- defined in ghc/rts/Stats.c
-printTimes :: Integer -> Integer -> IO ()
-printTimes allocs psecs
+printTimes :: DynFlags -> Integer -> Integer -> IO ()
+printTimes dflags allocs psecs
= do let secs = (fromIntegral psecs / (10^(12::Integer))) :: Float
secs_str = showFFloat (Just 2) secs
- putStrLn (showSDoc (
+ putStrLn (showSDoc dflags (
parens (text (secs_str "") <+> text "secs" <> comma <+>
text (show allocs) <+> text "bytes")))
diff --git a/ghc/GhciTags.hs b/ghc/GhciTags.hs
index a3ad646309..1f43328f8d 100644
--- a/ghc/GhciTags.hs
+++ b/ghc/GhciTags.hs
@@ -6,13 +6,6 @@
--
-----------------------------------------------------------------------------
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSp
--- for details
-
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module GhciTags (
createCTagsWithLineNumbersCmd,
@@ -24,7 +17,6 @@ import Exception
import GHC
import GhciMonad
import Outputable
-import Util
-- ToDo: figure out whether we need these, and put something appropriate
-- into the GHC API instead
@@ -32,7 +24,9 @@ import Name (nameOccName)
import OccName (pprOccName)
import MonadUtils
+import Data.Function
import Data.Maybe
+import Data.Ord
import Panic
import Data.List
import Control.Monad
@@ -65,12 +59,12 @@ ghciCreateTagsFile kind file = do
createTagsFile kind file
-- ToDo:
--- - remove restriction that all modules must be interpreted
--- (problem: we don't know source locations for entities unless
--- we compiled the module.
+-- - remove restriction that all modules must be interpreted
+-- (problem: we don't know source locations for entities unless
+-- we compiled the module.
--
--- - extract createTagsFile so it can be used from the command-line
--- (probably need to fix first problem before this is useful).
+-- - extract createTagsFile so it can be used from the command-line
+-- (probably need to fix first problem before this is useful).
--
createTagsFile :: TagsKind -> FilePath -> GHCi ()
createTagsFile tagskind tagsFile = do
@@ -93,12 +87,13 @@ listModuleTags m = do
case mbModInfo of
Nothing -> return []
Just mInfo -> do
+ dflags <- getDynFlags
mb_print_unqual <- GHC.mkPrintUnqualifiedForModule mInfo
let unqual = fromMaybe GHC.alwaysQualify mb_print_unqual
let names = fromMaybe [] $GHC.modInfoTopLevelScope mInfo
let localNames = filter ((m==) . nameModule) names
mbTyThings <- mapM GHC.lookupName localNames
- return $! [ tagInfo unqual exported kind name realLoc
+ return $! [ tagInfo dflags unqual exported kind name realLoc
| tyThing <- catMaybes mbTyThings
, let name = getName tyThing
, let exported = GHC.modInfoIsExportedName mInfo name
@@ -126,24 +121,25 @@ data TagInfo = TagInfo
-- get tag info, for later translation into Vim or Emacs style
-tagInfo :: PrintUnqualified -> Bool -> Char -> Name -> RealSrcLoc -> TagInfo
-tagInfo unqual exported kind name loc
+tagInfo :: DynFlags -> PrintUnqualified -> Bool -> Char -> Name -> RealSrcLoc
+ -> TagInfo
+tagInfo dflags unqual exported kind name loc
= TagInfo exported kind
- (showSDocForUser unqual $ pprOccName (nameOccName name))
- (showSDocForUser unqual $ ftext (srcLocFile loc))
+ (showSDocForUser dflags unqual $ pprOccName (nameOccName name))
+ (showSDocForUser dflags unqual $ ftext (srcLocFile loc))
(srcLocLine loc) (srcLocCol loc) Nothing
collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
-- ctags style with the Ex exresion being just the line number, Vim et al
collateAndWriteTags CTagsWithLineNumbers file tagInfos = do
- let tags = unlines $ sortLe (<=) $ map showCTag tagInfos
+ let tags = unlines $ sort $ map showCTag tagInfos
tryIO (writeFile file tags)
-- ctags style with the Ex exresion being a regex searching the line, Vim et al
collateAndWriteTags CTagsWithRegExes file tagInfos = do -- ctags style, Vim et al
tagInfoGroups <- makeTagGroupsWithSrcInfo tagInfos
- let tags = unlines $ sortLe (<=) $ map showCTag $concat tagInfoGroups
+ let tags = unlines $ sort $ map showCTag $concat tagInfoGroups
tryIO (writeFile file tags)
collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
@@ -160,16 +156,14 @@ collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
makeTagGroupsWithSrcInfo :: [TagInfo] -> IO [[TagInfo]]
makeTagGroupsWithSrcInfo tagInfos = do
- let byFile op ti0 ti1 = tagFile ti0 `op` tagFile ti1
- groups = groupBy (byFile (==)) $ sortLe (byFile (<=)) tagInfos
+ let groups = groupBy ((==) `on` tagFile) $ sortBy (comparing tagFile) tagInfos
mapM addTagSrcInfo groups
where
addTagSrcInfo [] = ghcError (CmdLineError "empty tag file group??")
addTagSrcInfo group@(tagInfo:_) = do
file <- readFile $tagFile tagInfo
- let byLine ti0 ti1 = tagLine ti0 <= tagLine ti1
- sortedGroup = sortLe byLine group
+ let sortedGroup = sortBy (comparing tagLine) group
return $ perFile sortedGroup 1 0 $ lines file
perFile allTags@(tag:tags) cnt pos allLs@(l:ls)
diff --git a/ghc/InteractiveUI.hs b/ghc/InteractiveUI.hs
index 45bac2c9ef..d9d6bc235e 100644
--- a/ghc/InteractiveUI.hs
+++ b/ghc/InteractiveUI.hs
@@ -21,12 +21,14 @@ import Debugger
-- The GHC interface
import DynFlags
+import GhcMonad ( modifySession )
import qualified GHC
import GHC ( LoadHowMuch(..), Target(..), TargetId(..), InteractiveImport(..),
TyThing(..), Phase, BreakIndex, Resume, SingleStep, Ghc,
handleSourceError )
import HsImpExp
-import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, dep_pkgs )
+import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, dep_pkgs, hsc_IC,
+ setInteractivePrintName )
import Module
import Name
import Packages ( trusted, getPackageDetails, exposed, exposedModules, pkgIdMap )
@@ -49,27 +51,26 @@ import Linker
import Maybes ( orElse, expectJust )
import NameSet
import Panic hiding ( showException )
-import StaticFlags
-import Util ( on, global, toArgs, toCmdArgs, removeSpaces, getCmd,
- filterOut, seqList, looksLikeModuleName, partitionWith )
+import Util
-- Haskell Libraries
import System.Console.Haskeline as Haskeline
-import qualified System.Console.Haskeline.Encoding as Encoding
import Control.Applicative hiding (empty)
import Control.Monad as Monad
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
import Data.Array
import qualified Data.ByteString.Char8 as BS
import Data.Char
+import Data.Function
import Data.IORef ( IORef, readIORef, writeIORef )
import Data.List ( find, group, intercalate, intersperse, isPrefixOf, nub,
partition, sort, sortBy )
import Data.Maybe
-import Exception hiding (catch, block, unblock)
+import Exception hiding (catch)
import Foreign.C
import Foreign.Safe
@@ -126,7 +127,7 @@ builtin_commands = [
("def", keepGoing (defineMacro False), completeExpression),
("def!", keepGoing (defineMacro True), completeExpression),
("delete", keepGoing deleteCmd, noCompletion),
- ("edit", keepGoing editFile, completeFilename),
+ ("edit", keepGoing' editFile, completeFilename),
("etags", keepGoing createETagsFileCmd, completeFilename),
("force", keepGoing forceCmd, completeExpression),
("forward", keepGoing forwardCmd, noCompletion),
@@ -146,7 +147,9 @@ builtin_commands = [
("run", keepGoing runRun, completeFilename),
("script", keepGoing' scriptCmd, completeFilename),
("set", keepGoing setCmd, completeSetOptions),
+ ("seti", keepGoing setiCmd, completeSeti),
("show", keepGoing showCmd, completeShowOptions),
+ ("showi", keepGoing showiCmd, completeShowiOptions),
("sprint", keepGoing sprintCmd, completeExpression),
("step", keepGoing stepCmd, completeIdentifier),
("steplocal", keepGoing stepLocalCmd, completeIdentifier),
@@ -185,7 +188,7 @@ keepGoing' a str = a str >> return False
keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi Bool)
keepGoingPaths a str
= do case toArgs str of
- Left err -> Encoding.encode err >>= liftIO . BS.hPutStrLn stderr
+ Left err -> liftIO $ hPutStrLn stderr err
Right args -> a args
return False
@@ -253,6 +256,7 @@ helpText =
" -- Commands for changing settings:\n" ++
"\n" ++
" :set <option> ... set options\n" ++
+ " :seti <option> ... set options for interactive evaluation only\n" ++
" :set args <arg> ... set the arguments returned by System.getArgs\n" ++
" :set prog <progname> set the value returned by System.getProgName\n" ++
" :set prompt <prompt> set the prompt used in GHCi\n" ++
@@ -279,9 +283,10 @@ helpText =
" :show imports show the current imports\n" ++
" :show modules show the currently loaded modules\n" ++
" :show packages show the currently active package flags\n" ++
- " :show languages show the currently active language flags\n" ++
+ " :show language show the currently active language flags\n" ++
" :show <setting> show value of <setting>, which is one of\n" ++
" [args, prog, prompt, editor, stop]\n" ++
+ " :showi language show language flags for interactive evaluation\n" ++
"\n"
findEditor :: IO String
@@ -330,6 +335,11 @@ interactiveUI srcs maybe_exprs = do
-- Initialise buffering for the *interpreted* I/O system
initInterpBuffering
+ -- The initial set of DynFlags used for interactive evaluation is the same
+ -- as the global DynFlags, plus -XExtendedDefaultRules
+ dflags <- getDynFlags
+ GHC.setInteractiveDynFlags (xopt_set dflags Opt_ExtendedDefaultRules)
+
liftIO $ when (isNothing maybe_exprs) $ do
-- Only for GHCi (not runghc and ghc -e):
@@ -381,8 +391,9 @@ withGhcAppData right left = do
runGHCi :: [(FilePath, Maybe Phase)] -> Maybe [String] -> GHCi ()
runGHCi paths maybe_exprs = do
+ dflags <- getDynFlags
let
- read_dot_files = not opt_IgnoreDotGhci
+ read_dot_files = not (dopt Opt_IgnoreDotGhci dflags)
current_dir = return (Just ".ghci")
@@ -421,11 +432,10 @@ runGHCi paths maybe_exprs = do
getDirectory f = case takeDirectory f of "" -> "."; d -> d
--
- setGHCContext []
+ setGHCContextFromGHCiState
when (read_dot_files) $ do
- mcfgs0 <- sequence $ [ current_dir, app_user_dir, home_dir ]
- ++ map (return . Just) opt_GhciScripts
+ mcfgs0 <- sequence $ [ current_dir, app_user_dir, home_dir ] ++ map (return . Just ) (ghciScripts dflags)
mcfgs <- liftIO $ mapM canonicalizePath' (catMaybes mcfgs0)
mapM_ sourceConfigFile $ nub $ catMaybes mcfgs
-- nub, because we don't want to read .ghci twice if the
@@ -437,17 +447,16 @@ runGHCi paths maybe_exprs = do
when (not (null paths)) $ do
ok <- ghciHandle (\e -> do showException e; return Failed) $
-- TODO: this is a hack.
- runInputTWithPrefs defaultPrefs defaultSettings $ do
- let (filePaths, phases) = unzip paths
- filePaths' <- mapM (Encoding.decode . BS.pack) filePaths
- loadModule (zip filePaths' phases)
+ runInputTWithPrefs defaultPrefs defaultSettings $
+ loadModule paths
when (isJust maybe_exprs && failed ok) $
liftIO (exitWith (ExitFailure 1))
+ installInteractivePrint (interactivePrint dflags) (isJust maybe_exprs)
+
-- if verbosity is greater than 0, or we are connected to a
-- terminal, display the prompt in the interactive loop.
is_tty <- liftIO (hIsTerminalDevice stdin)
- dflags <- getDynFlags
let show_prompt = verbosity dflags > 0 || is_tty
-- reset line number
@@ -575,8 +584,7 @@ mkPrompt = do
rev_imports = reverse imports -- rightmost are the most recent
modules_bit =
- hsep [ char '*' <> ppr (GHC.moduleName m)
- | IIModule m <- rev_imports ] <+>
+ hsep [ char '*' <> ppr m | IIModule m <- rev_imports ] <+>
hsep (map ppr [ myIdeclName d | IIDecl d <- rev_imports ])
-- use the 'as' name if there is one
@@ -591,7 +599,8 @@ mkPrompt = do
f [] = empty
st <- getGHCiState
- return (showSDoc (f (prompt st)))
+ dflags <- getDynFlags
+ return (showSDoc dflags (f (prompt st)))
queryQueue :: GHCi (Maybe String)
@@ -602,6 +611,18 @@ queryQueue = do
c:cs -> do setGHCiState st{ cmdqueue = cs }
return (Just c)
+-- Reconfigurable pretty-printing Ticket #5461
+installInteractivePrint :: Maybe String -> Bool -> GHCi ()
+installInteractivePrint Nothing _ = return ()
+installInteractivePrint (Just ipFun) exprmode = do
+ ok <- trySuccess $ do
+ (name:_) <- GHC.parseName ipFun
+ modifySession (\he -> let new_ic = setInteractivePrintName (hsc_IC he) name
+ in he{hsc_IC = new_ic})
+ return Succeeded
+
+ when (failed ok && exprmode) $ liftIO (exitWith (ExitFailure 1))
+
-- | The main read-eval-print loop
runCommands :: InputT GHCi (Maybe String) -> InputT GHCi ()
runCommands = runCommands' handler
@@ -957,8 +978,9 @@ info :: String -> InputT GHCi ()
info "" = ghcError (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
info s = handleSourceError GHC.printException $ do
unqual <- GHC.getPrintUnqual
+ dflags <- getDynFlags
sdocs <- mapM infoThing (words s)
- mapM_ (liftIO . putStrLn . showSDocForUser unqual) sdocs
+ mapM_ (liftIO . putStrLn . showSDocForUser dflags unqual) sdocs
infoThing :: GHC.GhcMonad m => String -> m SDoc
infoThing str = do
@@ -984,12 +1006,12 @@ filterOutChildren get_thing xs
pprInfo :: PrintExplicitForalls -> (TyThing, Fixity, [GHC.ClsInst]) -> SDoc
pprInfo pefas (thing, fixity, insts)
= pprTyThingInContextLoc pefas thing
- $$ show_fixity fixity
+ $$ show_fixity
$$ vcat (map GHC.pprInstance insts)
where
- show_fixity fix
- | fix == GHC.defaultFixity = empty
- | otherwise = ppr fix <+> ppr (GHC.getName thing)
+ show_fixity
+ | fixity == GHC.defaultFixity = empty
+ | otherwise = ppr fixity <+> pprInfixName (GHC.getName thing)
-----------------------------------------------------------------------------
-- :main
@@ -1045,15 +1067,16 @@ trySuccess act =
-----------------------------------------------------------------------------
-- :edit
-editFile :: String -> GHCi ()
+editFile :: String -> InputT GHCi ()
editFile str =
- do file <- if null str then chooseEditFile else return str
- st <- getGHCiState
+ do file <- if null str then lift chooseEditFile else return str
+ st <- lift getGHCiState
let cmd = editor st
when (null cmd)
$ ghcError (CmdLineError "editor not set, use :set editor")
- _ <- liftIO $ system (cmd ++ ' ':file)
- return ()
+ code <- liftIO $ system (cmd ++ ' ':file)
+ when (code == ExitSuccess)
+ $ reloadModule ""
-- The user didn't specify a file so we pick one for them.
-- Our strategy is to pick the first module that failed to load,
@@ -1168,7 +1191,8 @@ checkModule m = do
let modl = GHC.mkModuleName m
ok <- handleSourceError (\e -> GHC.printException e >> return False) $ do
r <- GHC.typecheckModule =<< GHC.parseModule =<< GHC.getModSummary modl
- liftIO $ putStrLn $ showSDoc $
+ dflags <- getDynFlags
+ liftIO $ putStrLn $ showSDoc dflags $
case GHC.moduleInfo r of
cm | Just scope <- GHC.modInfoTopLevelScope cm ->
let
@@ -1285,8 +1309,13 @@ setContextAfterLoad keep_ctxt ms = do
load_this summary | m <- GHC.ms_mod summary = do
is_interp <- GHC.moduleIsInterpreted m
- let new_ctx | is_interp = [IIModule m]
- | otherwise = [IIDecl $ simpleImportDecl (GHC.moduleName m)]
+ dflags <- getDynFlags
+ let star_ok = is_interp && not (safeLanguageOn dflags)
+ -- We import the module with a * iff
+ -- - it is interpreted, and
+ -- - -XSafe is off (it doesn't allow *-imports)
+ let new_ctx | star_ok = [mkIIModule (GHC.moduleName m)]
+ | otherwise = [mkIIDecl (GHC.moduleName m)]
setContextKeepingPackageModules keep_ctxt new_ctx
@@ -1304,7 +1333,7 @@ setContextKeepingPackageModules keep_ctx trans_ctx = do
new_rem_ctx <- if keep_ctx then return rem_ctx
else keepPackageImports rem_ctx
setGHCiState st{ remembered_ctx = new_rem_ctx,
- transient_ctx = trans_ctx }
+ transient_ctx = filterSubsumed new_rem_ctx trans_ctx }
setGHCContextFromGHCiState
@@ -1332,9 +1361,9 @@ modulesLoadedMsg ok mods = do
punctuate comma (map ppr mods)) <> text "."
case ok of
Failed ->
- liftIO $ putStrLn $ showSDoc (text "Failed, modules loaded: " <> mod_commas)
+ liftIO $ putStrLn $ showSDoc dflags (text "Failed, modules loaded: " <> mod_commas)
Succeeded ->
- liftIO $ putStrLn $ showSDoc (text "Ok, modules loaded: " <> mod_commas)
+ liftIO $ putStrLn $ showSDoc dflags (text "Ok, modules loaded: " <> mod_commas)
-----------------------------------------------------------------------------
@@ -1432,7 +1461,7 @@ isSafeModule m = do
let iface' = fromJust iface
- trust = showPpr $ getSafeMode $ GHC.mi_trust iface'
+ trust = showPpr dflags $ getSafeMode $ GHC.mi_trust iface'
pkgT = packageTrusted dflags m
pkg = if pkgT then "trusted" else "untrusted"
(good', bad') = tallyPkgs dflags $
@@ -1462,7 +1491,7 @@ isSafeModule m = do
False -> liftIO $ putStrLn $ mname ++ " is NOT trusted!"
where
- goodTrust t = t `elem` [Sf_Safe, Sf_SafeInfered, Sf_Trustworthy]
+ goodTrust t = t `elem` [Sf_Safe, Sf_SafeInferred, Sf_Trustworthy]
mname = GHC.moduleNameString $ GHC.moduleName m
@@ -1502,7 +1531,7 @@ guessCurrentModule cmd
when (null imports) $ ghcError $
CmdLineError (':' : cmd ++ ": no current module")
case (head imports) of
- IIModule m -> return m
+ IIModule m -> GHC.findModule m Nothing
IIDecl d -> GHC.findModule (unLoc (ideclName d)) (ideclPkgQual d)
-- without bang, show items in context of their parents and omit children
@@ -1579,7 +1608,7 @@ browseModule bang modl exports_only = do
prettyThings = map (pretty pefas) things
prettyThings' | bang = annotate $ zip modNames prettyThings
| otherwise = prettyThings
- liftIO $ putStrLn $ showSDocForUser unqual (vcat prettyThings')
+ liftIO $ putStrLn $ showSDocForUser dflags unqual (vcat prettyThings')
-- ToDo: modInfoInstances currently throws an exception for
-- package modules. When it works, we can do this:
-- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
@@ -1609,69 +1638,109 @@ moduleCmd str
sensible ('*':m) = looksLikeModuleName m
sensible m = looksLikeModuleName m
- starred ('*':m) = Left m
- starred m = Right m
+ starred ('*':m) = Left (GHC.mkModuleName m)
+ starred m = Right (GHC.mkModuleName m)
+
-addModulesToContext :: [String] -> [String] -> GHCi ()
-addModulesToContext as bs = do
- mapM_ (add True) as
- mapM_ (add False) bs
+-- -----------------------------------------------------------------------------
+-- Four ways to manipulate the context:
+-- (a) :module +<stuff>: addModulesToContext
+-- (b) :module -<stuff>: remModulesFromContext
+-- (c) :module <stuff>: setContext
+-- (d) import <module>...: addImportToContext
+
+addModulesToContext :: [ModuleName] -> [ModuleName] -> GHCi ()
+addModulesToContext starred unstarred = restoreContextOnFailure $ do
+ addModulesToContext_ starred unstarred
+
+addModulesToContext_ :: [ModuleName] -> [ModuleName] -> GHCi ()
+addModulesToContext_ starred unstarred = do
+ mapM_ addII (map mkIIModule starred ++ map mkIIDecl unstarred)
setGHCContextFromGHCiState
- where
- add :: Bool -> String -> GHCi ()
- add star str = do
- i <- checkAdd star str
- modifyGHCiState $ \st ->
- st { remembered_ctx = addNotSubsumed i (remembered_ctx st) }
-remModulesFromContext :: [String] -> [String] -> GHCi ()
-remModulesFromContext as bs = do
- mapM_ rm (as ++ bs)
+remModulesFromContext :: [ModuleName] -> [ModuleName] -> GHCi ()
+remModulesFromContext starred unstarred = do
+ -- we do *not* call restoreContextOnFailure here. If the user
+ -- is trying to fix up a context that contains errors by removing
+ -- modules, we don't want GHC to silently put them back in again.
+ mapM_ rm (starred ++ unstarred)
setGHCContextFromGHCiState
where
- rm :: String -> GHCi ()
+ rm :: ModuleName -> GHCi ()
rm str = do
- m <- moduleName <$> lookupModule str
+ m <- moduleName <$> lookupModuleName str
let filt = filter ((/=) m . iiModuleName)
modifyGHCiState $ \st ->
st { remembered_ctx = filt (remembered_ctx st)
, transient_ctx = filt (transient_ctx st) }
+setContext :: [ModuleName] -> [ModuleName] -> GHCi ()
+setContext starred unstarred = restoreContextOnFailure $ do
+ modifyGHCiState $ \st -> st { remembered_ctx = [], transient_ctx = [] }
+ -- delete the transient context
+ addModulesToContext_ starred unstarred
+
addImportToContext :: String -> GHCi ()
-addImportToContext str = do
+addImportToContext str = restoreContextOnFailure $ do
idecl <- GHC.parseImportDecl str
- _ <- GHC.lookupModule (unLoc (ideclName idecl)) Nothing -- #5836
- modifyGHCiState $ \st ->
- st { remembered_ctx = addNotSubsumed (IIDecl idecl) (remembered_ctx st) }
+ addII (IIDecl idecl) -- #5836
setGHCContextFromGHCiState
-setContext :: [String] -> [String] -> GHCi ()
-setContext starred not_starred = do
- is1 <- mapM (checkAdd True) starred
- is2 <- mapM (checkAdd False) not_starred
- let iss = foldr addNotSubsumed [] (is1++is2)
- modifyGHCiState $ \st -> st { remembered_ctx = iss, transient_ctx = [] }
- -- delete the transient context
- setGHCContextFromGHCiState
+-- Util used by addImportToContext and addModulesToContext
+addII :: InteractiveImport -> GHCi ()
+addII iidecl = do
+ checkAdd iidecl
+ modifyGHCiState $ \st ->
+ st { remembered_ctx = addNotSubsumed iidecl (remembered_ctx st)
+ , transient_ctx = filter (not . (iidecl `iiSubsumes`))
+ (transient_ctx st)
+ }
-checkAdd :: Bool -> String -> GHCi InteractiveImport
-checkAdd star mstr = do
- dflags <- getDynFlags
- case safeLanguageOn dflags of
- True | star -> ghcError $ CmdLineError "can't use * imports with Safe Haskell"
+-- Sometimes we can't tell whether an import is valid or not until
+-- we finally call 'GHC.setContext'. e.g.
+--
+-- import System.IO (foo)
+--
+-- will fail because System.IO does not export foo. In this case we
+-- don't want to store the import in the context permanently, so we
+-- catch the failure from 'setGHCContextFromGHCiState' and set the
+-- context back to what it was.
+--
+-- See #6007
+--
+restoreContextOnFailure :: GHCi a -> GHCi a
+restoreContextOnFailure do_this = do
+ st <- getGHCiState
+ let rc = remembered_ctx st; tc = transient_ctx st
+ do_this `gonException` (modifyGHCiState $ \st' ->
+ st' { remembered_ctx = rc, transient_ctx = tc })
+
+-- -----------------------------------------------------------------------------
+-- Validate a module that we want to add to the context
- True -> do m <- lookupModule mstr
- s <- GHC.isModuleTrusted m
- case s of
- True -> return $ IIDecl (simpleImportDecl $ moduleName m)
- False -> ghcError $ CmdLineError $ "can't import " ++ mstr
- ++ " as it isn't trusted."
+checkAdd :: InteractiveImport -> GHCi ()
+checkAdd ii = do
+ dflags <- getDynFlags
+ let safe = safeLanguageOn dflags
+ case ii of
+ IIModule modname
+ | safe -> ghcError $ CmdLineError "can't use * imports with Safe Haskell"
+ | otherwise -> wantInterpretedModuleName modname >> return ()
+
+ IIDecl d -> do
+ let modname = unLoc (ideclName d)
+ pkgqual = ideclPkgQual d
+ m <- GHC.lookupModule modname pkgqual
+ when safe $ do
+ t <- GHC.isModuleTrusted m
+ when (not t) $
+ ghcError $ CmdLineError $
+ "can't import " ++ moduleNameString modname
+ ++ " as it isn't trusted."
- False | star -> do m <- wantInterpretedModule mstr
- return $ IIModule m
- False -> do m <- lookupModule mstr
- return $ IIDecl (simpleImportDecl $ moduleName m)
+-- -----------------------------------------------------------------------------
+-- Update the GHC API's view of the context
-- | Sets the GHC context from the GHCi state. The GHC context is
-- always set this way, we never modify it incrementally.
@@ -1687,46 +1756,36 @@ checkAdd star mstr = do
--
setGHCContextFromGHCiState :: GHCi ()
setGHCContextFromGHCiState = do
- let ok (IIModule m) = checkAdd True (moduleNameString (moduleName m))
- ok (IIDecl d) = checkAdd False (moduleNameString (unLoc (ideclName d)))
st <- getGHCiState
- iidecls <- filterM (tryBool . ok) (transient_ctx st ++ remembered_ctx st)
- setGHCContext iidecls
-
+ -- re-use checkAdd to check whether the module is valid. If the
+ -- module does not exist, we do *not* want to print an error
+ -- here, we just want to silently keep the module in the context
+ -- until such time as the module reappears again. So we ignore
+ -- the actual exception thrown by checkAdd, using tryBool to
+ -- turn it into a Bool.
+ iidecls <- filterM (tryBool.checkAdd) (transient_ctx st ++ remembered_ctx st)
+ dflags <- GHC.getSessionDynFlags
+ GHC.setContext $
+ if xopt Opt_ImplicitPrelude dflags && not (any isPreludeImport iidecls)
+ then iidecls ++ [implicitPreludeImport]
+ else iidecls
+ -- XXX put prel at the end, so that guessCurrentModule doesn't pick it up.
--- | Sets the GHC contexts to the given set of imports, adding a Prelude
--- import if there isn't an explicit one already.
-setGHCContext :: [InteractiveImport] -> GHCi ()
-setGHCContext iidecls = GHC.setContext (iidecls ++ prel)
- -- XXX put prel at the end, so that guessCurrentModule doesn't pick it up.
- where
- prel | any isPreludeImport iidecls = []
- | otherwise = [implicitPreludeImport]
-- -----------------------------------------------------------------------------
-- Utils on InteractiveImport
--- | Returns True if the left import subsumes the right one. Doesn't
--- need to be 100% accurate, conservatively returning False is fine.
---
--- Note that an IIModule does not necessarily subsume an IIDecl,
--- because e.g. a module might export a name that is only available
--- qualified within the module itself.
---
-iiSubsumes :: InteractiveImport -> InteractiveImport -> Bool
-iiSubsumes (IIModule m1) (IIModule m2) = m1==m2
-iiSubsumes (IIDecl d1) (IIDecl d2) -- A bit crude
- = unLoc (ideclName d1) == unLoc (ideclName d2)
- && ideclAs d1 == ideclAs d2
- && (not (ideclQualified d1) || ideclQualified d2)
- && (isNothing (ideclHiding d1) || ideclHiding d1 == ideclHiding d2)
-iiSubsumes _ _ = False
+mkIIModule :: ModuleName -> InteractiveImport
+mkIIModule = IIModule
-iiModules :: [InteractiveImport] -> [Module]
+mkIIDecl :: ModuleName -> InteractiveImport
+mkIIDecl = IIDecl . simpleImportDecl
+
+iiModules :: [InteractiveImport] -> [ModuleName]
iiModules is = [m | IIModule m <- is]
iiModuleName :: InteractiveImport -> ModuleName
-iiModuleName (IIModule m) = moduleName m
+iiModuleName (IIModule m) = m
iiModuleName (IIDecl d) = unLoc (ideclName d)
preludeModuleName :: ModuleName
@@ -1745,6 +1804,39 @@ addNotSubsumed i is
| any (`iiSubsumes` i) is = is
| otherwise = i : filter (not . (i `iiSubsumes`)) is
+-- | @filterSubsumed is js@ returns the elements of @js@ not subsumed
+-- by any of @is@.
+filterSubsumed :: [InteractiveImport] -> [InteractiveImport]
+ -> [InteractiveImport]
+filterSubsumed is js = filter (\j -> not (any (`iiSubsumes` j) is)) js
+
+-- | Returns True if the left import subsumes the right one. Doesn't
+-- need to be 100% accurate, conservatively returning False is fine.
+-- (EXCEPT: (IIModule m) *must* subsume itself, otherwise a panic in
+-- plusProv will ensue (#5904))
+--
+-- Note that an IIModule does not necessarily subsume an IIDecl,
+-- because e.g. a module might export a name that is only available
+-- qualified within the module itself.
+--
+-- Note that 'import M' does not necessarily subsume 'import M(foo)',
+-- because M might not export foo and we want an error to be produced
+-- in that case.
+--
+iiSubsumes :: InteractiveImport -> InteractiveImport -> Bool
+iiSubsumes (IIModule m1) (IIModule m2) = m1==m2
+iiSubsumes (IIDecl d1) (IIDecl d2) -- A bit crude
+ = unLoc (ideclName d1) == unLoc (ideclName d2)
+ && ideclAs d1 == ideclAs d2
+ && (not (ideclQualified d1) || ideclQualified d2)
+ && (ideclHiding d1 `hidingSubsumes` ideclHiding d2)
+ where
+ _ `hidingSubsumes` Just (False,[]) = True
+ Just (False, xs) `hidingSubsumes` Just (False,ys) = all (`elem` xs) ys
+ h1 `hidingSubsumes` h2 = h1 == h2
+iiSubsumes _ _ = False
+
+
----------------------------------------------------------------------------
-- :set
@@ -1756,35 +1848,68 @@ addNotSubsumed i is
-- figure out which ones & disallow them.
setCmd :: String -> GHCi ()
-setCmd ""
+setCmd "" = showOptions False
+setCmd "-a" = showOptions True
+setCmd str
+ = case getCmd str of
+ Right ("args", rest) ->
+ case toArgs rest of
+ Left err -> liftIO (hPutStrLn stderr err)
+ Right args -> setArgs args
+ Right ("prog", rest) ->
+ case toArgs rest of
+ Right [prog] -> setProg prog
+ _ -> liftIO (hPutStrLn stderr "syntax: :set prog <progname>")
+ Right ("prompt", rest) -> setPrompt $ dropWhile isSpace rest
+ Right ("editor", rest) -> setEditor $ dropWhile isSpace rest
+ Right ("stop", rest) -> setStop $ dropWhile isSpace rest
+ _ -> case toArgs str of
+ Left err -> liftIO (hPutStrLn stderr err)
+ Right wds -> setOptions wds
+
+setiCmd :: String -> GHCi ()
+setiCmd "" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags False
+setiCmd "-a" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags True
+setiCmd str =
+ case toArgs str of
+ Left err -> liftIO (hPutStrLn stderr err)
+ Right wds -> newDynFlags True wds
+
+showOptions :: Bool -> GHCi ()
+showOptions show_all
= do st <- getGHCiState
+ dflags <- getDynFlags
let opts = options st
- liftIO $ putStrLn (showSDoc (
+ liftIO $ putStrLn (showSDoc dflags (
text "options currently set: " <>
if null opts
then text "none."
else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
))
- dflags <- getDynFlags
- liftIO $ putStrLn (showSDoc (
- text "GHCi-specific dynamic flag settings:" $$
- nest 2 (vcat (map (flagSetting dflags) ghciFlags))
- ))
- liftIO $ putStrLn (showSDoc (
- text "other dynamic, non-language, flag settings:" $$
- nest 2 (vcat (map (flagSetting dflags) others))
- ))
- liftIO $ putStrLn (showSDoc (
- text "warning settings:" $$
- nest 2 (vcat (map (warnSetting dflags) DynFlags.fWarningFlags))
- ))
-
- where flagSetting dflags (str, f, _)
- | dopt f dflags = fstr str
- | otherwise = fnostr str
- warnSetting dflags (str, f, _)
- | wopt f dflags = fstr str
- | otherwise = fnostr str
+ getDynFlags >>= liftIO . showDynFlags show_all
+
+
+showDynFlags :: Bool -> DynFlags -> IO ()
+showDynFlags show_all dflags = do
+ showLanguages' show_all dflags
+ putStrLn $ showSDoc dflags $
+ text "GHCi-specific dynamic flag settings:" $$
+ nest 2 (vcat (map (setting dopt) ghciFlags))
+ putStrLn $ showSDoc dflags $
+ text "other dynamic, non-language, flag settings:" $$
+ nest 2 (vcat (map (setting dopt) others))
+ putStrLn $ showSDoc dflags $
+ text "warning settings:" $$
+ nest 2 (vcat (map (setting wopt) DynFlags.fWarningFlags))
+ where
+ setting test (str, f, _)
+ | quiet = empty
+ | is_on = fstr str
+ | otherwise = fnostr str
+ where is_on = test f dflags
+ quiet = not show_all && test f default_dflags == is_on
+
+ default_dflags = defaultDynFlags (settings dflags)
fstr str = text "-f" <> text str
fnostr str = text "-fno-" <> text str
@@ -1797,22 +1922,6 @@ setCmd ""
,Opt_BreakOnError
,Opt_PrintEvldWithShow
]
-setCmd str
- = case getCmd str of
- Right ("args", rest) ->
- case toArgs rest of
- Left err -> liftIO (hPutStrLn stderr err)
- Right args -> setArgs args
- Right ("prog", rest) ->
- case toArgs rest of
- Right [prog] -> setProg prog
- _ -> liftIO (hPutStrLn stderr "syntax: :set prog <progname>")
- Right ("prompt", rest) -> setPrompt $ dropWhile isSpace rest
- Right ("editor", rest) -> setEditor $ dropWhile isSpace rest
- Right ("stop", rest) -> setStop $ dropWhile isSpace rest
- _ -> case toArgs str of
- Left err -> liftIO (hPutStrLn stderr err)
- Right wds -> setOptions wds
setArgs, setOptions :: [String] -> GHCi ()
setProg, setEditor, setStop, setPrompt :: String -> GHCi ()
@@ -1863,32 +1972,49 @@ setOptions wds =
let (plus_opts, minus_opts) = partitionWith isPlus wds
mapM_ setOpt plus_opts
-- then, dynamic flags
- newDynFlags minus_opts
+ newDynFlags False minus_opts
-newDynFlags :: [String] -> GHCi ()
-newDynFlags minus_opts = do
- dflags0 <- getDynFlags
- let pkg_flags = packageFlags dflags0
- (dflags1, leftovers, warns) <- liftIO $ GHC.parseDynamicFlags dflags0 $ map noLoc minus_opts
- liftIO $ handleFlagWarnings dflags1 warns
+newDynFlags :: Bool -> [String] -> GHCi ()
+newDynFlags interactive_only minus_opts = do
+ let lopts = map noLoc minus_opts
+ idflags0 <- GHC.getInteractiveDynFlags
+ (idflags1, leftovers, warns) <- GHC.parseDynamicFlags idflags0 lopts
+
+ liftIO $ handleFlagWarnings idflags1 warns
when (not $ null leftovers)
(ghcError . CmdLineError
$ "Some flags have not been recognized: "
++ (concat . intersperse ", " $ map unLoc leftovers))
- new_pkgs <- setDynFlags dflags1
-
- -- if the package flags changed, we should reset the context
- -- and link the new packages.
- dflags2 <- getDynFlags
- when (packageFlags dflags2 /= pkg_flags) $ do
- liftIO $ hPutStrLn stderr "package flags have changed, resetting and loading new packages..."
- GHC.setTargets []
- _ <- GHC.load LoadAllTargets
- liftIO (linkPackages dflags2 new_pkgs)
- -- package flags changed, we can't re-use any of the old context
- setContextAfterLoad False []
+ when (interactive_only &&
+ packageFlags idflags1 /= packageFlags idflags0) $ do
+ liftIO $ hPutStrLn stderr "cannot set package flags with :seti; use :set"
+ GHC.setInteractiveDynFlags idflags1
+ installInteractivePrint (interactivePrint idflags1) False
+
+ dflags0 <- getDynFlags
+ when (not interactive_only) $ do
+ (dflags1, _, _) <- liftIO $ GHC.parseDynamicFlags dflags0 lopts
+ new_pkgs <- GHC.setProgramDynFlags dflags1
+
+ -- if the package flags changed, reset the context and link
+ -- the new packages.
+ dflags2 <- getDynFlags
+ when (packageFlags dflags2 /= packageFlags dflags0) $ do
+ liftIO $ hPutStrLn stderr "package flags have changed, resetting and loading new packages..."
+ GHC.setTargets []
+ _ <- GHC.load LoadAllTargets
+ liftIO $ linkPackages dflags2 new_pkgs
+ -- package flags changed, we can't re-use any of the old context
+ setContextAfterLoad False []
+ -- and copy the package state to the interactive DynFlags
+ idflags <- GHC.getInteractiveDynFlags
+ GHC.setInteractiveDynFlags
+ idflags{ pkgState = pkgState dflags2
+ , pkgDatabase = pkgDatabase dflags2
+ , packageFlags = packageFlags dflags2 }
+
return ()
@@ -1919,7 +2045,7 @@ unsetOptions str
mapM_ unsetOpt plus_opts
no_flags <- mapM no_flag minus_opts
- newDynFlags no_flags
+ newDynFlags False no_flags
isMinus :: String -> Bool
isMinus ('-':_) = True
@@ -1959,6 +2085,8 @@ optToStr RevertCAFs = "r"
-- :show
showCmd :: String -> GHCi ()
+showCmd "" = showOptions False
+showCmd "-a" = showOptions True
showCmd str = do
st <- getGHCiState
case words str of
@@ -1970,23 +2098,36 @@ showCmd str = do
["imports"] -> showImports
["modules" ] -> showModules
["bindings"] -> showBindings
- ["linker"] -> liftIO showLinkerState
+ ["linker"] ->
+ do dflags <- getDynFlags
+ liftIO $ showLinkerState dflags
["breaks"] -> showBkptTable
["context"] -> showContext
["packages"] -> showPackages
- ["languages"] -> showLanguages
+ ["languages"] -> showLanguages -- backwards compat
+ ["language"] -> showLanguages
+ ["lang"] -> showLanguages -- useful abbreviation
_ -> ghcError (CmdLineError ("syntax: :show [ args | prog | prompt | editor | stop | modules | bindings\n"++
- " | breaks | context | packages | languages ]"))
+ " | breaks | context | packages | language ]"))
+
+showiCmd :: String -> GHCi ()
+showiCmd str = do
+ case words str of
+ ["languages"] -> showiLanguages -- backwards compat
+ ["language"] -> showiLanguages
+ ["lang"] -> showiLanguages -- useful abbreviation
+ _ -> ghcError (CmdLineError ("syntax: :showi language"))
showImports :: GHCi ()
showImports = do
st <- getGHCiState
+ dflags <- getDynFlags
let rem_ctx = reverse (remembered_ctx st)
trans_ctx = transient_ctx st
show_one (IIModule star_m)
- = ":module +*" ++ moduleNameString (moduleName star_m)
- show_one (IIDecl imp) = showSDoc (ppr imp)
+ = ":module +*" ++ moduleNameString star_m
+ show_one (IIDecl imp) = showPpr dflags imp
prel_imp
| any isPreludeImport (rem_ctx ++ trans_ctx) = []
@@ -2028,11 +2169,11 @@ showBindings = do
pprTT :: PrintExplicitForalls -> (TyThing, Fixity, [GHC.ClsInst]) -> SDoc
pprTT pefas (thing, fixity, _insts) =
pprTyThing pefas thing
- $$ show_fixity fixity
+ $$ show_fixity
where
- show_fixity fix
- | fix == GHC.defaultFixity = empty
- | otherwise = ppr fix <+> ppr (GHC.getName thing)
+ show_fixity
+ | fixity == GHC.defaultFixity = empty
+ | otherwise = ppr fixity <+> ppr (GHC.getName thing)
printTyThing :: TyThing -> GHCi ()
@@ -2056,8 +2197,9 @@ showContext = do
showPackages :: GHCi ()
showPackages = do
- pkg_flags <- fmap packageFlags getDynFlags
- liftIO $ putStrLn $ showSDoc $ vcat $
+ dflags <- getDynFlags
+ let pkg_flags = packageFlags dflags
+ liftIO $ putStrLn $ showSDoc dflags $ vcat $
text ("active package flags:"++if null pkg_flags then " none" else "")
: map showFlag pkg_flags
where showFlag (ExposePackage p) = text $ " -package " ++ p
@@ -2068,18 +2210,42 @@ showPackages = do
showFlag (DistrustPackage p) = text $ " -distrust " ++ p
showLanguages :: GHCi ()
-showLanguages = do
- dflags <- getDynFlags
- liftIO $ putStrLn $ showSDoc $ vcat $
- text "active language flags:" :
- [text (" -X" ++ str) | (str, f, _) <- DynFlags.xFlags, xopt f dflags]
-
+showLanguages = getDynFlags >>= liftIO . showLanguages' False
+
+showiLanguages :: GHCi ()
+showiLanguages = GHC.getInteractiveDynFlags >>= liftIO . showLanguages' False
+
+showLanguages' :: Bool -> DynFlags -> IO ()
+showLanguages' show_all dflags =
+ putStrLn $ showSDoc dflags $ vcat
+ [ text "base language is: " <>
+ case language dflags of
+ Nothing -> text "Haskell2010"
+ Just Haskell98 -> text "Haskell98"
+ Just Haskell2010 -> text "Haskell2010"
+ , (if show_all then text "all active language options:"
+ else text "with the following modifiers:") $$
+ nest 2 (vcat (map (setting xopt) DynFlags.xFlags))
+ ]
+ where
+ setting test (str, f, _)
+ | quiet = empty
+ | is_on = text "-X" <> text str
+ | otherwise = text "-XNo" <> text str
+ where is_on = test f dflags
+ quiet = not show_all && test f default_dflags == is_on
+
+ default_dflags =
+ defaultDynFlags (settings dflags) `lang_set`
+ case language dflags of
+ Nothing -> Just Haskell2010
+ other -> other
-- -----------------------------------------------------------------------------
-- Completion
completeCmd, completeMacro, completeIdentifier, completeModule,
- completeSetModule,
+ completeSetModule, completeSeti, completeShowiOptions,
completeHomeModule, completeSetOptions, completeShowOptions,
completeHomeModuleOrFile, completeExpression
:: CompletionFunc GHCi
@@ -2116,26 +2282,27 @@ completeMacro = wrapIdentCompleter $ \w -> do
completeIdentifier = wrapIdentCompleter $ \w -> do
rdrs <- GHC.getRdrNamesInScope
- return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
+ dflags <- GHC.getSessionDynFlags
+ return (filter (w `isPrefixOf`) (map (showPpr dflags) rdrs))
completeModule = wrapIdentCompleter $ \w -> do
dflags <- GHC.getSessionDynFlags
let pkg_mods = allExposedModules dflags
loaded_mods <- liftM (map GHC.ms_mod_name) getLoadedModules
return $ filter (w `isPrefixOf`)
- $ map (showSDoc.ppr) $ loaded_mods ++ pkg_mods
+ $ map (showPpr dflags) $ loaded_mods ++ pkg_mods
completeSetModule = wrapIdentCompleterWithModifier "+-" $ \m w -> do
+ dflags <- GHC.getSessionDynFlags
modules <- case m of
Just '-' -> do
imports <- GHC.getContext
return $ map iiModuleName imports
_ -> do
- dflags <- GHC.getSessionDynFlags
let pkg_mods = allExposedModules dflags
loaded_mods <- liftM (map GHC.ms_mod_name) getLoadedModules
return $ loaded_mods ++ pkg_mods
- return $ filter (w `isPrefixOf`) $ map (showSDoc.ppr) modules
+ return $ filter (w `isPrefixOf`) $ map (showPpr dflags) modules
completeHomeModule = wrapIdentCompleter listHomeModules
@@ -2143,19 +2310,27 @@ listHomeModules :: String -> GHCi [String]
listHomeModules w = do
g <- GHC.getModuleGraph
let home_mods = map GHC.ms_mod_name g
+ dflags <- getDynFlags
return $ sort $ filter (w `isPrefixOf`)
- $ map (showSDoc.ppr) home_mods
+ $ map (showPpr dflags) home_mods
completeSetOptions = wrapCompleter flagWordBreakChars $ \w -> do
return (filter (w `isPrefixOf`) opts)
where opts = "args":"prog":"prompt":"editor":"stop":flagList
flagList = map head $ group $ sort allFlags
+completeSeti = wrapCompleter flagWordBreakChars $ \w -> do
+ return (filter (w `isPrefixOf`) flagList)
+ where flagList = map head $ group $ sort allFlags
+
completeShowOptions = wrapCompleter flagWordBreakChars $ \w -> do
return (filter (w `isPrefixOf`) opts)
where opts = ["args", "prog", "prompt", "editor", "stop",
"modules", "bindings", "linker", "breaks",
- "context", "packages", "languages"]
+ "context", "packages", "language"]
+
+completeShowiOptions = wrapCompleter flagWordBreakChars $ \w -> do
+ return (filter (w `isPrefixOf`) ["language"])
completeHomeModuleOrFile = completeWord Nothing filenameWordBreakChars
$ unionComplete (fmap (map simpleCompletion) . listHomeModules)
@@ -2352,10 +2527,11 @@ breakSwitch (arg1:rest)
| all isDigit arg1 = do
imports <- GHC.getContext
case iiModules imports of
- (md : _) -> breakByModuleLine md (read arg1) rest
+ (mn : _) -> do
+ md <- lookupModuleName mn
+ breakByModuleLine md (read arg1) rest
[] -> do
- liftIO $ putStrLn "Cannot find default module for breakpoint."
- liftIO $ putStrLn "Perhaps no modules are loaded for debugging?"
+ liftIO $ putStrLn "No modules are loaded with debugging support."
| otherwise = do -- try parsing it as an identifier
wantNameFromInterpretedModule noCanDo arg1 $ \name -> do
let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)
@@ -2514,7 +2690,9 @@ list2 [arg] | all isDigit arg = do
imports <- GHC.getContext
case iiModules imports of
[] -> liftIO $ putStrLn "No module to list"
- (md : _) -> listModuleLine md (read arg)
+ (mn : _) -> do
+ md <- lift $ lookupModuleName mn
+ listModuleLine md (read arg)
list2 [arg1,arg2] | looksLikeModuleName arg1, all isDigit arg2 = do
md <- wantInterpretedModule arg1
listModuleLine md (read arg2)
@@ -2718,14 +2896,16 @@ showException :: SomeException -> GHCi ()
showException se =
liftIO $ case fromException se of
-- omit the location for CmdLineError:
- Just (CmdLineError s) -> putStrLn s
+ Just (CmdLineError s) -> putException s
-- ditto:
- Just ph@(PhaseFailed {}) -> putStrLn (showGhcException ph "")
- Just other_ghc_ex -> print other_ghc_ex
+ Just ph@(PhaseFailed {}) -> putException (showGhcException ph "")
+ Just other_ghc_ex -> putException (show other_ghc_ex)
Nothing ->
case fromException se of
- Just UserInterrupt -> putStrLn "Interrupted."
- _ -> putStrLn ("*** Exception: " ++ show se)
+ Just UserInterrupt -> putException "Interrupted."
+ _ -> putException ("*** Exception: " ++ show se)
+ where
+ putException = hPutStrLn stderr
-----------------------------------------------------------------------------
@@ -2735,8 +2915,8 @@ showException se =
-- in an exception loop (eg. let a = error a in a) the ^C exception
-- may never be delivered. Thanks to Marcin for pointing out the bug.
-ghciHandle :: MonadException m => (SomeException -> m a) -> m a -> m a
-ghciHandle h m = Haskeline.catch m $ \e -> unblock (h e)
+ghciHandle :: ExceptionMonad m => (SomeException -> m a) -> m a -> m a
+ghciHandle h m = gcatch m $ \e -> gunblock (h e)
ghciTry :: GHCi a -> GHCi (Either SomeException a)
ghciTry (GHCi m) = GHCi $ \s -> gtry (m s)
@@ -2752,7 +2932,10 @@ tryBool m = do
-- Utils
lookupModule :: GHC.GhcMonad m => String -> m Module
-lookupModule mName = GHC.lookupModule (GHC.mkModuleName mName) Nothing
+lookupModule mName = lookupModuleName (GHC.mkModuleName mName)
+
+lookupModuleName :: GHC.GhcMonad m => ModuleName -> m Module
+lookupModuleName mName = GHC.lookupModule mName Nothing
isHomeModule :: Module -> Bool
isHomeModule m = GHC.modulePackageId m == mainPackageId
@@ -2760,10 +2943,7 @@ isHomeModule m = GHC.modulePackageId m == mainPackageId
-- TODO: won't work if home dir is encoded.
-- (changeDirectory may not work either in that case.)
expandPath :: MonadIO m => String -> InputT m String
-expandPath p = do
- exp_path <- liftIO $ expandPathIO p
- e <- fmap BS.unpack $ Encoding.encode exp_path
- return e
+expandPath = liftIO . expandPathIO
expandPathIO :: String -> IO String
expandPathIO p =
@@ -2775,8 +2955,12 @@ expandPathIO p =
return other
wantInterpretedModule :: GHC.GhcMonad m => String -> m Module
-wantInterpretedModule str = do
- modl <- lookupModule str
+wantInterpretedModule str = wantInterpretedModuleName (GHC.mkModuleName str)
+
+wantInterpretedModuleName :: GHC.GhcMonad m => ModuleName -> m Module
+wantInterpretedModuleName modname = do
+ modl <- lookupModuleName modname
+ let str = moduleNameString modname
dflags <- getDynFlags
when (GHC.modulePackageId modl /= thisPackage dflags) $
ghcError (CmdLineError ("module '" ++ str ++ "' is from another package;\nthis command requires an interpreted module"))
diff --git a/ghc/Main.hs b/ghc/Main.hs
index a1943cff50..d757c2d706 100644
--- a/ghc/Main.hs
+++ b/ghc/Main.hs
@@ -30,6 +30,7 @@ import InteractiveUI ( interactiveUI, ghciWelcomeMsg )
-- Various other random stuff that we need
import Config
+import Constants
import HscTypes
import Packages ( dumpPackages )
import DriverPhases ( Phase(..), isSourceFilename, anyHsc,
@@ -78,7 +79,8 @@ import Data.Maybe
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
- GHC.defaultErrorHandler defaultLogAction $ do
+ hSetBuffering stderr NoBuffering
+ GHC.defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
-- 1. extract the -B flag from the args
argv0 <- getArgs
@@ -155,6 +157,8 @@ main' postLoadMode dflags0 args flagWarnings = do
-- turn on -fimplicit-import-qualified for GHCi now, so that it
-- can be overriden from the command-line
+ -- XXX: this should really be in the interactive DynFlags, but
+ -- we don't set that until later in interactiveUI
dflags1a | DoInteractive <- postLoadMode = imp_qual_enabled
| DoEval _ <- postLoadMode = imp_qual_enabled
| otherwise = dflags1
@@ -164,6 +168,8 @@ main' postLoadMode dflags0 args flagWarnings = do
-- Leftover ones are presumably files
(dflags2, fileish_args, dynamicFlagWarnings) <- GHC.parseDynamicFlags dflags1a args
+ GHC.prettyPrintGhcErrors dflags2 $ do
+
let flagWarnings' = flagWarnings ++ dynamicFlagWarnings
handleSourceError (\e -> do
@@ -253,6 +259,10 @@ partition_args (arg:args) srcs objs
- module names (not forgetting hierarchical module names),
+ - things beginning with '-' are flags that were not recognised by
+ the flag parser, and we want them to generate errors later in
+ checkOptions, so we class them as source files (#5921)
+
- and finally we consider everything not containing a '.' to be
a comp manager input, as shorthand for a .hs or .lhs filename.
@@ -262,6 +272,7 @@ partition_args (arg:args) srcs objs
looks_like_an_input :: String -> Bool
looks_like_an_input m = isSourceFilename m
|| looksLikeModuleName m
+ || "-" `isPrefixOf` m
|| '.' `notElem` m
-- -----------------------------------------------------------------------------
@@ -760,7 +771,7 @@ abiHash strs = do
r <- findImportedModule hsc_env modname Nothing
case r of
Found _ m -> return m
- _error -> ghcError $ CmdLineError $ showSDoc $
+ _error -> ghcError $ CmdLineError $ showSDoc dflags $
cannotFindInterface dflags modname r
mods <- mapM find_it (map fst strs)
@@ -769,13 +780,13 @@ abiHash strs = do
ifaces <- initIfaceCheck hsc_env $ mapM get_iface mods
bh <- openBinMem (3*1024) -- just less than a block
- put_ bh opt_HiVersion
+ put_ bh hiVersion
-- package hashes change when the compiler version changes (for now)
-- see #5328
mapM_ (put_ bh . mi_mod_hash) ifaces
f <- fingerprintBinMem bh
- putStrLn (showSDoc (ppr f))
+ putStrLn (showPpr dflags f)
-- -----------------------------------------------------------------------------
-- Util
diff --git a/ghc/ghc-bin.cabal.in b/ghc/ghc-bin.cabal.in
index 0cf51d05e1..a7e7bbae66 100644
--- a/ghc/ghc-bin.cabal.in
+++ b/ghc/ghc-bin.cabal.in
@@ -27,7 +27,7 @@ Executable ghc
Main-Is: Main.hs
Build-Depends: base >= 3 && < 5,
array >= 0.1 && < 0.5,
- bytestring >= 0.9 && < 0.10,
+ bytestring >= 0.9 && < 0.11,
directory >= 1 && < 1.2,
process >= 1 && < 1.2,
filepath >= 1 && < 1.4,
@@ -44,7 +44,7 @@ Executable ghc
CPP-Options: -DGHCI
GHC-Options: -fno-warn-name-shadowing
Other-Modules: InteractiveUI, GhciMonad, GhciTags
- Build-Depends: mtl, haskeline
+ Build-Depends: transformers, haskeline
Extensions: ForeignFunctionInterface,
UnboxedTuples,
FlexibleInstances,
diff --git a/ghc/ghc.mk b/ghc/ghc.mk
index 022ee85a84..a13f03b875 100644
--- a/ghc/ghc.mk
+++ b/ghc/ghc.mk
@@ -22,6 +22,15 @@ ghc_stage2_CONFIGURE_OPTS += --flags=ghci
ghc_stage3_CONFIGURE_OPTS += --flags=ghci
endif
+ifeq "$(compiler_stage1_VERSION_MUNGED)" "YES"
+# If we munge the stage1 version, and we're using a devel snapshot for
+# stage0, then stage1 may actually have an earlier version than stage0
+# (e.g. boot with ghc-7.5.20120316, building ghc-7.5). We therefore
+# need to tell Cabal to use version 7.5 of the ghc package when building
+# in ghc/stage1
+ghc_stage1_CONFIGURE_OPTS += --constraint "ghc == $(compiler_stage1_MUNGED_VERSION)"
+endif
+
ghc_stage1_MORE_HC_OPTS = $(GhcStage1HcOpts)
ghc_stage2_MORE_HC_OPTS = $(GhcStage2HcOpts)
ghc_stage3_MORE_HC_OPTS = $(GhcStage3HcOpts)
@@ -148,7 +157,7 @@ INSTALL_LIBS += settings
ifeq "$(Windows)" "NO"
install: install_ghc_link
-.PNONY: install_ghc_link
+.PHONY: install_ghc_link
install_ghc_link:
$(call removeFiles,"$(DESTDIR)$(bindir)/ghc")
$(LN_S) $(CrossCompilePrefix)ghc-$(ProjectVersion) "$(DESTDIR)$(bindir)/$(CrossCompilePrefix)ghc"
diff --git a/ghc/hschooks.c b/ghc/hschooks.c
index 037d4e18be..232ac08045 100644
--- a/ghc/hschooks.c
+++ b/ghc/hschooks.c
@@ -4,6 +4,7 @@ for various bits of the RTS. They are linked
in instead of the defaults.
*/
+#include "../rts/PosixSource.h"
#include "Rts.h"
#include "HsFFI.h"
@@ -31,8 +32,8 @@ defaultsHook (void)
}
void
-StackOverflowHook (unsigned long stack_size) /* in bytes */
+StackOverflowHook (lnat stack_size) /* in bytes */
{
- fprintf(stderr, "GHC stack-space overflow: current limit is %ld bytes.\nUse the `-K<size>' option to increase it.\n", stack_size);
+ fprintf(stderr, "GHC stack-space overflow: current limit is %zu bytes.\nUse the `-K<size>' option to increase it.\n", (size_t)stack_size);
}