diff options
author | nineonine <mail4chemik@gmail.com> | 2022-01-28 00:29:01 -0800 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-02-05 19:21:49 -0500 |
commit | 299acff08aa1b7b720ad2b69c459c514033bc395 (patch) | |
tree | 12cf8090a0b6a405b49a29aeefa47a24f3883452 | |
parent | 6af8e71ed7e749ba94e7a7eaf8b2229341bf35da (diff) | |
download | haskell-299acff08aa1b7b720ad2b69c459c514033bc395.tar.gz |
Exit with failure when -e fails (fixes #18411 #9916 #17560)
33 files changed, 263 insertions, 70 deletions
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs index 9a62d53d17..4043f3e247 100644 --- a/ghc/GHCi/UI.hs +++ b/ghc/GHCi/UI.hs @@ -67,6 +67,7 @@ import GHC.Types.TyThing import GHC.Types.TyThing.Ppr import GHC.Core.TyCo.Ppr import GHC.Types.SafeHaskell ( getSafeMode ) +import GHC.Types.SourceError ( SourceError ) import GHC.Types.Name import GHC.Types.Var ( varType ) import GHC.Iface.Syntax ( showToHeader ) @@ -291,13 +292,13 @@ flagWordBreakChars :: String flagWordBreakChars = " \t\n" -keepGoing :: (String -> GHCi ()) -> (String -> InputT GHCi Bool) +keepGoing :: (String -> GHCi ()) -> (String -> InputT GHCi CmdExecOutcome) keepGoing a str = keepGoing' (lift . a) str -keepGoingMulti :: (String -> GHCi ()) -> (String -> InputT GHCi Bool) +keepGoingMulti :: (String -> GHCi ()) -> (String -> InputT GHCi CmdExecOutcome) keepGoingMulti a str = keepGoingMulti' (lift . a) str -keepGoing' :: GhciMonad m => (a -> m ()) -> a -> m Bool +keepGoing' :: GhciMonad m => (a -> m ()) -> a -> m CmdExecOutcome keepGoing' a str = do in_multi <- inMultiMode if in_multi @@ -305,19 +306,19 @@ keepGoing' a str = do liftIO $ hPutStrLn stderr "Command is not supported (yet) in multi-mode" else a str - return False + return CmdSuccess -- For commands which are actually support in multi-mode, initially just :reload -keepGoingMulti' :: GhciMonad m => (String -> m ()) -> String -> m Bool -keepGoingMulti' a str = a str >> return False +keepGoingMulti' :: GhciMonad m => (String -> m ()) -> String -> m CmdExecOutcome +keepGoingMulti' a str = a str >> return CmdSuccess inMultiMode :: GhciMonad m => m Bool inMultiMode = multiMode <$> getGHCiState -keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi Bool) +keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi CmdExecOutcome) keepGoingPaths a str = do case toArgsNoLoc str of - Left err -> liftIO $ hPutStrLn stderr err >> return False + Left err -> liftIO $ hPutStrLn stderr err >> return CmdSuccess Right args -> keepGoing' a args defShortHelpText :: String @@ -763,7 +764,7 @@ runGHCi paths maybe_exprs = do $ topHandler e -- this used to be topHandlerFastExit, see #2228 runInputTWithPrefs defaultPrefs defaultSettings $ do - -- make `ghc -e` exit nonzero on invalid input, see #7962 + -- make `ghc -e` exit nonzero on failure, see #7962, #9916, #17560, #18441 _ <- runCommands' hdle (Just $ hdle (toException $ ExitFailure 1) >> return ()) (return Nothing) @@ -1029,7 +1030,7 @@ queryQueue = do return (Just c) -- Reconfigurable pretty-printing Ticket #5461 -installInteractivePrint :: GHC.GhcMonad m => Maybe String -> Bool -> m () +installInteractivePrint :: GhciMonad m => Maybe String -> Bool -> m () installInteractivePrint Nothing _ = return () installInteractivePrint (Just ipFun) exprmode = do ok <- trySuccess $ do @@ -1072,6 +1073,7 @@ runCommands' eh sourceErrorHandler gCmd = mask $ \unmask -> do -- Otherwise the result is Just b where b is True if the command succeeded; -- this is relevant only to ghc -e, which will exit with status 1 -- if the command was unsuccessful. GHCi will continue in either case. +-- TODO: replace Bool with CmdExecOutcome runOneCommand :: (SomeException -> GHCi Bool) -> InputT GHCi (Maybe String) -> InputT GHCi (Maybe Bool) runOneCommand eh gCmd = do @@ -1123,15 +1125,18 @@ runOneCommand eh gCmd = do -- SDM (2007-11-07): is userError the one to use here? collectError = userError "unterminated multiline command :{ .. :}" + cmdOutcome :: CmdExecOutcome -> Maybe Bool + cmdOutcome CleanExit = Nothing + cmdOutcome CmdSuccess = Just True + cmdOutcome CmdFailure = Just False + -- | Handle a line of input doCommand :: String -> InputT GHCi CommandResult -- command doCommand stmt | stmt'@(':' : cmd) <- removeSpaces stmt = do (stats, result) <- runWithStats (const Nothing) $ specialCommand cmd - let processResult True = Nothing - processResult False = Just True - return $ CommandComplete stmt' (processResult <$> result) stats + return $ CommandComplete stmt' (cmdOutcome <$> result) stats -- haskell doCommand stmt = do @@ -1409,7 +1414,7 @@ printTypeOfName n data MaybeCommand = GotCommand Command | BadCommand | NoLastCommand -- | Entry point for execution a ':<command>' input from user -specialCommand :: String -> InputT GHCi Bool +specialCommand :: String -> InputT GHCi CmdExecOutcome specialCommand ('!':str) = lift $ shellEscape (dropWhile isSpace str) specialCommand str = do let (cmd,rest) = break isSpace str @@ -1418,16 +1423,20 @@ specialCommand str = do case maybe_cmd of GotCommand cmd -> (cmdAction cmd) (dropWhile isSpace rest) BadCommand -> - do liftIO $ hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n" + do liftIO $ hPutStr stderr ("unknown command ':" ++ cmd ++ "'\n" ++ htxt) - return False + return CmdFailure NoLastCommand -> - do liftIO $ hPutStr stdout ("there is no last command to perform\n" + do liftIO $ hPutStr stderr ("there is no last command to perform\n" ++ htxt) - return False + return CmdFailure -shellEscape :: MonadIO m => String -> m Bool -shellEscape str = liftIO (system str >> return False) +shellEscape :: MonadIO m => String -> m CmdExecOutcome +shellEscape str = liftIO $ do + exitCode <- system str + case exitCode of + ExitSuccess -> return CmdSuccess + ExitFailure _ -> return CmdFailure lookupCommand :: GhciMonad m => String -> m (MaybeCommand) lookupCommand "" = do @@ -1662,15 +1671,15 @@ changeDirectory dir = do liftIO $ evalIO interp fhv _ -> pure () -trySuccess :: GHC.GhcMonad m => m SuccessFlag -> m SuccessFlag +trySuccess :: GhciMonad m => m SuccessFlag -> m SuccessFlag trySuccess act = - handleSourceError (\e -> do GHC.printException e + handleSourceError (\e -> do printErrAndMaybeExit e -- immediately exit fith failure if in ghc -e return Failed) $ do act -trySuccessWithRes :: (Monoid a, GHC.GhcMonad m) => m (SuccessFlag, a) -> m (SuccessFlag, a) +trySuccessWithRes :: (Monoid a, GhciMonad m) => m (SuccessFlag, a) -> m (SuccessFlag, a) trySuccessWithRes act = - handleSourceError (\e -> do GHC.printException e + handleSourceError (\e -> do printErrAndMaybeExit e -- immediately exit fith failure if in ghc -e return (Failed, mempty)) act @@ -1739,10 +1748,12 @@ chooseEditFile = -- :def defineMacro :: GhciMonad m => Bool{-overwrite-} -> String -> m () -defineMacro _ (':':_) = liftIO $ putStrLn - "macro name cannot start with a colon" -defineMacro _ ('!':_) = liftIO $ putStrLn - "macro name cannot start with an exclamation mark" +defineMacro _ (':':_) = (liftIO $ hPutStrLn stderr + "macro name cannot start with a colon") + >> failIfExprEvalMode +defineMacro _ ('!':_) = (liftIO $ hPutStrLn stderr + "macro name cannot start with an exclamation mark") + >> failIfExprEvalMode -- little code duplication allows to grep error msg defineMacro overwrite s = do let (macro_name, definition) = break isSpace s @@ -1765,7 +1776,7 @@ defineMacro overwrite s = do unless overwrite check_newname -- compile the expression - handleSourceError GHC.printException $ do + handleSourceError printErrAndMaybeExit $ do step <- getGhciStepIO expr <- GHC.parseExpr definition -- > ghciStepIO . definition :: String -> IO String @@ -1795,12 +1806,12 @@ runMacro :: GhciMonad m => GHC.ForeignHValue -- String -> IO String -> String - -> m Bool + -> m CmdExecOutcome runMacro fun s = do interp <- hscInterp <$> GHC.getSession str <- liftIO $ evalStringToIOString interp fun s enqueueCommands (lines str) - return False + return CmdSuccess ----------------------------------------------------------------------------- @@ -1824,7 +1835,7 @@ undefineMacro str = mapM_ undef (words str) -- :cmd cmdCmd :: GhciMonad m => String -> m () -cmdCmd str = handleSourceError GHC.printException $ do +cmdCmd str = handleSourceError printErrAndMaybeExit $ do step <- getGhciStepIO expr <- GHC.parseExpr str -- > ghciStepIO str :: IO String @@ -1854,7 +1865,7 @@ getGhciStepIO = do checkModule :: GhciMonad m => String -> m () checkModule m = do let modl = GHC.mkModuleName m - ok <- handleSourceError (\e -> GHC.printException e >> return False) $ do + ok <- handleSourceError (\e -> printErrAndMaybeExit e >> return False) $ do r <- GHC.typecheckModule =<< GHC.parseModule =<< GHC.getModSummary modl dflags <- getDynFlags liftIO $ putStrLn $ showSDoc dflags $ @@ -2048,11 +2059,11 @@ addModule files = do _ <- doLoadAndCollectInfo False LoadAllTargets return () where - checkTarget :: GHC.GhcMonad m => Target -> m Bool + checkTarget :: GhciMonad m => Target -> m Bool checkTarget Target { targetId = TargetModule m } = checkTargetModule m - checkTarget Target { targetId = TargetFile f _ } = liftIO $ checkTargetFile f + checkTarget Target { targetId = TargetFile f _ } = checkTargetFile f - checkTargetModule :: GHC.GhcMonad m => ModuleName -> m Bool + checkTargetModule :: GhciMonad m => ModuleName -> m Bool checkTargetModule m = do hsc_env <- GHC.getSession let home_unit = hsc_home_unit hsc_env @@ -2060,13 +2071,15 @@ addModule files = do Finder.findImportedModule hsc_env m (ThisPkg (homeUnitId home_unit)) case result of Found _ _ -> return True - _ -> (liftIO $ putStrLn $ - "Module " ++ moduleNameString m ++ " not found") >> return False + _ -> do liftIO $ hPutStrLn stderr ("Module " ++ moduleNameString m ++ " not found") + failIfExprEvalMode + return False - checkTargetFile :: String -> IO Bool + checkTargetFile :: GhciMonad m => String -> m Bool checkTargetFile f = do - exists <- (doesFileExist f) :: IO Bool - unless exists $ putStrLn $ "File " ++ f ++ " not found" + exists <- liftIO (doesFileExist f) + unless exists $ liftIO $ hPutStrLn stderr $ "File " ++ f ++ " not found" + failIfExprEvalMode return exists -- | @:unadd@ command @@ -2083,10 +2096,11 @@ reloadModule :: GhciMonad m => String -> m () reloadModule m = do session <- GHC.getSession let home_unit = homeUnitId (hsc_home_unit session) - void $ doLoadAndCollectInfo True (loadTargets home_unit) + ok <- doLoadAndCollectInfo True (loadTargets home_unit) + when (failed ok) failIfExprEvalMode where loadTargets hu | null m = LoadAllTargets - | otherwise = LoadUpTo (mkModule hu (GHC.mkModuleName m)) + | otherwise = LoadUpTo (mkModule hu (GHC.mkModuleName m)) reloadModuleDefer :: GhciMonad m => String -> m () reloadModuleDefer = wrapDeferTypeErrors . reloadModule @@ -2268,16 +2282,18 @@ modulesLoadedMsg ok mods = do -- Fix #9887 -- | Run an 'ExceptT' wrapped 'GhcMonad' while handling source errors --- and printing 'throwE' strings to 'stderr' -runExceptGhcMonad :: GHC.GhcMonad m => ExceptT SDoc m () -> m () -runExceptGhcMonad act = handleSourceError GHC.printException $ - either handleErr pure =<< - runExceptT act +-- and printing 'throwE' strings to 'stderr'. If in expression +-- evaluation mode - throw GhcException and exit. +runExceptGhciMonad :: GhciMonad m => ExceptT SDoc m () -> m () +runExceptGhciMonad act = handleSourceError GHC.printException $ + either handleErr pure =<< + runExceptT act where handleErr sdoc = do dflags <- getDynFlags unit_state <- hsc_units <$> GHC.getSession liftIO . hPutStrLn stderr . showSDocForUser dflags unit_state alwaysQualify $ sdoc + failIfExprEvalMode -- | Inverse of 'runExceptT' for \"pure\" computations -- (c.f. 'except' for 'Except') @@ -2287,8 +2303,8 @@ exceptT = ExceptT . pure ----------------------------------------------------------------------------- -- | @:type@ command. See also Note [TcRnExprMode] in GHC.Tc.Module. -typeOfExpr :: GHC.GhcMonad m => String -> m () -typeOfExpr str = handleSourceError GHC.printException $ +typeOfExpr :: GhciMonad m => String -> m () +typeOfExpr str = handleSourceError printErrAndMaybeExit $ case break isSpace str of ("+v", _) -> printForUser (text "`:type +v' has gone; use `:type' instead") ("+d", rest) -> do_it GHC.TM_Default (dropWhile isSpace rest) @@ -2303,7 +2319,7 @@ typeOfExpr str = handleSourceError GHC.printException $ -- | @:type-at@ command typeAtCmd :: GhciMonad m => String -> m () -typeAtCmd str = runExceptGhcMonad $ do +typeAtCmd str = runExceptGhciMonad $ do (span',sample) <- exceptT $ parseSpanArg str infos <- lift $ mod_infos <$> getGHCiState (info, ty) <- findType infos span' sample @@ -2314,7 +2330,7 @@ typeAtCmd str = runExceptGhcMonad $ do -- | @:uses@ command usesCmd :: GhciMonad m => String -> m () -usesCmd str = runExceptGhcMonad $ do +usesCmd str = runExceptGhciMonad $ do (span',sample) <- exceptT $ parseSpanArg str infos <- lift $ mod_infos <$> getGHCiState uses <- findNameUses infos span' sample @@ -2324,7 +2340,7 @@ usesCmd str = runExceptGhcMonad $ do -- | @:loc-at@ command locAtCmd :: GhciMonad m => String -> m () -locAtCmd str = runExceptGhcMonad $ do +locAtCmd str = runExceptGhciMonad $ do (span',sample) <- exceptT $ parseSpanArg str infos <- lift $ mod_infos <$> getGHCiState (_,_,sp) <- findLoc infos span' sample @@ -2334,7 +2350,7 @@ locAtCmd str = runExceptGhcMonad $ do -- | @:all-types@ command allTypesCmd :: GhciMonad m => String -> m () -allTypesCmd _ = runExceptGhcMonad $ do +allTypesCmd _ = runExceptGhciMonad $ do infos <- lift $ mod_infos <$> getGHCiState forM_ (M.elems infos) $ \mi -> forM_ (modinfoSpans mi) (lift . printSpan) @@ -2427,8 +2443,8 @@ showRealSrcSpan spn = concat [ fp, ":(", show sl, ",", show sc ----------------------------------------------------------------------------- -- | @:kind@ command -kindOfType :: GHC.GhcMonad m => Bool -> String -> m () -kindOfType norm str = handleSourceError GHC.printException $ do +kindOfType :: GhciMonad m => Bool -> String -> m () +kindOfType norm str = handleSourceError printErrAndMaybeExit $ do (ty, kind) <- GHC.typeKind norm str printForUser $ vcat [ text str <+> dcolon <+> pprSigmaType kind , ppWhen norm $ equals <+> pprSigmaType ty ] @@ -2436,8 +2452,8 @@ kindOfType norm str = handleSourceError GHC.printException $ do ----------------------------------------------------------------------------- -- :quit -quit :: Monad m => String -> m Bool -quit _ = return True +quit :: Monad m => String -> m CmdExecOutcome +quit _ = return CleanExit ----------------------------------------------------------------------------- @@ -4497,6 +4513,16 @@ showException se = where putException = hPutStrLn stderr +failIfExprEvalMode :: GhciMonad m => m () +failIfExprEvalMode = do + s <- getGHCiState + when (ghc_e s) $ + liftIO (exitWith (ExitFailure 1)) + +-- | When in expression evaluation mode (ghc -e), we want to exit immediately. +-- Otherwis, just print out the message. +printErrAndMaybeExit :: (GhciMonad m, MonadIO m, HasLogger m) => SourceError -> m () +printErrAndMaybeExit = (>> failIfExprEvalMode) . GHC.printException ----------------------------------------------------------------------------- -- recursive exception handlers diff --git a/ghc/GHCi/UI/Monad.hs b/ghc/GHCi/UI/Monad.hs index 3aead3e91e..aede0a9dc1 100644 --- a/ghc/GHCi/UI/Monad.hs +++ b/ghc/GHCi/UI/Monad.hs @@ -15,6 +15,7 @@ module GHCi.UI.Monad ( GHCiState(..), GhciMonad(..), GHCiOption(..), isOptionSet, setOption, unsetOption, Command(..), CommandResult(..), cmdSuccess, + CmdExecOutcome(..), LocalConfigBehaviour(..), PromptFunction, BreakLocation(..), @@ -173,8 +174,8 @@ data Command = Command { cmdName :: String -- ^ Name of GHCi command (e.g. "exit") - , cmdAction :: String -> InputT GHCi Bool - -- ^ The 'Bool' value denotes whether to exit GHCi + , cmdAction :: String -> InputT GHCi CmdExecOutcome + -- ^ The 'CmdExecOutcome' value denotes whether to exit GHCi cleanly or error out , cmdHidden :: Bool -- ^ Commands which are excluded from default completion -- and @:help@ summary. This is usually set for commands not @@ -183,6 +184,20 @@ data Command -- ^ 'CompletionFunc' for arguments } +-- | Used to denote GHCi command execution result. Specifically, used to +-- distinguish between two ghci execution modes - "REPL" and "Expression +-- evaluation mode (ghc -e)". When in "REPL" mode, we don't want to exit +-- GHCi session when error occurs, (which is when we use "CmdSuccess"). +-- Otherwise, when in expression evaluation mode, all command failures +-- should lead to GHCi session termination (with ExitFailure 1) which is +-- when "CmdFailure" is used(this is useful when executing scripts). +-- "CleanExit" is used to signal end of GHCi session (for example, when +-- ":quit" command is called). +data CmdExecOutcome + = CleanExit + | CmdSuccess + | CmdFailure + data CommandResult = CommandComplete { cmdInput :: String diff --git a/testsuite/tests/driver/T16167.stderr b/testsuite/tests/driver/T16167.stderr new file mode 100644 index 0000000000..59eac9cfdb --- /dev/null +++ b/testsuite/tests/driver/T16167.stderr @@ -0,0 +1 @@ +*** Exception: ExitFailure 1 diff --git a/testsuite/tests/ghc-e/should_fail/Makefile b/testsuite/tests/ghc-e/should_fail/Makefile index 827dfc776a..627d85fe43 100644 --- a/testsuite/tests/ghc-e/should_fail/Makefile +++ b/testsuite/tests/ghc-e/should_fail/Makefile @@ -3,22 +3,76 @@ include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk T7962: - -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "return (" + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "return (" || echo $$? >&2 T9905fail1: - -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "import This.Module.Does.Not.Exist" + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "import This.Module.Does.Not.Exist" || echo $$? >&2 T9905fail2: - -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "import Data.List (bogusIdentifier)" + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "import Data.List (bogusIdentifier)" || echo $$? >&2 T9905fail3: - -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "import Prelude (+)" # syntax error + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "import Prelude (+)" || echo $$? >&2 # syntax error ghc-e-fail1: - -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "class [" + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "class [" || echo $$? >&2 ghc-e-fail2: - -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "type A = A" + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e "type A = A" || echo $$? >&2 T9930fail: -'$(TEST_HC)' $(TEST_HC_OPTS) -v0 -x hs T9930 + +T18441fail0: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":" || echo $$? >&2 + +T18441fail1: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":abcde" || echo $$? >&2 + +T18441fail2: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":set -Xabcde" || echo $$? >&2 # unrecognized flag + +T18441fail4: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":load Abcde" || echo $$? >&2 # no module + +T18441fail5: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":reload Abcde" || echo $$? >&2 # no module + +T18441fail6: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":add Abcde" || echo $$? >&2 # no module + +T18441fail7: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":script Abcde" || echo $$? >&2 # no script + +T18441fail8: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":script Abc def" || echo $$? >&2 # bad script input + +T18441fail9: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":def abc" || echo $$? >&2 # macro not an expr + +T18441fail10: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":def :abc" || echo $$? >&2 # bad macro + +T18441fail11: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":def !abc" || echo $$? >&2 # bad macro + +T18441fail12: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":cmd abc" || echo $$? >&2 # cmd compilation failure + +T18441fail13: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":t" || echo $$? >&2 + +T18441fail14: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":type-at H.hs 1 1 1 1 f" || echo $$? >&2 + +T18441fail15: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":loc-at H.hs 1 1 1 1 f" || echo $$? >&2 + +T18441fail16: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":k" || echo $$? >&2 + +T18441fail17: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":run a" || echo $$? >&2 + +T18441fail18: + -'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e ":main" || echo $$? >&2 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail0.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail0.stderr new file mode 100644 index 0000000000..1918b09df9 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail0.stderr @@ -0,0 +1,3 @@ +there is no last command to perform +use :? for help. +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail1.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail1.stderr new file mode 100644 index 0000000000..10d382d050 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail1.stderr @@ -0,0 +1,3 @@ +unknown command ':abcde' +use :? for help. +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail10.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail10.stderr new file mode 100644 index 0000000000..2e71b287e3 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail10.stderr @@ -0,0 +1,2 @@ +macro name cannot start with a colon +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail11.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail11.stderr new file mode 100644 index 0000000000..298e204c62 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail11.stderr @@ -0,0 +1,2 @@ +macro name cannot start with an exclamation mark +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail12.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail12.stderr new file mode 100644 index 0000000000..38ea987f38 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail12.stderr @@ -0,0 +1,5 @@ + +<interactive>:1:1: error: + Variable not in scope: abc :: IO String + Suggested fix: Perhaps use ‘abs’ (imported from Prelude) +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail13.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail13.stderr new file mode 100644 index 0000000000..35f740c0a9 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail13.stderr @@ -0,0 +1,3 @@ + +<no location info>: error: not an expression: ‘’ +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail14.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail14.stderr new file mode 100644 index 0000000000..c1515dae77 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail14.stderr @@ -0,0 +1,2 @@ +Couldn't guess that module name. Does it exist? +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail15.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail15.stderr new file mode 100644 index 0000000000..c1515dae77 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail15.stderr @@ -0,0 +1,2 @@ +Couldn't guess that module name. Does it exist? +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail16.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail16.stderr new file mode 100644 index 0000000000..2194e5f81b --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail16.stderr @@ -0,0 +1,4 @@ + +<interactive>:1:1: error: + parse error (possibly incorrect indentation or mismatched brackets) +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail17.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail17.stderr new file mode 100644 index 0000000000..d0749cc833 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail17.stderr @@ -0,0 +1,3 @@ + +<interactive>:0:33: error: Variable not in scope: a :: IO a +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail18.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail18.stderr new file mode 100644 index 0000000000..9981715a36 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail18.stderr @@ -0,0 +1,5 @@ + +<interactive>:0:53: error: + Variable not in scope: main :: IO a0 + Suggested fix: Perhaps use ‘min’ (imported from Prelude) +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail2.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail2.stderr new file mode 100644 index 0000000000..849747f5eb --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail2.stderr @@ -0,0 +1,2 @@ +<interactive>: Some flags have not been recognized: -Xabcde +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail4.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail4.stderr new file mode 100644 index 0000000000..91e20fe8f1 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail4.stderr @@ -0,0 +1,3 @@ + +<no location info>: error: module ‘Abcde’ cannot be found locally +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail5.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail5.stderr new file mode 100644 index 0000000000..05578a2262 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail5.stderr @@ -0,0 +1,3 @@ + +<no location info>: error: no such module: ‘main:Abcde’ +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail6.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail6.stderr new file mode 100644 index 0000000000..6979f8d919 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail6.stderr @@ -0,0 +1,2 @@ +Module Abcde not found +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail7.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail7.stderr new file mode 100644 index 0000000000..aaf284760a --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail7.stderr @@ -0,0 +1,2 @@ +<interactive>: IO error: "Abcde" does not exist +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail8.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail8.stderr new file mode 100644 index 0000000000..80b40ae5f5 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail8.stderr @@ -0,0 +1,2 @@ +<interactive>: syntax: :script <filename> +1 diff --git a/testsuite/tests/ghc-e/should_fail/T18441fail9.stderr b/testsuite/tests/ghc-e/should_fail/T18441fail9.stderr new file mode 100644 index 0000000000..35f740c0a9 --- /dev/null +++ b/testsuite/tests/ghc-e/should_fail/T18441fail9.stderr @@ -0,0 +1,3 @@ + +<no location info>: error: not an expression: ‘’ +1 diff --git a/testsuite/tests/ghc-e/should_fail/T7962.stderr b/testsuite/tests/ghc-e/should_fail/T7962.stderr index b58aa89502..cf1fdb92be 100644 --- a/testsuite/tests/ghc-e/should_fail/T7962.stderr +++ b/testsuite/tests/ghc-e/should_fail/T7962.stderr @@ -1,3 +1,4 @@ <interactive>:0:9: error: parse error (possibly incorrect indentation or mismatched brackets) +1 diff --git a/testsuite/tests/ghc-e/should_fail/T9905fail1.stderr b/testsuite/tests/ghc-e/should_fail/T9905fail1.stderr index 1f0fb05138..9d0d79c23e 100644 --- a/testsuite/tests/ghc-e/should_fail/T9905fail1.stderr +++ b/testsuite/tests/ghc-e/should_fail/T9905fail1.stderr @@ -2,3 +2,4 @@ <no location info>: error: Could not find module ‘This.Module.Does.Not.Exist’ It is not a module in the current program, or in any known package. +1 diff --git a/testsuite/tests/ghc-e/should_fail/T9905fail2.stderr b/testsuite/tests/ghc-e/should_fail/T9905fail2.stderr index 9143eccae4..8be6c2aadb 100644 --- a/testsuite/tests/ghc-e/should_fail/T9905fail2.stderr +++ b/testsuite/tests/ghc-e/should_fail/T9905fail2.stderr @@ -1,3 +1,4 @@ <interactive>:0:19: error: Module ‘Data.List’ does not export ‘bogusIdentifier’ +1 diff --git a/testsuite/tests/ghc-e/should_fail/T9905fail3.stderr b/testsuite/tests/ghc-e/should_fail/T9905fail3.stderr index 85226ea2b4..de9de0b88f 100644 --- a/testsuite/tests/ghc-e/should_fail/T9905fail3.stderr +++ b/testsuite/tests/ghc-e/should_fail/T9905fail3.stderr @@ -1,2 +1,3 @@ <interactive>:0:17: error: parse error on input ‘+’ +1 diff --git a/testsuite/tests/ghc-e/should_fail/all.T b/testsuite/tests/ghc-e/should_fail/all.T index 76f9afe0a8..7196bbe969 100644 --- a/testsuite/tests/ghc-e/should_fail/all.T +++ b/testsuite/tests/ghc-e/should_fail/all.T @@ -14,3 +14,43 @@ test('ghc-e-fail2', req_interp, makefile_test, ['ghc-e-fail2']) # and no failure is induced. test('T9930fail', [extra_files(['T9930']), when(opsys('mingw32'), skip)], makefile_test, ['T9930fail']) + +test('T18441fail0', req_interp, makefile_test, ['T18441fail0']) + +test('T18441fail1', req_interp, makefile_test, ['T18441fail1']) + +test('T18441fail2', req_interp, makefile_test, ['T18441fail2']) + +test('T18441fail3', [ignore_stderr, exit_code(1)], run_command, ['{compiler} -e ":! abcde"']) + +test('T18441fail4', req_interp, makefile_test, ['T18441fail4']) + +test('T18441fail5', req_interp, makefile_test, ['T18441fail5']) + +test('T18441fail6', req_interp, makefile_test, ['T18441fail6']) + +test('T18441fail7', req_interp, makefile_test, ['T18441fail7']) + +test('T18441fail8', req_interp, makefile_test, ['T18441fail8']) + +test('T18441fail9', req_interp, makefile_test, ['T18441fail9']) + +test('T18441fail10', req_interp, makefile_test, ['T18441fail10']) + +test('T18441fail11', req_interp, makefile_test, ['T18441fail11']) + +test('T18441fail12', req_interp, makefile_test, ['T18441fail12']) + +test('T18441fail13', req_interp, makefile_test, ['T18441fail13']) + +test('T18441fail14', req_interp, makefile_test, ['T18441fail14']) + +test('T18441fail15', req_interp, makefile_test, ['T18441fail15']) + +test('T18441fail16', req_interp, makefile_test, ['T18441fail16']) + +test('T18441fail17', req_interp, makefile_test, ['T18441fail17']) + +test('T18441fail18', req_interp, makefile_test, ['T18441fail18']) + +test('T18441fail19', [ignore_stderr, exit_code(1)], run_command, ['{compiler} -e ":cd abcd"']) diff --git a/testsuite/tests/ghc-e/should_fail/ghc-e-fail1.stderr b/testsuite/tests/ghc-e/should_fail/ghc-e-fail1.stderr index cf75b40644..d1f2d18251 100644 --- a/testsuite/tests/ghc-e/should_fail/ghc-e-fail1.stderr +++ b/testsuite/tests/ghc-e/should_fail/ghc-e-fail1.stderr @@ -1,3 +1,4 @@ <interactive>:0:8: error: parse error (possibly incorrect indentation or mismatched brackets) +1 diff --git a/testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr b/testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr index bcd0565d6a..858139c117 100644 --- a/testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr +++ b/testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr @@ -2,3 +2,4 @@ <interactive>:0:1: error: Cycle in type synonym declarations: <interactive>:0:1-10: type A = A +1 diff --git a/testsuite/tests/ghci/scripts/T10508.stderr b/testsuite/tests/ghci/scripts/T10508.stderr index 8cbcb2936d..89392b3ea8 100644 --- a/testsuite/tests/ghci/scripts/T10508.stderr +++ b/testsuite/tests/ghci/scripts/T10508.stderr @@ -8,3 +8,5 @@ In the first argument of ‘return’, namely ‘id’ In the expression: return id In the second argument of ‘(.)’, namely ‘(\ _ -> return id)’ +unknown command ':macro' +use :? for help. diff --git a/testsuite/tests/ghci/scripts/T10508.stdout b/testsuite/tests/ghci/scripts/T10508.stdout index c6c8d3a447..d2a5eee71e 100644 --- a/testsuite/tests/ghci/scripts/T10508.stdout +++ b/testsuite/tests/ghci/scripts/T10508.stdout @@ -2,5 +2,3 @@ 1 2 0 -unknown command ':macro' -use :? for help. diff --git a/testsuite/tests/ghci/scripts/T14676.stderr b/testsuite/tests/ghci/scripts/T14676.stderr new file mode 100644 index 0000000000..c99d0900d5 --- /dev/null +++ b/testsuite/tests/ghci/scripts/T14676.stderr @@ -0,0 +1,2 @@ +File Notfound.hs not found +Module NotFound not found diff --git a/testsuite/tests/ghci/scripts/T14676.stdout b/testsuite/tests/ghci/scripts/T14676.stdout index c3e9fbd6b4..9c1e707676 100644 --- a/testsuite/tests/ghci/scripts/T14676.stdout +++ b/testsuite/tests/ghci/scripts/T14676.stdout @@ -1,3 +1 @@ -File Notfound.hs not found -Module NotFound not found prog002/A1.hs |