summaryrefslogtreecommitdiff
path: root/compiler/GHC
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC')
-rw-r--r--compiler/GHC/Cmm/Lexer.x8
-rw-r--r--compiler/GHC/Cmm/Parser.y26
-rw-r--r--compiler/GHC/Cmm/Parser/Monad.hs5
-rw-r--r--compiler/GHC/Driver/Backpack.hs3
-rw-r--r--compiler/GHC/Driver/Config.hs2
-rw-r--r--compiler/GHC/Driver/Errors.hs8
-rw-r--r--compiler/GHC/Driver/Errors/Ppr.hs10
-rw-r--r--compiler/GHC/Driver/Errors/Types.hs12
-rw-r--r--compiler/GHC/Driver/Main.hs38
-rw-r--r--compiler/GHC/Driver/Make.hs2
-rw-r--r--compiler/GHC/Driver/Pipeline.hs3
-rw-r--r--compiler/GHC/Parser.y30
-rw-r--r--compiler/GHC/Parser/Errors.hs421
-rw-r--r--compiler/GHC/Parser/Errors/Ppr.hs1210
-rw-r--r--compiler/GHC/Parser/Errors/Types.hs499
-rw-r--r--compiler/GHC/Parser/Header.hs9
-rw-r--r--compiler/GHC/Parser/Lexer.x165
-rw-r--r--compiler/GHC/Parser/PostProcess.hs285
-rw-r--r--compiler/GHC/Parser/PostProcess/Haddock.hs7
-rw-r--r--compiler/GHC/Types/Hint.hs38
20 files changed, 1524 insertions, 1257 deletions
diff --git a/compiler/GHC/Cmm/Lexer.x b/compiler/GHC/Cmm/Lexer.x
index 85b06ea624..bf379ec7da 100644
--- a/compiler/GHC/Cmm/Lexer.x
+++ b/compiler/GHC/Cmm/Lexer.x
@@ -26,7 +26,9 @@ import GHC.Types.Unique.FM
import GHC.Data.StringBuffer
import GHC.Data.FastString
import GHC.Parser.CharClass
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
+import GHC.Parser.Errors.Ppr ()
+import GHC.Utils.Error
import GHC.Utils.Misc
--import TRACE
@@ -326,7 +328,9 @@ lexToken = do
AlexEOF -> do let span = mkPsSpan loc1 loc1
liftP (setLastToken span 0)
return (L span CmmT_EOF)
- AlexError (loc2,_) -> liftP $ failLocMsgP (psRealLoc loc1) (psRealLoc loc2) (PsError PsErrCmmLexer [])
+ AlexError (loc2,_) ->
+ let msg srcLoc = mkPlainErrorMsgEnvelope srcLoc PsErrCmmLexer
+ in liftP $ failLocMsgP (psRealLoc loc1) (psRealLoc loc2) msg
AlexSkip inp2 _ -> do
setInput inp2
lexToken
diff --git a/compiler/GHC/Cmm/Parser.y b/compiler/GHC/Cmm/Parser.y
index a83feff8cf..d182a6f714 100644
--- a/compiler/GHC/Cmm/Parser.y
+++ b/compiler/GHC/Cmm/Parser.y
@@ -239,7 +239,8 @@ import qualified GHC.Cmm.Parser.Monad as PD
import GHC.Cmm.CallConv
import GHC.Runtime.Heap.Layout
import GHC.Parser.Lexer
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
+import GHC.Parser.Errors.Ppr
import GHC.Types.CostCentre
import GHC.Types.ForeignCall
@@ -918,7 +919,7 @@ getLit _ = panic "invalid literal" -- TODO messy failure
nameToMachOp :: FastString -> PD (Width -> MachOp)
nameToMachOp name =
case lookupUFM machOps name of
- Nothing -> failMsgPD $ PsError (PsErrCmmParser (CmmUnknownPrimitive name)) []
+ Nothing -> failMsgPD $ \span -> mkPlainErrorMsgEnvelope span $ PsErrCmmParser (CmmUnknownPrimitive name)
Just m -> return m
exprOp :: FastString -> [CmmParse CmmExpr] -> PD (CmmParse CmmExpr)
@@ -1083,12 +1084,14 @@ parseSafety :: String -> PD Safety
parseSafety "safe" = return PlaySafe
parseSafety "unsafe" = return PlayRisky
parseSafety "interruptible" = return PlayInterruptible
-parseSafety str = failMsgPD $ PsError (PsErrCmmParser (CmmUnrecognisedSafety str)) []
+parseSafety str = failMsgPD $ \span -> mkPlainErrorMsgEnvelope span $
+ PsErrCmmParser (CmmUnrecognisedSafety str)
parseCmmHint :: String -> PD ForeignHint
parseCmmHint "ptr" = return AddrHint
parseCmmHint "signed" = return SignedHint
-parseCmmHint str = failMsgPD $ PsError (PsErrCmmParser (CmmUnrecognisedHint str)) []
+parseCmmHint str = failMsgPD $ \span -> mkPlainErrorMsgEnvelope span $
+ PsErrCmmParser (CmmUnrecognisedHint str)
-- labels are always pointers, so we might as well infer the hint
inferCmmHint :: CmmExpr -> ForeignHint
@@ -1115,7 +1118,7 @@ happyError = PD $ \_ _ s -> unP srcParseFail s
stmtMacro :: FastString -> [CmmParse CmmExpr] -> PD (CmmParse ())
stmtMacro fun args_code = do
case lookupUFM stmtMacros fun of
- Nothing -> failMsgPD $ PsError (PsErrCmmParser (CmmUnknownMacro fun)) []
+ Nothing -> failMsgPD $ \span -> mkPlainErrorMsgEnvelope span $ PsErrCmmParser (CmmUnknownMacro fun)
Just fcode -> return $ do
args <- sequence args_code
code (fcode args)
@@ -1218,7 +1221,8 @@ foreignCall conv_string results_code expr_code args_code safety ret
= do conv <- case conv_string of
"C" -> return CCallConv
"stdcall" -> return StdCallConv
- _ -> failMsgPD $ PsError (PsErrCmmParser (CmmUnknownCConv conv_string)) []
+ _ -> failMsgPD $ \span -> mkPlainErrorMsgEnvelope span $
+ PsErrCmmParser (CmmUnknownCConv conv_string)
return $ do
platform <- getPlatform
results <- sequence results_code
@@ -1296,7 +1300,7 @@ primCall results_code name args_code
= do
platform <- PD.getPlatform
case lookupUFM (callishMachOps platform) name of
- Nothing -> failMsgPD $ PsError (PsErrCmmParser (CmmUnknownPrimitive name)) []
+ Nothing -> failMsgPD $ \span -> mkPlainErrorMsgEnvelope span $ PsErrCmmParser (CmmUnknownPrimitive name)
Just f -> return $ do
results <- sequence results_code
args <- sequence args_code
@@ -1451,7 +1455,11 @@ initEnv profile = listToUFM [
where platform = profilePlatform profile
-parseCmmFile :: DynFlags -> Module -> HomeUnit -> FilePath -> IO (Bag PsWarning, Bag PsError, Maybe (CmmGroup, [InfoProvEnt]))
+parseCmmFile :: DynFlags
+ -> Module
+ -> HomeUnit
+ -> FilePath
+ -> IO (Messages PsMessage, Messages PsMessage, Maybe (CmmGroup, [InfoProvEnt]))
parseCmmFile dflags this_mod home_unit filename = do
buf <- hGetStringBuffer filename
let
@@ -1474,7 +1482,7 @@ parseCmmFile dflags this_mod home_unit filename = do
return (cmm ++ cmm2, used_info)
(cmm, _) = runC dflags no_module st fcode
(warnings,errors) = getMessages pst
- if not (isEmptyBag errors)
+ if not (isEmptyMessages errors)
then return (warnings, errors, Nothing)
else return (warnings, errors, Just cmm)
where
diff --git a/compiler/GHC/Cmm/Parser/Monad.hs b/compiler/GHC/Cmm/Parser/Monad.hs
index 77124ad1b2..4a72780c2f 100644
--- a/compiler/GHC/Cmm/Parser/Monad.hs
+++ b/compiler/GHC/Cmm/Parser/Monad.hs
@@ -27,7 +27,8 @@ import Control.Monad
import GHC.Driver.Session
import GHC.Parser.Lexer
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
+import GHC.Types.Error ( MsgEnvelope )
import GHC.Types.SrcLoc
import GHC.Unit.Types
import GHC.Unit.Home
@@ -47,7 +48,7 @@ instance Monad PD where
liftP :: P a -> PD a
liftP (P f) = PD $ \_ _ s -> f s
-failMsgPD :: (SrcSpan -> PsError) -> PD a
+failMsgPD :: (SrcSpan -> MsgEnvelope PsMessage) -> PD a
failMsgPD = liftP . failMsgP
returnPD :: a -> PD a
diff --git a/compiler/GHC/Driver/Backpack.hs b/compiler/GHC/Driver/Backpack.hs
index 3d8048e825..dceed41099 100644
--- a/compiler/GHC/Driver/Backpack.hs
+++ b/compiler/GHC/Driver/Backpack.hs
@@ -35,7 +35,6 @@ import GHC.Parser
import GHC.Parser.Header
import GHC.Parser.Lexer
import GHC.Parser.Annotation
-import GHC.Parser.Errors.Ppr
import GHC hiding (Failed, Succeeded)
import GHC.Tc.Utils.Monad
@@ -106,7 +105,7 @@ doBackpack [src_filename] = do
buf <- liftIO $ hGetStringBuffer src_filename
let loc = mkRealSrcLoc (mkFastString src_filename) 1 1 -- TODO: not great
case unP parseBackpack (initParserState (initParserOpts dflags) buf loc) of
- PFailed pst -> throwErrors (foldPsMessages mkParserErr (getErrorMessages pst))
+ PFailed pst -> throwErrors (GhcPsMessage <$> getErrorMessages pst)
POk _ pkgname_bkp -> do
-- OK, so we have an LHsUnit PackageName, but we want an
-- LHsUnit HsComponentId. So let's rename it.
diff --git a/compiler/GHC/Driver/Config.hs b/compiler/GHC/Driver/Config.hs
index cd3b165a65..7a96271403 100644
--- a/compiler/GHC/Driver/Config.hs
+++ b/compiler/GHC/Driver/Config.hs
@@ -15,6 +15,7 @@ import GHC.Core.SimpleOpt
import GHC.Core.Coercion.Opt
import GHC.Parser.Lexer
import GHC.Runtime.Interpreter (BCOOpts(..))
+import GHC.Utils.Error (mkPlainMsgEnvelope)
import GHCi.Message (EvalOpts(..))
import GHC.Conc (getNumProcessors)
@@ -39,6 +40,7 @@ initParserOpts =
mkParserOpts
<$> warningFlags
<*> extensionFlags
+ <*> mkPlainMsgEnvelope
<*> safeImportsOn
<*> gopt Opt_Haddock
<*> gopt Opt_KeepRawTokenStream
diff --git a/compiler/GHC/Driver/Errors.hs b/compiler/GHC/Driver/Errors.hs
index f980502f5d..777761f201 100644
--- a/compiler/GHC/Driver/Errors.hs
+++ b/compiler/GHC/Driver/Errors.hs
@@ -9,7 +9,7 @@ import GHC.Driver.Session
import GHC.Driver.Errors.Types
import GHC.Data.Bag
import GHC.Prelude
-import GHC.Parser.Errors ( PsError(..) )
+import GHC.Parser.Errors.Types
import GHC.Types.SrcLoc
import GHC.Types.SourceError
import GHC.Types.Error
@@ -64,7 +64,5 @@ printOrThrowDiagnostics logger dflags msgs
-- for dealing with parse errors when the driver is doing dependency analysis.
-- Defined here to avoid module loops between GHC.Driver.Error.Types and
-- GHC.Driver.Error.Ppr
-mkDriverPsHeaderMessage :: PsError -> MsgEnvelope DriverMessage
-mkDriverPsHeaderMessage ps_err
- = mkPlainErrorMsgEnvelope (errLoc ps_err) $
- DriverPsHeaderMessage (errDesc ps_err) (errHints ps_err)
+mkDriverPsHeaderMessage :: MsgEnvelope PsMessage -> MsgEnvelope DriverMessage
+mkDriverPsHeaderMessage = fmap DriverPsHeaderMessage
diff --git a/compiler/GHC/Driver/Errors/Ppr.hs b/compiler/GHC/Driver/Errors/Ppr.hs
index 853d83b76b..b8553c0533 100644
--- a/compiler/GHC/Driver/Errors/Ppr.hs
+++ b/compiler/GHC/Driver/Errors/Ppr.hs
@@ -10,7 +10,7 @@ import GHC.Driver.Errors.Types
import GHC.Driver.Flags
import GHC.Driver.Session
import GHC.HsToCore.Errors.Ppr ()
-import GHC.Parser.Errors.Ppr (pprPsError)
+import GHC.Parser.Errors.Ppr ()
import GHC.Tc.Errors.Ppr ()
import GHC.Types.Error
import GHC.Unit.Types
@@ -69,8 +69,8 @@ instance Diagnostic DriverMessage where
diagnosticMessage = \case
DriverUnknownMessage m
-> diagnosticMessage m
- DriverPsHeaderMessage desc hints
- -> mkSimpleDecorated $ pprPsError desc hints
+ DriverPsHeaderMessage m
+ -> diagnosticMessage m
DriverMissingHomeModules missing buildingCabalPackage
-> let msg | buildingCabalPackage == YesBuildingCabalPackage
= hang
@@ -151,8 +151,8 @@ instance Diagnostic DriverMessage where
diagnosticHints = \case
DriverUnknownMessage m
-> diagnosticHints m
- DriverPsHeaderMessage _desc hints
- -> hints
+ DriverPsHeaderMessage psMsg
+ -> diagnosticHints psMsg
DriverMissingHomeModules{}
-> noHints
DriverUnusedPackages{}
diff --git a/compiler/GHC/Driver/Errors/Types.hs b/compiler/GHC/Driver/Errors/Types.hs
index 2519d5597c..142b3b2be9 100644
--- a/compiler/GHC/Driver/Errors/Types.hs
+++ b/compiler/GHC/Driver/Errors/Types.hs
@@ -12,7 +12,6 @@ module GHC.Driver.Errors.Types (
-- * Utility functions
, hoistTcRnMessage
, hoistDsMessage
- , foldPsMessages
, checkBuildingCabalPackage
) where
@@ -25,7 +24,6 @@ import GHC.Driver.Session
import GHC.Types.Error
import GHC.Unit.Module
-import GHC.Parser.Errors ( PsErrorDesc )
import GHC.Parser.Errors.Types ( PsMessage )
import GHC.Tc.Errors.Types ( TcRnMessage )
import GHC.HsToCore.Errors.Types ( DsMessage )
@@ -92,14 +90,6 @@ data GhcMessage where
ghcUnknownMessage :: (Diagnostic a, Typeable a) => a -> GhcMessage
ghcUnknownMessage = GhcUnknownMessage
--- | Given a collection of @e@ wrapped in a 'Foldable' structure, converts it
--- into 'Messages' via the supplied transformation function.
-foldPsMessages :: Foldable f
- => (e -> MsgEnvelope PsMessage)
- -> f e
- -> Messages GhcMessage
-foldPsMessages f = foldMap (singleMessage . fmap GhcPsMessage . f)
-
-- | Abstracts away the frequent pattern where we are calling 'ioMsgMaybe' on
-- the result of 'IO (Messages TcRnMessage, a)'.
hoistTcRnMessage :: Monad m => m (Messages TcRnMessage, a) -> m (Messages GhcMessage, a)
@@ -119,7 +109,7 @@ data DriverMessage where
DriverUnknownMessage :: (Diagnostic a, Typeable a) => a -> DriverMessage
-- | A parse error in parsing a Haskell file header during dependency
-- analysis
- DriverPsHeaderMessage :: !PsErrorDesc -> ![GhcHint] -> DriverMessage
+ DriverPsHeaderMessage :: !PsMessage -> DriverMessage
{-| DriverMissingHomeModules is a warning (controlled with -Wmissing-home-modules) that
arises when running GHC in --make mode when some modules needed for compilation
diff --git a/compiler/GHC/Driver/Main.hs b/compiler/GHC/Driver/Main.hs
index f0204246b6..e97fb5a4c6 100644
--- a/compiler/GHC/Driver/Main.hs
+++ b/compiler/GHC/Driver/Main.hs
@@ -145,8 +145,6 @@ import GHC.Core.FamInstEnv
import GHC.CoreToStg.Prep
import GHC.CoreToStg ( coreToStg )
-import GHC.Parser.Errors
-import GHC.Parser.Errors.Ppr
import GHC.Parser.Errors.Types
import GHC.Parser
import GHC.Parser.Lexer as Lexer
@@ -233,7 +231,7 @@ import qualified Data.Set as S
import Data.Set (Set)
import Data.Functor
import Control.DeepSeq (force)
-import Data.Bifunctor (first, bimap)
+import Data.Bifunctor (first)
{- **********************************************************************
%* *
@@ -288,26 +286,21 @@ handleWarnings = do
-- | log warning in the monad, and if there are errors then
-- throw a SourceError exception.
-logWarningsReportErrors :: (Bag PsWarning, Bag PsError) -> Hsc ()
+logWarningsReportErrors :: (Messages PsWarning, Messages PsError) -> Hsc ()
logWarningsReportErrors (warnings,errors) = do
- dflags <- getDynFlags
- let warns = foldPsMessages (mkParserWarn dflags) warnings
- errs = foldPsMessages mkParserErr errors
- logDiagnostics warns
- when (not $ isEmptyMessages errs) $ throwErrors errs
+ logDiagnostics (GhcPsMessage <$> warnings)
+ when (not $ isEmptyMessages errors) $ throwErrors (GhcPsMessage <$> errors)
-- | Log warnings and throw errors, assuming the messages
-- contain at least one error (e.g. coming from PFailed)
-handleWarningsThrowErrors :: (Bag PsWarning, Bag PsError) -> Hsc a
+handleWarningsThrowErrors :: (Messages PsWarning, Messages PsError) -> Hsc a
handleWarningsThrowErrors (warnings, errors) = do
dflags <- getDynFlags
- let warns = foldPsMessages (mkParserWarn dflags) warnings
- errs = foldPsMessages mkParserErr errors
- logDiagnostics warns
+ logDiagnostics (GhcPsMessage <$> warnings)
logger <- getLogger
- let (wWarns, wErrs) = partitionMessages warns
+ let (wWarns, wErrs) = partitionMessages warnings
liftIO $ printMessages logger dflags wWarns
- throwErrors $ errs `unionMessages` wErrs
+ throwErrors $ fmap GhcPsMessage $ errors `unionMessages` wErrs
-- | Deal with errors and warnings returned by a compilation step
--
@@ -418,11 +411,8 @@ hscParse' mod_summary
PFailed pst ->
handleWarningsThrowErrors (getMessages pst)
POk pst rdr_module -> do
- let (warns, errs) =
- bimap (foldPsMessages (mkParserWarn dflags))
- (foldPsMessages mkParserErr)
- (getMessages pst)
- logDiagnostics warns
+ let (warns, errs) = getMessages pst
+ logDiagnostics (GhcPsMessage <$> warns)
liftIO $ dumpIfSet_dyn logger dflags Opt_D_dump_parsed "Parser"
FormatHaskell (ppr rdr_module)
liftIO $ dumpIfSet_dyn logger dflags Opt_D_dump_parsed_ast "Parser AST"
@@ -431,7 +421,7 @@ hscParse' mod_summary
rdr_module)
liftIO $ dumpIfSet_dyn logger dflags Opt_D_source_stats "Source Statistics"
FormatText (ppSourceStats False rdr_module)
- when (not $ isEmptyMessages errs) $ throwErrors errs
+ when (not $ isEmptyMessages errs) $ throwErrors (GhcPsMessage <$> errs)
-- To get the list of extra source files, we take the list
-- that the parser gave us,
@@ -1618,10 +1608,8 @@ hscCompileCmmFile hsc_env filename output_filename = runHsc hsc_env $ do
$ do
(warns,errs,cmm) <- withTiming logger dflags (text "ParseCmm"<+>brackets (text filename)) (\_ -> ())
$ parseCmmFile dflags cmm_mod home_unit filename
- let msgs = foldPsMessages (mkParserWarn dflags) warns
- `unionMessages`
- foldPsMessages mkParserErr errs
- return (msgs, cmm)
+ let msgs = warns `unionMessages` errs
+ return (GhcPsMessage <$> msgs, cmm)
liftIO $ do
dumpIfSet_dyn logger dflags Opt_D_dump_cmm_verbose_by_proc "Parsed Cmm" FormatCMM (pdoc platform cmm)
diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs
index 855675aa67..03803ecaf8 100644
--- a/compiler/GHC/Driver/Make.hs
+++ b/compiler/GHC/Driver/Make.hs
@@ -2818,7 +2818,7 @@ getPreprocessedImports hsc_env src_fn mb_phase maybe_buf = do
let imp_prelude = xopt LangExt.ImplicitPrelude pi_local_dflags
popts = initParserOpts pi_local_dflags
mimps <- getImports popts imp_prelude pi_hspp_buf pi_hspp_fn src_fn
- return (first (mkMessages . fmap mkDriverPsHeaderMessage) mimps)
+ return (first (mkMessages . fmap mkDriverPsHeaderMessage . getMessages) mimps)
return PreprocessedImports {..}
diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs
index f8ad427dc2..54221c4847 100644
--- a/compiler/GHC/Driver/Pipeline.hs
+++ b/compiler/GHC/Driver/Pipeline.hs
@@ -59,7 +59,6 @@ import GHC.Platform.Ways
import GHC.Platform.ArchOS
import GHC.Parser.Header
-import GHC.Parser.Errors.Ppr
import GHC.SysTools
import GHC.Utils.TmpFs
@@ -1248,7 +1247,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn
popts = initParserOpts dflags
eimps <- getImports popts imp_prelude buf input_fn (basename <.> suff)
case eimps of
- Left errs -> throwErrors (foldPsMessages mkParserErr errs)
+ Left errs -> throwErrors (GhcPsMessage <$> errs)
Right (src_imps,imps,L _ mod_name) -> return
(Just buf, mod_name, imps, src_imps)
diff --git a/compiler/GHC/Parser.y b/compiler/GHC/Parser.y
index c89079ca70..363493482a 100644
--- a/compiler/GHC/Parser.y
+++ b/compiler/GHC/Parser.y
@@ -61,6 +61,7 @@ import GHC.Data.FastString
import GHC.Data.Maybe ( orElse )
import GHC.Utils.Outputable
+import GHC.Utils.Error
import GHC.Utils.Misc ( looksLikePackageName, fstOf3, sndOf3, thdOf3 )
import GHC.Utils.Panic
import GHC.Prelude
@@ -84,7 +85,8 @@ import GHC.Parser.PostProcess
import GHC.Parser.PostProcess.Haddock
import GHC.Parser.Lexer
import GHC.Parser.Annotation
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
+import GHC.Parser.Errors.Ppr ()
import GHC.Builtin.Types ( unitTyCon, unitDataCon, tupleTyCon, tupleDataCon, nilDataCon,
unboxedUnitTyCon, unboxedUnitDataCon,
@@ -809,7 +811,7 @@ HYPHEN :: { [AddEpAnn] }
| PREFIX_MINUS { [mj AnnMinus $1 ] }
| VARSYM {% if (getVARSYM $1 == fsLit "-")
then return [mj AnnMinus $1]
- else do { addError $ PsError PsErrExpectedHyphen [] (getLoc $1)
+ else do { addError $ mkPlainErrorMsgEnvelope (getLoc $1) $ PsErrExpectedHyphen
; return [] } }
@@ -1126,7 +1128,8 @@ maybe_safe :: { (Maybe EpaLocation,Bool) }
maybe_pkg :: { (Maybe EpaLocation,Maybe StringLiteral) }
: STRING {% do { let { pkgFS = getSTRING $1 }
; unless (looksLikePackageName (unpackFS pkgFS)) $
- addError $ PsError (PsErrInvalidPackageName pkgFS) [] (getLoc $1)
+ addError $ mkPlainErrorMsgEnvelope (getLoc $1) $
+ (PsErrInvalidPackageName pkgFS)
; return (Just (glAA $1), Just (StringLiteral (getSTRINGs $1) pkgFS Nothing)) } }
| {- empty -} { (Nothing,Nothing) }
@@ -1855,7 +1858,8 @@ rule_activation_marker :: { [AddEpAnn] }
: PREFIX_TILDE { [mj AnnTilde $1] }
| VARSYM {% if (getVARSYM $1 == fsLit "~")
then return [mj AnnTilde $1]
- else do { addError $ PsError PsErrInvalidRuleActivationMarker [] (getLoc $1)
+ else do { addError $ mkPlainErrorMsgEnvelope (getLoc $1) $
+ PsErrInvalidRuleActivationMarker
; return [] } }
rule_explicit_activation :: { ([AddEpAnn]
@@ -3275,8 +3279,8 @@ pat :: { LPat GhcPs }
pat : exp {% (checkPattern <=< runPV) (unECP $1) }
bindpat :: { LPat GhcPs }
-bindpat : exp {% -- See Note [Parser-Validator Hint] in GHC.Parser.PostProcess
- checkPattern_hints [SuggestMissingDo]
+bindpat : exp {% -- See Note [Parser-Validator Details] in GHC.Parser.PostProcess
+ checkPattern_details incompleteDoBlock
(unECP $1) }
apat :: { LPat GhcPs }
@@ -3944,7 +3948,7 @@ getSCC :: Located Token -> P FastString
getSCC lt = do let s = getSTRING lt
-- We probably actually want to be more restrictive than this
if ' ' `elem` unpackFS s
- then addFatalError $ PsError PsErrSpaceInSCC [] (getLoc lt)
+ then addFatalError $ mkPlainErrorMsgEnvelope (getLoc lt) $ PsErrSpaceInSCC
else return s
-- Utilities for combining source spans
@@ -4085,7 +4089,7 @@ fileSrcSpan = do
hintLinear :: MonadP m => SrcSpan -> m ()
hintLinear span = do
linearEnabled <- getBit LinearTypesBit
- unless linearEnabled $ addError $ PsError PsErrLinearFunction [] span
+ unless linearEnabled $ addError $ mkPlainErrorMsgEnvelope span $ PsErrLinearFunction
-- Does this look like (a %m)?
looksLikeMult :: LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> Bool
@@ -4104,14 +4108,15 @@ looksLikeMult ty1 l_op ty2
hintMultiWayIf :: SrcSpan -> P ()
hintMultiWayIf span = do
mwiEnabled <- getBit MultiWayIfBit
- unless mwiEnabled $ addError $ PsError PsErrMultiWayIf [] span
+ unless mwiEnabled $ addError $ mkPlainErrorMsgEnvelope span PsErrMultiWayIf
-- Hint about explicit-forall
hintExplicitForall :: Located Token -> P ()
hintExplicitForall tok = do
forall <- getBit ExplicitForallBit
rulePrag <- getBit InRulePragBit
- unless (forall || rulePrag) $ addError $ PsError (PsErrExplicitForall (isUnicode tok)) [] (getLoc tok)
+ unless (forall || rulePrag) $ addError $ mkPlainErrorMsgEnvelope (getLoc tok) $
+ (PsErrExplicitForall (isUnicode tok))
-- Hint about qualified-do
hintQualifiedDo :: Located Token -> P ()
@@ -4119,7 +4124,8 @@ hintQualifiedDo tok = do
qualifiedDo <- getBit QualifiedDoBit
case maybeQDoDoc of
Just qdoDoc | not qualifiedDo ->
- addError $ PsError (PsErrIllegalQualifiedDo qdoDoc) [] (getLoc tok)
+ addError $ mkPlainErrorMsgEnvelope (getLoc tok) $
+ (PsErrIllegalQualifiedDo qdoDoc)
_ -> return ()
where
maybeQDoDoc = case unLoc tok of
@@ -4133,7 +4139,7 @@ hintQualifiedDo tok = do
reportEmptyDoubleQuotes :: SrcSpan -> P a
reportEmptyDoubleQuotes span = do
thQuotes <- getBit ThQuotesBit
- addFatalError $ PsError (PsErrEmptyDoubleQuotes thQuotes) [] span
+ addFatalError $ mkPlainErrorMsgEnvelope span $ PsErrEmptyDoubleQuotes thQuotes
{-
%************************************************************************
diff --git a/compiler/GHC/Parser/Errors.hs b/compiler/GHC/Parser/Errors.hs
deleted file mode 100644
index 7a9c154ed8..0000000000
--- a/compiler/GHC/Parser/Errors.hs
+++ /dev/null
@@ -1,421 +0,0 @@
-module GHC.Parser.Errors
- ( PsWarning(..)
- , TransLayoutReason(..)
- , OperatorWhitespaceSymbol(..)
- , OperatorWhitespaceOccurrence(..)
- , NumUnderscoreReason(..)
- , PsError(..)
- , PsErrorDesc(..)
- , LexErr(..)
- , CmmParserError(..)
- , LexErrKind(..)
- , StarIsType (..)
- )
-where
-
-import GHC.Prelude
-import GHC.Types.Error
-import GHC.Types.SrcLoc
-import GHC.Types.Name.Reader (RdrName)
-import GHC.Types.Name.Occurrence (OccName)
-import GHC.Parser.Types
-import Language.Haskell.Syntax.Extension
-import GHC.Hs.Extension
-import GHC.Hs.Expr
-import GHC.Hs.Pat
-import GHC.Hs.Type
-import GHC.Hs.Lit
-import GHC.Hs.Decls
-import GHC.Core.Coercion.Axiom (Role)
-import GHC.Data.FastString
-import GHC.Unit.Module.Name
-
--- | A warning that might arise during parsing.
-data PsWarning
-
- -- | Warn when tabulations are found
- = PsWarnTab
- { tabFirst :: !SrcSpan -- ^ First occurrence of a tab
- , tabCount :: !Word -- ^ Number of other occurrences
- }
-
- | PsWarnTransitionalLayout !SrcSpan !TransLayoutReason
- -- ^ Transitional layout warnings
-
- | PsWarnUnrecognisedPragma !SrcSpan
- -- ^ Unrecognised pragma
-
- | PsWarnHaddockInvalidPos !SrcSpan
- -- ^ Invalid Haddock comment position
-
- | PsWarnHaddockIgnoreMulti !SrcSpan
- -- ^ Multiple Haddock comment for the same entity
-
- | PsWarnStarBinder !SrcSpan
- -- ^ Found binding occurrence of "*" while StarIsType is enabled
-
- | PsWarnStarIsType !SrcSpan
- -- ^ Using "*" for "Type" without StarIsType enabled
-
- | PsWarnImportPreQualified !SrcSpan
- -- ^ Pre qualified import with 'WarnPrepositiveQualifiedModule' enabled
-
- | PsWarnOperatorWhitespaceExtConflict !SrcSpan !OperatorWhitespaceSymbol
- | PsWarnOperatorWhitespace !SrcSpan !FastString !OperatorWhitespaceOccurrence
-
--- | The operator symbol in the 'WarnOperatorWhitespaceExtConflict' warning.
-data OperatorWhitespaceSymbol
- = OperatorWhitespaceSymbol_PrefixPercent
- | OperatorWhitespaceSymbol_PrefixDollar
- | OperatorWhitespaceSymbol_PrefixDollarDollar
-
--- | The operator occurrence type in the 'WarnOperatorWhitespace' warning.
-data OperatorWhitespaceOccurrence
- = OperatorWhitespaceOccurrence_Prefix
- | OperatorWhitespaceOccurrence_Suffix
- | OperatorWhitespaceOccurrence_TightInfix
-
-data TransLayoutReason
- = TransLayout_Where -- ^ "`where' clause at the same depth as implicit layout block"
- | TransLayout_Pipe -- ^ "`|' at the same depth as implicit layout block")
-
-data PsError = PsError
- { errDesc :: !PsErrorDesc -- ^ Error description
- , errHints :: ![GhcHint] -- ^ Hints
- , errLoc :: !SrcSpan -- ^ Error position
- }
-
-data PsErrorDesc
- = PsErrLambdaCase
- -- ^ LambdaCase syntax used without the extension enabled
-
- | PsErrEmptyLambda
- -- ^ A lambda requires at least one parameter
-
- | PsErrNumUnderscores !NumUnderscoreReason
- -- ^ Underscores in literals without the extension enabled
-
- | PsErrPrimStringInvalidChar
- -- ^ Invalid character in primitive string
-
- | PsErrMissingBlock
- -- ^ Missing block
-
- | PsErrLexer !LexErr !LexErrKind
- -- ^ Lexer error
-
- | PsErrSuffixAT
- -- ^ Suffix occurrence of `@`
-
- | PsErrParse !String
- -- ^ Parse errors
-
- | PsErrCmmLexer
- -- ^ Cmm lexer error
-
- | PsErrUnsupportedBoxedSumExpr !(SumOrTuple (HsExpr GhcPs))
- -- ^ Unsupported boxed sum in expression
-
- | PsErrUnsupportedBoxedSumPat !(SumOrTuple (PatBuilder GhcPs))
- -- ^ Unsupported boxed sum in pattern
-
- | PsErrUnexpectedQualifiedConstructor !RdrName
- -- ^ Unexpected qualified constructor
-
- | PsErrTupleSectionInPat
- -- ^ Tuple section in pattern context
-
- | PsErrIllegalBangPattern !(Pat GhcPs)
- -- ^ Bang-pattern without BangPattterns enabled
-
- | PsErrOpFewArgs !StarIsType !RdrName
- -- ^ Operator applied to too few arguments
-
- | PsErrImportQualifiedTwice
- -- ^ Import: multiple occurrences of 'qualified'
-
- | PsErrImportPostQualified
- -- ^ Post qualified import without 'ImportQualifiedPost'
-
- | PsErrIllegalExplicitNamespace
- -- ^ Explicit namespace keyword without 'ExplicitNamespaces'
-
- | PsErrVarForTyCon !RdrName
- -- ^ Expecting a type constructor but found a variable
-
- | PsErrIllegalPatSynExport
- -- ^ Illegal export form allowed by PatternSynonyms
-
- | PsErrMalformedEntityString
- -- ^ Malformed entity string
-
- | PsErrDotsInRecordUpdate
- -- ^ Dots used in record update
-
- | PsErrPrecedenceOutOfRange !Int
- -- ^ Precedence out of range
-
- | PsErrOverloadedRecordDotInvalid
- -- ^ Invalid use of record dot syntax `.'
-
- | PsErrOverloadedRecordUpdateNotEnabled
- -- ^ `OverloadedRecordUpdate` is not enabled.
-
- | PsErrOverloadedRecordUpdateNoQualifiedFields
- -- ^ Can't use qualified fields when OverloadedRecordUpdate is enabled.
-
- | PsErrInvalidDataCon !(HsType GhcPs)
- -- ^ Cannot parse data constructor in a data/newtype declaration
-
- | PsErrInvalidInfixDataCon !(HsType GhcPs) !RdrName !(HsType GhcPs)
- -- ^ Cannot parse data constructor in a data/newtype declaration
-
- | PsErrUnpackDataCon
- -- ^ UNPACK applied to a data constructor
-
- | PsErrUnexpectedKindAppInDataCon !DataConBuilder !(HsType GhcPs)
- -- ^ Unexpected kind application in data/newtype declaration
-
- | PsErrInvalidRecordCon !(PatBuilder GhcPs)
- -- ^ Not a record constructor
-
- | PsErrIllegalUnboxedStringInPat !(HsLit GhcPs)
- -- ^ Illegal unboxed string literal in pattern
-
- | PsErrDoNotationInPat
- -- ^ Do-notation in pattern
-
- | PsErrIfTheElseInPat
- -- ^ If-then-else syntax in pattern
-
- | PsErrLambdaCaseInPat
- -- ^ Lambda-case in pattern
-
- | PsErrCaseInPat
- -- ^ case..of in pattern
-
- | PsErrLetInPat
- -- ^ let-syntax in pattern
-
- | PsErrLambdaInPat
- -- ^ Lambda-syntax in pattern
-
- | PsErrArrowExprInPat !(HsExpr GhcPs)
- -- ^ Arrow expression-syntax in pattern
-
- | PsErrArrowCmdInPat !(HsCmd GhcPs)
- -- ^ Arrow command-syntax in pattern
-
- | PsErrArrowCmdInExpr !(HsCmd GhcPs)
- -- ^ Arrow command-syntax in expression
-
- | PsErrViewPatInExpr !(LHsExpr GhcPs) !(LHsExpr GhcPs)
- -- ^ View-pattern in expression
-
- | PsErrTypeAppWithoutSpace !RdrName !(LHsExpr GhcPs)
- -- ^ Type-application without space before '@'
-
- | PsErrLazyPatWithoutSpace !(LHsExpr GhcPs)
- -- ^ Lazy-pattern ('~') without space after it
-
- | PsErrBangPatWithoutSpace !(LHsExpr GhcPs)
- -- ^ Bang-pattern ('!') without space after it
-
- | PsErrUnallowedPragma !(HsPragE GhcPs)
- -- ^ Pragma not allowed in this position
-
- | PsErrQualifiedDoInCmd !ModuleName
- -- ^ Qualified do block in command
-
- | PsErrInvalidInfixHole
- -- ^ Invalid infix hole, expected an infix operator
-
- | PsErrSemiColonsInCondExpr
- -- ^ Unexpected semi-colons in conditional expression
- !(HsExpr GhcPs) -- ^ conditional expr
- !Bool -- ^ "then" semi-colon?
- !(HsExpr GhcPs) -- ^ "then" expr
- !Bool -- ^ "else" semi-colon?
- !(HsExpr GhcPs) -- ^ "else" expr
-
- | PsErrSemiColonsInCondCmd
- -- ^ Unexpected semi-colons in conditional command
- !(HsExpr GhcPs) -- ^ conditional expr
- !Bool -- ^ "then" semi-colon?
- !(HsCmd GhcPs) -- ^ "then" expr
- !Bool -- ^ "else" semi-colon?
- !(HsCmd GhcPs) -- ^ "else" expr
-
- | PsErrAtInPatPos
- -- ^ @-operator in a pattern position
-
- | PsErrLambdaCmdInFunAppCmd !(LHsCmd GhcPs)
- -- ^ Unexpected lambda command in function application
-
- | PsErrCaseCmdInFunAppCmd !(LHsCmd GhcPs)
- -- ^ Unexpected case command in function application
-
- | PsErrIfCmdInFunAppCmd !(LHsCmd GhcPs)
- -- ^ Unexpected if command in function application
-
- | PsErrLetCmdInFunAppCmd !(LHsCmd GhcPs)
- -- ^ Unexpected let command in function application
-
- | PsErrDoCmdInFunAppCmd !(LHsCmd GhcPs)
- -- ^ Unexpected do command in function application
-
- | PsErrDoInFunAppExpr !(Maybe ModuleName) !(LHsExpr GhcPs)
- -- ^ Unexpected do block in function application
-
- | PsErrMDoInFunAppExpr !(Maybe ModuleName) !(LHsExpr GhcPs)
- -- ^ Unexpected mdo block in function application
-
- | PsErrLambdaInFunAppExpr !(LHsExpr GhcPs)
- -- ^ Unexpected lambda expression in function application
-
- | PsErrCaseInFunAppExpr !(LHsExpr GhcPs)
- -- ^ Unexpected case expression in function application
-
- | PsErrLambdaCaseInFunAppExpr !(LHsExpr GhcPs)
- -- ^ Unexpected lambda-case expression in function application
-
- | PsErrLetInFunAppExpr !(LHsExpr GhcPs)
- -- ^ Unexpected let expression in function application
-
- | PsErrIfInFunAppExpr !(LHsExpr GhcPs)
- -- ^ Unexpected if expression in function application
-
- | PsErrProcInFunAppExpr !(LHsExpr GhcPs)
- -- ^ Unexpected proc expression in function application
-
- | PsErrMalformedTyOrClDecl !(LHsType GhcPs)
- -- ^ Malformed head of type or class declaration
-
- | PsErrIllegalWhereInDataDecl
- -- ^ Illegal 'where' keyword in data declaration
-
- | PsErrIllegalDataTypeContext !(LHsContext GhcPs)
- -- ^ Illegal datatyp context
-
- | PsErrParseErrorOnInput !OccName
- -- ^ Parse error on input
-
- | PsErrMalformedDecl !SDoc !RdrName
- -- ^ Malformed ... declaration for ...
-
- | PsErrUnexpectedTypeAppInDecl !(LHsType GhcPs) !SDoc !RdrName
- -- ^ Unexpected type application in a declaration
-
- | PsErrNotADataCon !RdrName
- -- ^ Not a data constructor
-
- | PsErrRecordSyntaxInPatSynDecl !(LPat GhcPs)
- -- ^ Record syntax used in pattern synonym declaration
-
- | PsErrEmptyWhereInPatSynDecl !RdrName
- -- ^ Empty 'where' clause in pattern-synonym declaration
-
- | PsErrInvalidWhereBindInPatSynDecl !RdrName !(HsDecl GhcPs)
- -- ^ Invalid binding name in 'where' clause of pattern-synonym declaration
-
- | PsErrNoSingleWhereBindInPatSynDecl !RdrName !(HsDecl GhcPs)
- -- ^ Multiple bindings in 'where' clause of pattern-synonym declaration
-
- | PsErrDeclSpliceNotAtTopLevel !(SpliceDecl GhcPs)
- -- ^ Declaration splice not a top-level
-
- | PsErrInferredTypeVarNotAllowed
- -- ^ Inferred type variables not allowed here
-
- | PsErrMultipleNamesInStandaloneKindSignature [LIdP GhcPs]
- -- ^ Multiple names in standalone kind signatures
-
- | PsErrIllegalImportBundleForm
- -- ^ Illegal import bundle form
-
- | PsErrIllegalRoleName !FastString [Role]
- -- ^ Illegal role name
-
- | PsErrInvalidTypeSignature !(LHsExpr GhcPs)
- -- ^ Invalid type signature
-
- | PsErrUnexpectedTypeInDecl !(LHsType GhcPs) !SDoc !RdrName [LHsTypeArg GhcPs] !SDoc
- -- ^ Unexpected type in declaration
-
- | PsErrExpectedHyphen
- -- ^ Expected a hyphen
-
- | PsErrSpaceInSCC
- -- ^ Found a space in a SCC
-
- | PsErrEmptyDoubleQuotes !Bool-- Is TH on?
- -- ^ Found two single quotes
-
- | PsErrInvalidPackageName !FastString
- -- ^ Invalid package name
-
- | PsErrInvalidRuleActivationMarker
- -- ^ Invalid rule activation marker
-
- | PsErrLinearFunction
- -- ^ Linear function found but LinearTypes not enabled
-
- | PsErrMultiWayIf
- -- ^ Multi-way if-expression found but MultiWayIf not enabled
-
- | PsErrExplicitForall !Bool -- is Unicode forall?
- -- ^ Explicit forall found but no extension allowing it is enabled
-
- | PsErrIllegalQualifiedDo !SDoc
- -- ^ Found qualified-do without QualifiedDo enabled
-
- | PsErrCmmParser !CmmParserError
- -- ^ Cmm parser error
-
- | PsErrIllegalTraditionalRecordSyntax !SDoc
- -- ^ Illegal traditional record syntax
- --
- -- TODO: distinguish errors without using SDoc
-
- | PsErrParseErrorInCmd !SDoc
- -- ^ Parse error in command
- --
- -- TODO: distinguish errors without using SDoc
-
- | PsErrParseErrorInPat !SDoc
- -- ^ Parse error in pattern
- --
- -- TODO: distinguish errors without using SDoc
-
-
-newtype StarIsType = StarIsType Bool
-
-data NumUnderscoreReason
- = NumUnderscore_Integral
- | NumUnderscore_Float
- deriving (Show,Eq,Ord)
-
-data LexErrKind
- = LexErrKind_EOF -- ^ End of input
- | LexErrKind_UTF8 -- ^ UTF-8 decoding error
- | LexErrKind_Char !Char -- ^ Error at given character
- deriving (Show,Eq,Ord)
-
-data LexErr
- = LexError -- ^ Lexical error
- | LexUnknownPragma -- ^ Unknown pragma
- | LexErrorInPragma -- ^ Lexical error in pragma
- | LexNumEscapeRange -- ^ Numeric escape sequence out of range
- | LexStringCharLit -- ^ Llexical error in string/character literal
- | LexStringCharLitEOF -- ^ Unexpected end-of-file in string/character literal
- | LexUnterminatedComment -- ^ Unterminated `{-'
- | LexUnterminatedOptions -- ^ Unterminated OPTIONS pragma
- | LexUnterminatedQQ -- ^ Unterminated quasiquotation
-
--- | Errors from the Cmm parser
-data CmmParserError
- = CmmUnknownPrimitive !FastString -- ^ Unknown Cmm primitive
- | CmmUnknownMacro !FastString -- ^ Unknown macro
- | CmmUnknownCConv !String -- ^ Unknown calling convention
- | CmmUnrecognisedSafety !String -- ^ Unrecognised safety
- | CmmUnrecognisedHint !String -- ^ Unrecognised hint
diff --git a/compiler/GHC/Parser/Errors/Ppr.hs b/compiler/GHC/Parser/Errors/Ppr.hs
index 4cc8da75f4..6a2152f3f7 100644
--- a/compiler/GHC/Parser/Errors/Ppr.hs
+++ b/compiler/GHC/Parser/Errors/Ppr.hs
@@ -1,528 +1,479 @@
+{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} -- instance Diagnostic PsMessage
-module GHC.Parser.Errors.Ppr
- ( mkParserWarn
- , mkParserErr
- , pprPsError
- )
-where
+module GHC.Parser.Errors.Ppr where
import GHC.Prelude
import GHC.Driver.Flags
-import GHC.Parser.Errors
import GHC.Parser.Errors.Types
import GHC.Parser.Types
import GHC.Types.Basic
import GHC.Types.Error
-import GHC.Types.Hint (perhapsAsPat)
import GHC.Types.SrcLoc
-import GHC.Types.Name.Reader (starInfo, rdrNameOcc, mkUnqual)
+import GHC.Types.Name.Reader (opIsAt, starInfo, rdrNameOcc, mkUnqual)
import GHC.Types.Name.Occurrence (isSymOcc, occNameFS, varName)
import GHC.Utils.Outputable
import GHC.Utils.Misc
import GHC.Data.FastString
+import GHC.Data.Maybe (catMaybes)
import GHC.Hs.Expr (prependQualified,HsExpr(..))
import GHC.Hs.Type (pprLHsContext)
import GHC.Builtin.Names (allNameStrings)
import GHC.Builtin.Types (filterCTuple)
-import GHC.Driver.Session (DynFlags)
-import GHC.Utils.Error (diagReasonSeverity)
+import qualified GHC.LanguageExtensions as LangExt
-instance Diagnostic PsMessage where
- diagnosticMessage (PsUnknownMessage m) = diagnosticMessage m
- diagnosticReason (PsUnknownMessage m) = diagnosticReason m
- -- FIXME(adinapoli) Fix it properly for #18516.
- -- The reason why we temporarily set 'diagnosticHints' to be
- -- the empty list is because currently the parser types does
- -- not integrate tightly with the new diagnostic infrastructure
- -- and as such hints and bundled together with the rendereded
- -- diagnostic, and the same 'PsErrorDesc' is sometimes emitted
- -- twice but with a different hint, which makes it hard to
- -- untangle the two. Therefore, to smooth out the integration,
- -- we provisionally tuck the hints directly into a 'PsUnknownMessage'
- -- and we rendered them inside 'diagnosticMessage'.
- diagnosticHints (PsUnknownMessage _m) = []
-
-mk_parser_err :: [GhcHint] -> SrcSpan -> SDoc -> MsgEnvelope PsMessage
-mk_parser_err hints span doc = MsgEnvelope
- { errMsgSpan = span
- , errMsgContext = alwaysQualify
- , errMsgDiagnostic = PsUnknownMessage $ mkPlainError hints doc
- , errMsgSeverity = SevError
- }
-
-mk_parser_warn :: DynFlags -> WarningFlag -> SrcSpan -> SDoc -> MsgEnvelope PsMessage
-mk_parser_warn df flag span doc = MsgEnvelope
- { errMsgSpan = span
- , errMsgContext = alwaysQualify
- , errMsgDiagnostic = PsUnknownMessage $ mkPlainDiagnostic reason noHints doc
- , errMsgSeverity = diagReasonSeverity df reason
- }
- where
- reason :: DiagnosticReason
- reason = WarningWithFlag flag
-mkParserWarn :: DynFlags -> PsWarning -> MsgEnvelope PsMessage
-mkParserWarn df = \case
- PsWarnTab loc tc
- -> mk_parser_warn df Opt_WarnTabs loc $
- text "Tab character found here"
- <> (if tc == 1
- then text ""
- else text ", and in" <+> speakNOf (fromIntegral (tc - 1)) (text "further location"))
- <> text "."
- $+$ text "Please use spaces instead."
-
- PsWarnTransitionalLayout loc reason
- -> mk_parser_warn df Opt_WarnAlternativeLayoutRuleTransitional loc $
+instance Diagnostic PsMessage where
+ diagnosticMessage = \case
+ PsUnknownMessage m
+ -> diagnosticMessage m
+
+ PsWarnHaddockInvalidPos
+ -> mkSimpleDecorated $ text "A Haddock comment cannot appear in this position and will be ignored."
+ PsWarnHaddockIgnoreMulti
+ -> mkSimpleDecorated $
+ text "Multiple Haddock comments for a single entity are not allowed." $$
+ text "The extraneous comment will be ignored."
+ PsWarnTab tc
+ -> mkSimpleDecorated $
+ text "Tab character found here"
+ <> (if tc == 1
+ then text ""
+ else text ", and in" <+> speakNOf (fromIntegral (tc - 1)) (text "further location"))
+ <> text "."
+ PsWarnTransitionalLayout reason
+ -> mkSimpleDecorated $
text "transitional layout will not be accepted in the future:"
$$ text (case reason of
TransLayout_Where -> "`where' clause at the same depth as implicit layout block"
TransLayout_Pipe -> "`|' at the same depth as implicit layout block"
)
-
- PsWarnUnrecognisedPragma loc
- -> mk_parser_warn df Opt_WarnUnrecognisedPragmas loc $
- text "Unrecognised pragma"
-
- PsWarnHaddockInvalidPos loc
- -> mk_parser_warn df Opt_WarnInvalidHaddock loc $
- text "A Haddock comment cannot appear in this position and will be ignored."
-
- PsWarnHaddockIgnoreMulti loc
- -> mk_parser_warn df Opt_WarnInvalidHaddock loc $
- text "Multiple Haddock comments for a single entity are not allowed." $$
- text "The extraneous comment will be ignored."
-
- PsWarnStarBinder loc
- -> mk_parser_warn df Opt_WarnStarBinder loc $
- text "Found binding occurrence of" <+> quotes (text "*")
- <+> text "yet StarIsType is enabled."
- $$ text "NB. To use (or export) this operator in"
- <+> text "modules with StarIsType,"
- $$ text " including the definition module, you must qualify it."
-
- PsWarnStarIsType loc
- -> mk_parser_warn df Opt_WarnStarIsType loc $
- text "Using" <+> quotes (text "*")
- <+> text "(or its Unicode variant) to mean"
- <+> quotes (text "Data.Kind.Type")
- $$ text "relies on the StarIsType extension, which will become"
- $$ text "deprecated in the future."
- $$ text "Suggested fix: use" <+> quotes (text "Type")
- <+> text "from" <+> quotes (text "Data.Kind") <+> text "instead."
-
- PsWarnImportPreQualified loc
- -> mk_parser_warn df Opt_WarnPrepositiveQualifiedModule loc $
- text "Found" <+> quotes (text "qualified")
- <+> text "in prepositive position"
- $$ text "Suggested fix: place " <+> quotes (text "qualified")
- <+> text "after the module name instead."
- $$ text "To allow this, enable language extension 'ImportQualifiedPost'"
-
- PsWarnOperatorWhitespaceExtConflict loc sym
- -> mk_parser_warn df Opt_WarnOperatorWhitespaceExtConflict loc $
- let mk_prefix_msg operator_symbol extension_name syntax_meaning =
+ PsWarnOperatorWhitespaceExtConflict sym
+ -> let mk_prefix_msg operator_symbol extension_name syntax_meaning =
text "The prefix use of a" <+> quotes (text operator_symbol)
<+> text "would denote" <+> text syntax_meaning
$$ nest 2 (text "were the" <+> text extension_name <+> text "extension enabled.")
$$ text "Suggested fix: add whitespace after the"
<+> quotes (text operator_symbol) <> char '.'
- in
+ in mkSimpleDecorated $
case sym of
OperatorWhitespaceSymbol_PrefixPercent -> mk_prefix_msg "%" "LinearTypes" "a multiplicity annotation"
OperatorWhitespaceSymbol_PrefixDollar -> mk_prefix_msg "$" "TemplateHaskell" "an untyped splice"
OperatorWhitespaceSymbol_PrefixDollarDollar -> mk_prefix_msg "$$" "TemplateHaskell" "a typed splice"
-
-
- PsWarnOperatorWhitespace loc sym occ_type
- -> mk_parser_warn df Opt_WarnOperatorWhitespace loc $
- let mk_msg occ_type_str =
+ PsWarnOperatorWhitespace sym occ_type
+ -> let mk_msg occ_type_str =
text "The" <+> text occ_type_str <+> text "use of a" <+> quotes (ftext sym)
<+> text "might be repurposed as special syntax"
$$ nest 2 (text "by a future language extension.")
$$ text "Suggested fix: add whitespace around it."
- in
+ in mkSimpleDecorated $
case occ_type of
OperatorWhitespaceOccurrence_Prefix -> mk_msg "prefix"
OperatorWhitespaceOccurrence_Suffix -> mk_msg "suffix"
OperatorWhitespaceOccurrence_TightInfix -> mk_msg "tight infix"
+ PsWarnStarBinder
+ -> mkSimpleDecorated $
+ text "Found binding occurrence of" <+> quotes (text "*")
+ <+> text "yet StarIsType is enabled."
+ $$ text "NB. To use (or export) this operator in"
+ <+> text "modules with StarIsType,"
+ $$ text " including the definition module, you must qualify it."
+ PsWarnStarIsType
+ -> mkSimpleDecorated $
+ text "Using" <+> quotes (text "*")
+ <+> text "(or its Unicode variant) to mean"
+ <+> quotes (text "Data.Kind.Type")
+ $$ text "relies on the StarIsType extension, which will become"
+ $$ text "deprecated in the future."
+ $$ text "Suggested fix: use" <+> quotes (text "Type")
+ <+> text "from" <+> quotes (text "Data.Kind") <+> text "instead."
+ PsWarnUnrecognisedPragma
+ -> mkSimpleDecorated $ text "Unrecognised pragma"
+ PsWarnImportPreQualified
+ -> mkSimpleDecorated $
+ text "Found" <+> quotes (text "qualified")
+ <+> text "in prepositive position"
+ $$ text "Suggested fix: place " <+> quotes (text "qualified")
+ <+> text "after the module name instead."
+ $$ text "To allow this, enable language extension 'ImportQualifiedPost'"
-mkParserErr :: PsError -> MsgEnvelope PsMessage
-mkParserErr err = mk_parser_err (errHints err) (errLoc err) $
- pprPsError (errDesc err) (errHints err)
-
--- | Render a 'PsErrorDesc' into an 'SDoc', with its 'Hint's.
-pprPsError :: PsErrorDesc -> [GhcHint] -> SDoc
-pprPsError desc hints = vcat (pp_err desc : map ppr hints)
-
-pp_err :: PsErrorDesc -> SDoc
-pp_err = \case
- PsErrLambdaCase
- -> text "Illegal lambda-case (use LambdaCase)"
-
- PsErrEmptyLambda
- -> text "A lambda requires at least one parameter"
-
- PsErrNumUnderscores reason
- -> text $ case reason of
- NumUnderscore_Integral -> "Use NumericUnderscores to allow underscores in integer literals"
- NumUnderscore_Float -> "Use NumericUnderscores to allow underscores in floating literals"
-
- PsErrPrimStringInvalidChar
- -> text "primitive string literal must contain only characters <= \'\\xFF\'"
-
- PsErrMissingBlock
- -> text "Missing block"
-
- PsErrLexer err kind
- -> hcat
- [ text $ case err of
- LexError -> "lexical error"
- LexUnknownPragma -> "unknown pragma"
- LexErrorInPragma -> "lexical error in pragma"
- LexNumEscapeRange -> "numeric escape sequence out of range"
- LexStringCharLit -> "lexical error in string/character literal"
- LexStringCharLitEOF -> "unexpected end-of-file in string/character literal"
- LexUnterminatedComment -> "unterminated `{-'"
- LexUnterminatedOptions -> "unterminated OPTIONS pragma"
- LexUnterminatedQQ -> "unterminated quasiquotation"
-
-
- , text $ case kind of
- LexErrKind_EOF -> " at end of input"
- LexErrKind_UTF8 -> " (UTF-8 decoding error)"
- LexErrKind_Char c -> " at character " ++ show c
- ]
-
- PsErrSuffixAT
- -> text "Suffix occurrence of @. For an as-pattern, remove the leading whitespace."
-
- PsErrParse token
+ PsErrLexer err kind
+ -> mkSimpleDecorated $ hcat
+ [ text $ case err of
+ LexError -> "lexical error"
+ LexUnknownPragma -> "unknown pragma"
+ LexErrorInPragma -> "lexical error in pragma"
+ LexNumEscapeRange -> "numeric escape sequence out of range"
+ LexStringCharLit -> "lexical error in string/character literal"
+ LexStringCharLitEOF -> "unexpected end-of-file in string/character literal"
+ LexUnterminatedComment -> "unterminated `{-'"
+ LexUnterminatedOptions -> "unterminated OPTIONS pragma"
+ LexUnterminatedQQ -> "unterminated quasiquotation"
+
+ , text $ case kind of
+ LexErrKind_EOF -> " at end of input"
+ LexErrKind_UTF8 -> " (UTF-8 decoding error)"
+ LexErrKind_Char c -> " at character " ++ show c
+ ]
+ PsErrParse token _details
| null token
- -> text "parse error (possibly incorrect indentation or mismatched brackets)"
-
+ -> mkSimpleDecorated $ text "parse error (possibly incorrect indentation or mismatched brackets)"
| otherwise
- -> text "parse error on input" <+> quotes (text token)
-
- PsErrCmmLexer
- -> text "Cmm lexical error"
-
- PsErrUnsupportedBoxedSumExpr s
- -> hang (text "Boxed sums not supported:") 2
- (pprSumOrTuple Boxed s)
-
- PsErrUnsupportedBoxedSumPat s
- -> hang (text "Boxed sums not supported:") 2
- (pprSumOrTuple Boxed s)
-
- PsErrUnexpectedQualifiedConstructor v
- -> hang (text "Expected an unqualified type constructor:") 2
- (ppr v)
-
- PsErrTupleSectionInPat
- -> text "Tuple section in pattern context"
-
- PsErrIllegalBangPattern e
- -> text "Illegal bang-pattern (use BangPatterns):" $$ ppr e
-
- PsErrOpFewArgs (StarIsType star_is_type) op
- -> text "Operator applied to too few arguments:" <+> ppr op
- $$ starInfo star_is_type op
-
- PsErrImportQualifiedTwice
- -> text "Multiple occurrences of 'qualified'"
-
- PsErrImportPostQualified
- -> text "Found" <+> quotes (text "qualified")
- <+> text "in postpositive position. "
- $$ text "To allow this, enable language extension 'ImportQualifiedPost'"
-
- PsErrIllegalExplicitNamespace
- -> text "Illegal keyword 'type' (use ExplicitNamespaces to enable)"
-
- PsErrVarForTyCon name
- -> text "Expecting a type constructor but found a variable,"
- <+> quotes (ppr name) <> text "."
- $$ if isSymOcc $ rdrNameOcc name
- then text "If" <+> quotes (ppr name) <+> text "is a type constructor"
- <+> text "then enable ExplicitNamespaces and use the 'type' keyword."
- else empty
-
- PsErrIllegalPatSynExport
- -> text "Illegal export form (use PatternSynonyms to enable)"
-
- PsErrMalformedEntityString
- -> text "Malformed entity string"
-
- PsErrDotsInRecordUpdate
- -> text "You cannot use `..' in a record update"
-
- PsErrPrecedenceOutOfRange i
- -> text "Precedence out of range: " <> int i
-
- PsErrOverloadedRecordDotInvalid
- -> text "Use of OverloadedRecordDot '.' not valid ('.' isn't allowed when constructing records or in record patterns)"
-
- PsErrOverloadedRecordUpdateNoQualifiedFields
- -> text "Fields cannot be qualified when OverloadedRecordUpdate is enabled"
-
- PsErrOverloadedRecordUpdateNotEnabled
- -> text "OverloadedRecordUpdate needs to be enabled"
-
- PsErrInvalidDataCon t
- -> hang (text "Cannot parse data constructor in a data/newtype declaration:") 2
- (ppr t)
-
- PsErrInvalidInfixDataCon lhs tc rhs
- -> hang (text "Cannot parse an infix data constructor in a data/newtype declaration:")
- 2 (ppr lhs <+> ppr tc <+> ppr rhs)
-
- PsErrUnpackDataCon
- -> text "{-# UNPACK #-} cannot be applied to a data constructor."
-
- PsErrUnexpectedKindAppInDataCon lhs ki
- -> hang (text "Unexpected kind application in a data/newtype declaration:") 2
- (ppr lhs <+> text "@" <> ppr ki)
-
- PsErrInvalidRecordCon p
- -> text "Not a record constructor:" <+> ppr p
-
- PsErrIllegalUnboxedStringInPat lit
- -> text "Illegal unboxed string literal in pattern:" $$ ppr lit
-
- PsErrDoNotationInPat
- -> text "do-notation in pattern"
-
- PsErrIfTheElseInPat
- -> text "(if ... then ... else ...)-syntax in pattern"
-
- PsErrLambdaCaseInPat
- -> text "(\\case ...)-syntax in pattern"
-
- PsErrCaseInPat
- -> text "(case ... of ...)-syntax in pattern"
-
- PsErrLetInPat
- -> text "(let ... in ...)-syntax in pattern"
-
- PsErrLambdaInPat
- -> text "Lambda-syntax in pattern."
- $$ text "Pattern matching on functions is not possible."
-
- PsErrArrowExprInPat e
- -> text "Expression syntax in pattern:" <+> ppr e
-
- PsErrArrowCmdInPat c
- -> text "Command syntax in pattern:" <+> ppr c
-
- PsErrArrowCmdInExpr c
- -> vcat
- [ text "Arrow command found where an expression was expected:"
- , nest 2 (ppr c)
- ]
-
- PsErrViewPatInExpr a b
- -> sep [ text "View pattern in expression context:"
- , nest 4 (ppr a <+> text "->" <+> ppr b)
- ]
-
- PsErrTypeAppWithoutSpace v e
- -> sep [ text "@-pattern in expression context:"
- , nest 4 (pprPrefixOcc v <> text "@" <> ppr e)
- ]
- $$ text "Type application syntax requires a space before '@'"
-
-
- PsErrLazyPatWithoutSpace e
- -> sep [ text "Lazy pattern in expression context:"
- , nest 4 (text "~" <> ppr e)
- ]
- $$ text "Did you mean to add a space after the '~'?"
-
- PsErrBangPatWithoutSpace e
- -> sep [ text "Bang pattern in expression context:"
- , nest 4 (text "!" <> ppr e)
- ]
- $$ text "Did you mean to add a space after the '!'?"
-
- PsErrUnallowedPragma prag
- -> hang (text "A pragma is not allowed in this position:") 2
- (ppr prag)
-
- PsErrQualifiedDoInCmd m
- -> hang (text "Parse error in command:") 2 $
- text "Found a qualified" <+> ppr m <> text ".do block in a command, but"
- $$ text "qualified 'do' is not supported in commands."
-
- PsErrParseErrorInCmd s
- -> hang (text "Parse error in command:") 2 s
-
- PsErrParseErrorInPat s
- -> text "Parse error in pattern:" <+> s
-
+ -> mkSimpleDecorated $ text "parse error on input" <+> quotes (text token)
+ PsErrCmmLexer
+ -> mkSimpleDecorated $ text "Cmm lexical error"
+ PsErrCmmParser cmm_err -> mkSimpleDecorated $ case cmm_err of
+ CmmUnknownPrimitive name -> text "unknown primitive" <+> ftext name
+ CmmUnknownMacro fun -> text "unknown macro" <+> ftext fun
+ CmmUnknownCConv cconv -> text "unknown calling convention:" <+> text cconv
+ CmmUnrecognisedSafety safety -> text "unrecognised safety" <+> text safety
+ CmmUnrecognisedHint hint -> text "unrecognised hint:" <+> text hint
- PsErrInvalidInfixHole
- -> text "Invalid infix hole, expected an infix operator"
+ PsErrTypeAppWithoutSpace v e
+ -> mkSimpleDecorated $
+ sep [ text "@-pattern in expression context:"
+ , nest 4 (pprPrefixOcc v <> text "@" <> ppr e)
+ ]
+ $$ text "Type application syntax requires a space before '@'"
+ PsErrLazyPatWithoutSpace e
+ -> mkSimpleDecorated $
+ sep [ text "Lazy pattern in expression context:"
+ , nest 4 (text "~" <> ppr e)
+ ]
+ $$ text "Did you mean to add a space after the '~'?"
+ PsErrBangPatWithoutSpace e
+ -> mkSimpleDecorated $
+ sep [ text "Bang pattern in expression context:"
+ , nest 4 (text "!" <> ppr e)
+ ]
+ $$ text "Did you mean to add a space after the '!'?"
+ PsErrInvalidInfixHole
+ -> mkSimpleDecorated $ text "Invalid infix hole, expected an infix operator"
+ PsErrExpectedHyphen
+ -> mkSimpleDecorated $ text "Expected a hyphen"
+ PsErrSpaceInSCC
+ -> mkSimpleDecorated $ text "Spaces are not allowed in SCCs"
+ PsErrEmptyDoubleQuotes th_on
+ -> mkSimpleDecorated $ if th_on then vcat (msg ++ th_msg) else vcat msg
+ where
+ msg = [ text "Parser error on `''`"
+ , text "Character literals may not be empty"
+ ]
+ th_msg = [ text "Or perhaps you intended to use quotation syntax of TemplateHaskell,"
+ , text "but the type variable or constructor is missing"
+ ]
- PsErrSemiColonsInCondExpr c st t se e
- -> text "Unexpected semi-colons in conditional:"
- $$ nest 4 expr
- $$ text "Perhaps you meant to use DoAndIfThenElse?"
+ PsErrLambdaCase
+ -> mkSimpleDecorated $ text "Illegal lambda-case (use LambdaCase)"
+ PsErrEmptyLambda
+ -> mkSimpleDecorated $ text "A lambda requires at least one parameter"
+ PsErrLinearFunction
+ -> mkSimpleDecorated $ text "Enable LinearTypes to allow linear functions"
+ PsErrOverloadedRecordUpdateNotEnabled
+ -> mkSimpleDecorated $ text "OverloadedRecordUpdate needs to be enabled"
+ PsErrMultiWayIf
+ -> mkSimpleDecorated $ text "Multi-way if-expressions need MultiWayIf turned on"
+ PsErrNumUnderscores reason
+ -> mkSimpleDecorated $
+ text $ case reason of
+ NumUnderscore_Integral -> "Use NumericUnderscores to allow underscores in integer literals"
+ NumUnderscore_Float -> "Use NumericUnderscores to allow underscores in floating literals"
+ PsErrIllegalBangPattern e
+ -> mkSimpleDecorated $ text "Illegal bang-pattern (use BangPatterns):" $$ ppr e
+ PsErrOverloadedRecordDotInvalid
+ -> mkSimpleDecorated $
+ text "Use of OverloadedRecordDot '.' not valid ('.' isn't allowed when constructing records or in record patterns)"
+ PsErrIllegalPatSynExport
+ -> mkSimpleDecorated $ text "Illegal export form (use PatternSynonyms to enable)"
+ PsErrOverloadedRecordUpdateNoQualifiedFields
+ -> mkSimpleDecorated $ text "Fields cannot be qualified when OverloadedRecordUpdate is enabled"
+ PsErrExplicitForall is_unicode
+ -> mkSimpleDecorated $ vcat
+ [ text "Illegal symbol" <+> quotes (forallSym is_unicode) <+> text "in type"
+ , text "Perhaps you intended to use RankNTypes or a similar language"
+ , text "extension to enable explicit-forall syntax:" <+>
+ forallSym is_unicode <+> text "<tvs>. <type>"
+ ]
+ where
+ forallSym True = text "∀"
+ forallSym False = text "forall"
+ PsErrIllegalQualifiedDo qdoDoc
+ -> mkSimpleDecorated $ vcat
+ [ text "Illegal qualified" <+> quotes qdoDoc <+> text "block"
+ , text "Perhaps you intended to use QualifiedDo"
+ ]
+ PsErrQualifiedDoInCmd m
+ -> mkSimpleDecorated $
+ hang (text "Parse error in command:") 2 $
+ text "Found a qualified" <+> ppr m <> text ".do block in a command, but"
+ $$ text "qualified 'do' is not supported in commands."
+ PsErrRecordSyntaxInPatSynDecl pat
+ -> mkSimpleDecorated $
+ text "record syntax not supported for pattern synonym declarations:"
+ $$ ppr pat
+ PsErrEmptyWhereInPatSynDecl patsyn_name
+ -> mkSimpleDecorated $
+ text "pattern synonym 'where' clause cannot be empty"
+ $$ text "In the pattern synonym declaration for: "
+ <+> ppr (patsyn_name)
+ PsErrInvalidWhereBindInPatSynDecl patsyn_name decl
+ -> mkSimpleDecorated $
+ text "pattern synonym 'where' clause must bind the pattern synonym's name"
+ <+> quotes (ppr patsyn_name) $$ ppr decl
+ PsErrNoSingleWhereBindInPatSynDecl _patsyn_name decl
+ -> mkSimpleDecorated $
+ text "pattern synonym 'where' clause must contain a single binding:"
+ $$ ppr decl
+ PsErrDeclSpliceNotAtTopLevel d
+ -> mkSimpleDecorated $
+ hang (text "Declaration splices are allowed only"
+ <+> text "at the top level:")
+ 2 (ppr d)
+ PsErrMultipleNamesInStandaloneKindSignature vs
+ -> mkSimpleDecorated $
+ vcat [ hang (text "Standalone kind signatures do not support multiple names at the moment:")
+ 2 (pprWithCommas ppr vs)
+ , text "See https://gitlab.haskell.org/ghc/ghc/issues/16754 for details."
+ ]
+ PsErrIllegalExplicitNamespace
+ -> mkSimpleDecorated $
+ text "Illegal keyword 'type' (use ExplicitNamespaces to enable)"
+
+ PsErrUnallowedPragma prag
+ -> mkSimpleDecorated $
+ hang (text "A pragma is not allowed in this position:") 2
+ (ppr prag)
+ PsErrImportPostQualified
+ -> mkSimpleDecorated $
+ text "Found" <+> quotes (text "qualified")
+ <+> text "in postpositive position. "
+ $$ text "To allow this, enable language extension 'ImportQualifiedPost'"
+ PsErrImportQualifiedTwice
+ -> mkSimpleDecorated $ text "Multiple occurrences of 'qualified'"
+ PsErrIllegalImportBundleForm
+ -> mkSimpleDecorated $
+ text "Illegal import form, this syntax can only be used to bundle"
+ $+$ text "pattern synonyms with types in module exports."
+ PsErrInvalidRuleActivationMarker
+ -> mkSimpleDecorated $ text "Invalid rule activation marker"
+
+ PsErrMissingBlock
+ -> mkSimpleDecorated $ text "Missing block"
+ PsErrUnsupportedBoxedSumExpr s
+ -> mkSimpleDecorated $
+ hang (text "Boxed sums not supported:") 2
+ (pprSumOrTuple Boxed s)
+ PsErrUnsupportedBoxedSumPat s
+ -> mkSimpleDecorated $
+ hang (text "Boxed sums not supported:") 2
+ (pprSumOrTuple Boxed s)
+ PsErrUnexpectedQualifiedConstructor v
+ -> mkSimpleDecorated $
+ hang (text "Expected an unqualified type constructor:") 2
+ (ppr v)
+ PsErrTupleSectionInPat
+ -> mkSimpleDecorated $ text "Tuple section in pattern context"
+ PsErrOpFewArgs (StarIsType star_is_type) op
+ -> mkSimpleDecorated $
+ text "Operator applied to too few arguments:" <+> ppr op
+ $$ starInfo star_is_type op
+ PsErrVarForTyCon name
+ -> mkSimpleDecorated $
+ text "Expecting a type constructor but found a variable,"
+ <+> quotes (ppr name) <> text "."
+ $$ if isSymOcc $ rdrNameOcc name
+ then text "If" <+> quotes (ppr name) <+> text "is a type constructor"
+ <+> text "then enable ExplicitNamespaces and use the 'type' keyword."
+ else empty
+ PsErrMalformedEntityString
+ -> mkSimpleDecorated $ text "Malformed entity string"
+ PsErrDotsInRecordUpdate
+ -> mkSimpleDecorated $ text "You cannot use `..' in a record update"
+ PsErrInvalidDataCon t
+ -> mkSimpleDecorated $
+ hang (text "Cannot parse data constructor in a data/newtype declaration:") 2
+ (ppr t)
+ PsErrInvalidInfixDataCon lhs tc rhs
+ -> mkSimpleDecorated $
+ hang (text "Cannot parse an infix data constructor in a data/newtype declaration:") 2
+ (ppr lhs <+> ppr tc <+> ppr rhs)
+ PsErrUnpackDataCon
+ -> mkSimpleDecorated $ text "{-# UNPACK #-} cannot be applied to a data constructor."
+ PsErrUnexpectedKindAppInDataCon lhs ki
+ -> mkSimpleDecorated $
+ hang (text "Unexpected kind application in a data/newtype declaration:") 2
+ (ppr lhs <+> text "@" <> ppr ki)
+ PsErrInvalidRecordCon p
+ -> mkSimpleDecorated $ text "Not a record constructor:" <+> ppr p
+ PsErrIllegalUnboxedStringInPat lit
+ -> mkSimpleDecorated $ text "Illegal unboxed string literal in pattern:" $$ ppr lit
+ PsErrDoNotationInPat
+ -> mkSimpleDecorated $ text "do-notation in pattern"
+ PsErrIfThenElseInPat
+ -> mkSimpleDecorated $ text "(if ... then ... else ...)-syntax in pattern"
+ PsErrLambdaCaseInPat
+ -> mkSimpleDecorated $ text "(\\case ...)-syntax in pattern"
+ PsErrCaseInPat
+ -> mkSimpleDecorated $ text "(case ... of ...)-syntax in pattern"
+ PsErrLetInPat
+ -> mkSimpleDecorated $ text "(let ... in ...)-syntax in pattern"
+ PsErrLambdaInPat
+ -> mkSimpleDecorated $
+ text "Lambda-syntax in pattern."
+ $$ text "Pattern matching on functions is not possible."
+ PsErrArrowExprInPat e
+ -> mkSimpleDecorated $ text "Expression syntax in pattern:" <+> ppr e
+ PsErrArrowCmdInPat c
+ -> mkSimpleDecorated $ text "Command syntax in pattern:" <+> ppr c
+ PsErrArrowCmdInExpr c
+ -> mkSimpleDecorated $
+ vcat
+ [ text "Arrow command found where an expression was expected:"
+ , nest 2 (ppr c)
+ ]
+ PsErrViewPatInExpr a b
+ -> mkSimpleDecorated $
+ sep [ text "View pattern in expression context:"
+ , nest 4 (ppr a <+> text "->" <+> ppr b)
+ ]
+ PsErrLambdaCmdInFunAppCmd a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "lambda command") a
+ PsErrCaseCmdInFunAppCmd a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "case command") a
+ PsErrIfCmdInFunAppCmd a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "if command") a
+ PsErrLetCmdInFunAppCmd a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "let command") a
+ PsErrDoCmdInFunAppCmd a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "do command") a
+ PsErrDoInFunAppExpr m a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (prependQualified m (text "do block")) a
+ PsErrMDoInFunAppExpr m a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (prependQualified m (text "mdo block")) a
+ PsErrLambdaInFunAppExpr a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "lambda expression") a
+ PsErrCaseInFunAppExpr a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "case expression") a
+ PsErrLambdaCaseInFunAppExpr a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "lambda-case expression") a
+ PsErrLetInFunAppExpr a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "let expression") a
+ PsErrIfInFunAppExpr a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "if expression") a
+ PsErrProcInFunAppExpr a
+ -> mkSimpleDecorated $ pp_unexpected_fun_app (text "proc expression") a
+ PsErrMalformedTyOrClDecl ty
+ -> mkSimpleDecorated $
+ text "Malformed head of type or class declaration:" <+> ppr ty
+ PsErrIllegalWhereInDataDecl
+ -> mkSimpleDecorated $
+ vcat
+ [ text "Illegal keyword 'where' in data declaration"
+ , text "Perhaps you intended to use GADTs or a similar language"
+ , text "extension to enable syntax: data T where"
+ ]
+ PsErrIllegalDataTypeContext c
+ -> mkSimpleDecorated $
+ text "Illegal datatype context (use DatatypeContexts):"
+ <+> pprLHsContext (Just c)
+ PsErrPrimStringInvalidChar
+ -> mkSimpleDecorated $ text "primitive string literal must contain only characters <= \'\\xFF\'"
+ PsErrSuffixAT
+ -> mkSimpleDecorated $
+ text "Suffix occurrence of @. For an as-pattern, remove the leading whitespace."
+ PsErrPrecedenceOutOfRange i
+ -> mkSimpleDecorated $ text "Precedence out of range: " <> int i
+ PsErrSemiColonsInCondExpr c st t se e
+ -> mkSimpleDecorated $
+ text "Unexpected semi-colons in conditional:"
+ $$ nest 4 expr
+ $$ text "Perhaps you meant to use DoAndIfThenElse?"
where
pprOptSemi True = semi
pprOptSemi False = empty
expr = text "if" <+> ppr c <> pprOptSemi st <+>
text "then" <+> ppr t <> pprOptSemi se <+>
text "else" <+> ppr e
-
- PsErrSemiColonsInCondCmd c st t se e
- -> text "Unexpected semi-colons in conditional:"
- $$ nest 4 expr
- $$ text "Perhaps you meant to use DoAndIfThenElse?"
+ PsErrSemiColonsInCondCmd c st t se e
+ -> mkSimpleDecorated $
+ text "Unexpected semi-colons in conditional:"
+ $$ nest 4 expr
+ $$ text "Perhaps you meant to use DoAndIfThenElse?"
where
pprOptSemi True = semi
pprOptSemi False = empty
expr = text "if" <+> ppr c <> pprOptSemi st <+>
text "then" <+> ppr t <> pprOptSemi se <+>
text "else" <+> ppr e
-
-
- PsErrAtInPatPos
- -> text "Found a binding for the"
- <+> quotes (text "@")
- <+> text "operator in a pattern position."
- $$ perhapsAsPat
-
- PsErrLambdaCmdInFunAppCmd a
- -> pp_unexpected_fun_app (text "lambda command") a
-
- PsErrCaseCmdInFunAppCmd a
- -> pp_unexpected_fun_app (text "case command") a
-
- PsErrIfCmdInFunAppCmd a
- -> pp_unexpected_fun_app (text "if command") a
-
- PsErrLetCmdInFunAppCmd a
- -> pp_unexpected_fun_app (text "let command") a
-
- PsErrDoCmdInFunAppCmd a
- -> pp_unexpected_fun_app (text "do command") a
-
- PsErrDoInFunAppExpr m a
- -> pp_unexpected_fun_app (prependQualified m (text "do block")) a
-
- PsErrMDoInFunAppExpr m a
- -> pp_unexpected_fun_app (prependQualified m (text "mdo block")) a
-
- PsErrLambdaInFunAppExpr a
- -> pp_unexpected_fun_app (text "lambda expression") a
-
- PsErrCaseInFunAppExpr a
- -> pp_unexpected_fun_app (text "case expression") a
-
- PsErrLambdaCaseInFunAppExpr a
- -> pp_unexpected_fun_app (text "lambda-case expression") a
-
- PsErrLetInFunAppExpr a
- -> pp_unexpected_fun_app (text "let expression") a
-
- PsErrIfInFunAppExpr a
- -> pp_unexpected_fun_app (text "if expression") a
-
- PsErrProcInFunAppExpr a
- -> pp_unexpected_fun_app (text "proc expression") a
-
- PsErrMalformedTyOrClDecl ty
- -> text "Malformed head of type or class declaration:"
- <+> ppr ty
-
- PsErrIllegalWhereInDataDecl
- -> vcat
- [ text "Illegal keyword 'where' in data declaration"
- , text "Perhaps you intended to use GADTs or a similar language"
- , text "extension to enable syntax: data T where"
- ]
-
- PsErrIllegalTraditionalRecordSyntax s
- -> text "Illegal record syntax (use TraditionalRecordSyntax):"
- <+> s
-
- PsErrParseErrorOnInput occ
- -> text "parse error on input" <+> ftext (occNameFS occ)
-
- PsErrIllegalDataTypeContext c
- -> text "Illegal datatype context (use DatatypeContexts):"
- <+> pprLHsContext (Just c)
-
- PsErrMalformedDecl what for
- -> text "Malformed" <+> what
- <+> text "declaration for" <+> quotes (ppr for)
-
- PsErrUnexpectedTypeAppInDecl ki what for
- -> vcat [ text "Unexpected type application"
- <+> text "@" <> ppr ki
- , text "In the" <+> what
- <+> text "declaration for"
- <+> quotes (ppr for)
- ]
-
- PsErrNotADataCon name
- -> text "Not a data constructor:" <+> quotes (ppr name)
-
- PsErrRecordSyntaxInPatSynDecl pat
- -> text "record syntax not supported for pattern synonym declarations:"
- $$ ppr pat
-
- PsErrEmptyWhereInPatSynDecl patsyn_name
- -> text "pattern synonym 'where' clause cannot be empty"
- $$ text "In the pattern synonym declaration for: "
- <+> ppr (patsyn_name)
-
- PsErrInvalidWhereBindInPatSynDecl patsyn_name decl
- -> text "pattern synonym 'where' clause must bind the pattern synonym's name"
- <+> quotes (ppr patsyn_name) $$ ppr decl
-
- PsErrNoSingleWhereBindInPatSynDecl _patsyn_name decl
- -> text "pattern synonym 'where' clause must contain a single binding:"
- $$ ppr decl
-
- PsErrDeclSpliceNotAtTopLevel d
- -> hang (text "Declaration splices are allowed only"
- <+> text "at the top level:")
- 2 (ppr d)
-
- PsErrInferredTypeVarNotAllowed
- -> text "Inferred type variables are not allowed here"
-
- PsErrIllegalRoleName role nearby
- -> text "Illegal role name" <+> quotes (ppr role)
- $$ case nearby of
- [] -> empty
- [r] -> text "Perhaps you meant" <+> quotes (ppr r)
- -- will this last case ever happen??
- _ -> hang (text "Perhaps you meant one of these:")
- 2 (pprWithCommas (quotes . ppr) nearby)
-
- PsErrMultipleNamesInStandaloneKindSignature vs
- -> vcat [ hang (text "Standalone kind signatures do not support multiple names at the moment:")
- 2 (pprWithCommas ppr vs)
- , text "See https://gitlab.haskell.org/ghc/ghc/issues/16754 for details."
- ]
-
- PsErrIllegalImportBundleForm
- -> text "Illegal import form, this syntax can only be used to bundle"
- $+$ text "pattern synonyms with types in module exports."
-
- PsErrInvalidTypeSignature lhs
- -> text "Invalid type signature:"
- <+> ppr lhs
- <+> text ":: ..."
- $$ text hint
+ PsErrAtInPatPos
+ -> mkSimpleDecorated $
+ text "Found a binding for the"
+ <+> quotes (text "@")
+ <+> text "operator in a pattern position."
+ $$ perhapsAsPat
+ PsErrParseErrorOnInput occ
+ -> mkSimpleDecorated $ text "parse error on input" <+> ftext (occNameFS occ)
+ PsErrMalformedDecl what for
+ -> mkSimpleDecorated $
+ text "Malformed" <+> what
+ <+> text "declaration for" <+> quotes (ppr for)
+ PsErrUnexpectedTypeAppInDecl ki what for
+ -> mkSimpleDecorated $
+ vcat [ text "Unexpected type application"
+ <+> text "@" <> ppr ki
+ , text "In the" <+> what
+ <+> text "declaration for"
+ <+> quotes (ppr for)
+ ]
+ PsErrNotADataCon name
+ -> mkSimpleDecorated $ text "Not a data constructor:" <+> quotes (ppr name)
+ PsErrInferredTypeVarNotAllowed
+ -> mkSimpleDecorated $ text "Inferred type variables are not allowed here"
+ PsErrIllegalTraditionalRecordSyntax s
+ -> mkSimpleDecorated $
+ text "Illegal record syntax (use TraditionalRecordSyntax):" <+> s
+ PsErrParseErrorInCmd s
+ -> mkSimpleDecorated $ hang (text "Parse error in command:") 2 s
+ PsErrInPat s details
+ -> let msg = parse_error_in_pat
+ body = case details of
+ PEIP_NegApp -> text "-" <> ppr s
+ PEIP_TypeArgs peipd_tyargs
+ | not (null peipd_tyargs) -> ppr s <+> vcat [
+ hsep [text "@" <> ppr t | t <- peipd_tyargs]
+ , text "Type applications in patterns are only allowed on data constructors."
+ ]
+ | otherwise -> ppr s
+ PEIP_OtherPatDetails (ParseContext (Just fun) _)
+ -> ppr s <+> text "In a function binding for the"
+ <+> quotes (ppr fun)
+ <+> text "operator."
+ $$ if opIsAt fun
+ then perhapsAsPat
+ else empty
+ _ -> ppr s
+ in mkSimpleDecorated $ msg <+> body
+ PsErrParseRightOpSectionInPat infixOcc s
+ -> mkSimpleDecorated $ parse_error_in_pat <+> pprInfixOcc infixOcc <> ppr s
+ PsErrIllegalRoleName role nearby
+ -> mkSimpleDecorated $
+ text "Illegal role name" <+> quotes (ppr role)
+ $$ case nearby of
+ [] -> empty
+ [r] -> text "Perhaps you meant" <+> quotes (ppr r)
+ -- will this last case ever happen??
+ _ -> hang (text "Perhaps you meant one of these:")
+ 2 (pprWithCommas (quotes . ppr) nearby)
+ PsErrInvalidTypeSignature lhs
+ -> mkSimpleDecorated $
+ text "Invalid type signature:"
+ <+> ppr lhs
+ <+> text ":: ..."
+ $$ text hint
where
hint | foreign_RDR `looks_like` lhs
= "Perhaps you meant to use ForeignFunctionInterface?"
@@ -537,7 +488,7 @@ pp_err = \case
-- so check for that, and suggest. cf #3805
-- Sadly 'foreign import' still barfs 'parse error' because
-- 'import' is a keyword
- -- looks_like :: RdrName -> LHsExpr GhcPs -> Bool -- AZ
+ -- looks_like :: RdrName -> LHsExpr GhcPsErr -> Bool -- AZ
looks_like s (L _ (HsVar _ (L _ v))) = v == s
looks_like s (L _ (HsApp _ lhs _)) = looks_like s lhs
looks_like _ _ = False
@@ -545,83 +496,276 @@ pp_err = \case
foreign_RDR = mkUnqual varName (fsLit "foreign")
default_RDR = mkUnqual varName (fsLit "default")
pattern_RDR = mkUnqual varName (fsLit "pattern")
-
- PsErrUnexpectedTypeInDecl t what tc tparms equals_or_where
- -> vcat [ text "Unexpected type" <+> quotes (ppr t)
- , text "In the" <+> what
- <+> text "declaration for" <+> quotes tc'
- , vcat[ (text "A" <+> what
- <+> text "declaration should have form")
- , nest 2
- (what
- <+> tc'
- <+> hsep (map text (takeList tparms allNameStrings))
- <+> equals_or_where) ] ]
- where
- -- Avoid printing a constraint tuple in the error message. Print
- -- a plain old tuple instead (since that's what the user probably
- -- wrote). See #14907
- tc' = ppr $ filterCTuple tc
-
- PsErrCmmParser cmm_err -> case cmm_err of
- CmmUnknownPrimitive name -> text "unknown primitive" <+> ftext name
- CmmUnknownMacro fun -> text "unknown macro" <+> ftext fun
- CmmUnknownCConv cconv -> text "unknown calling convention:" <+> text cconv
- CmmUnrecognisedSafety safety -> text "unrecognised safety" <+> text safety
- CmmUnrecognisedHint hint -> text "unrecognised hint:" <+> text hint
-
- PsErrExpectedHyphen
- -> text "Expected a hyphen"
-
- PsErrSpaceInSCC
- -> text "Spaces are not allowed in SCCs"
-
- PsErrEmptyDoubleQuotes th_on
- -> if th_on then vcat (msg ++ th_msg) else vcat msg
- where
- msg = [ text "Parser error on `''`"
- , text "Character literals may not be empty"
- ]
- th_msg = [ text "Or perhaps you intended to use quotation syntax of TemplateHaskell,"
- , text "but the type variable or constructor is missing"
- ]
-
- PsErrInvalidPackageName pkg
- -> vcat
+ PsErrUnexpectedTypeInDecl t what tc tparms equals_or_where
+ -> mkSimpleDecorated $
+ vcat [ text "Unexpected type" <+> quotes (ppr t)
+ , text "In the" <+> what
+ <+> text "declaration for" <+> quotes tc'
+ , vcat[ (text "A" <+> what
+ <+> text "declaration should have form")
+ , nest 2
+ (what
+ <+> tc'
+ <+> hsep (map text (takeList tparms allNameStrings))
+ <+> equals_or_where) ] ]
+ where
+ -- Avoid printing a constraint tuple in the error message. Print
+ -- a plain old tuple instead (since that's what the user probably
+ -- wrote). See #14907
+ tc' = ppr $ filterCTuple tc
+ PsErrInvalidPackageName pkg
+ -> mkSimpleDecorated $ vcat
[ text "Parse error" <> colon <+> quotes (ftext pkg)
, text "Version number or non-alphanumeric" <+>
text "character in package name"
]
- PsErrInvalidRuleActivationMarker
- -> text "Invalid rule activation marker"
-
- PsErrLinearFunction
- -> text "Enable LinearTypes to allow linear functions"
-
- PsErrMultiWayIf
- -> text "Multi-way if-expressions need MultiWayIf turned on"
-
- PsErrExplicitForall is_unicode
- -> vcat
- [ text "Illegal symbol" <+> quotes (forallSym is_unicode) <+> text "in type"
- , text "Perhaps you intended to use RankNTypes or a similar language"
- , text "extension to enable explicit-forall syntax:" <+>
- forallSym is_unicode <+> text "<tvs>. <type>"
- ]
- where
- forallSym True = text "∀"
- forallSym False = text "forall"
-
- PsErrIllegalQualifiedDo qdoDoc
- -> vcat
- [ text "Illegal qualified" <+> quotes qdoDoc <+> text "block"
- , text "Perhaps you intended to use QualifiedDo"
- ]
+ diagnosticReason = \case
+ PsUnknownMessage m -> diagnosticReason m
+ PsWarnTab{} -> WarningWithFlag Opt_WarnTabs
+ PsWarnTransitionalLayout{} -> WarningWithFlag Opt_WarnAlternativeLayoutRuleTransitional
+ PsWarnOperatorWhitespaceExtConflict{} -> WarningWithFlag Opt_WarnOperatorWhitespaceExtConflict
+ PsWarnOperatorWhitespace{} -> WarningWithFlag Opt_WarnOperatorWhitespace
+ PsWarnHaddockInvalidPos -> WarningWithFlag Opt_WarnInvalidHaddock
+ PsWarnHaddockIgnoreMulti -> WarningWithFlag Opt_WarnInvalidHaddock
+ PsWarnStarBinder -> WarningWithFlag Opt_WarnStarBinder
+ PsWarnStarIsType -> WarningWithFlag Opt_WarnStarIsType
+ PsWarnUnrecognisedPragma -> WarningWithFlag Opt_WarnUnrecognisedPragmas
+ PsWarnImportPreQualified -> WarningWithFlag Opt_WarnPrepositiveQualifiedModule
+ PsErrLexer{} -> ErrorWithoutFlag
+ PsErrCmmLexer -> ErrorWithoutFlag
+ PsErrCmmParser{} -> ErrorWithoutFlag
+ PsErrParse{} -> ErrorWithoutFlag
+ PsErrTypeAppWithoutSpace{} -> ErrorWithoutFlag
+ PsErrLazyPatWithoutSpace{} -> ErrorWithoutFlag
+ PsErrBangPatWithoutSpace{} -> ErrorWithoutFlag
+ PsErrInvalidInfixHole -> ErrorWithoutFlag
+ PsErrExpectedHyphen -> ErrorWithoutFlag
+ PsErrSpaceInSCC -> ErrorWithoutFlag
+ PsErrEmptyDoubleQuotes{} -> ErrorWithoutFlag
+ PsErrLambdaCase{} -> ErrorWithoutFlag
+ PsErrEmptyLambda{} -> ErrorWithoutFlag
+ PsErrLinearFunction{} -> ErrorWithoutFlag
+ PsErrMultiWayIf{} -> ErrorWithoutFlag
+ PsErrOverloadedRecordUpdateNotEnabled{} -> ErrorWithoutFlag
+ PsErrNumUnderscores{} -> ErrorWithoutFlag
+ PsErrIllegalBangPattern{} -> ErrorWithoutFlag
+ PsErrOverloadedRecordDotInvalid{} -> ErrorWithoutFlag
+ PsErrIllegalPatSynExport -> ErrorWithoutFlag
+ PsErrOverloadedRecordUpdateNoQualifiedFields -> ErrorWithoutFlag
+ PsErrExplicitForall{} -> ErrorWithoutFlag
+ PsErrIllegalQualifiedDo{} -> ErrorWithoutFlag
+ PsErrQualifiedDoInCmd{} -> ErrorWithoutFlag
+ PsErrRecordSyntaxInPatSynDecl{} -> ErrorWithoutFlag
+ PsErrEmptyWhereInPatSynDecl{} -> ErrorWithoutFlag
+ PsErrInvalidWhereBindInPatSynDecl{} -> ErrorWithoutFlag
+ PsErrNoSingleWhereBindInPatSynDecl{} -> ErrorWithoutFlag
+ PsErrDeclSpliceNotAtTopLevel{} -> ErrorWithoutFlag
+ PsErrMultipleNamesInStandaloneKindSignature{} -> ErrorWithoutFlag
+ PsErrIllegalExplicitNamespace -> ErrorWithoutFlag
+ PsErrUnallowedPragma{} -> ErrorWithoutFlag
+ PsErrImportPostQualified -> ErrorWithoutFlag
+ PsErrImportQualifiedTwice -> ErrorWithoutFlag
+ PsErrIllegalImportBundleForm -> ErrorWithoutFlag
+ PsErrInvalidRuleActivationMarker -> ErrorWithoutFlag
+ PsErrMissingBlock -> ErrorWithoutFlag
+ PsErrUnsupportedBoxedSumExpr{} -> ErrorWithoutFlag
+ PsErrUnsupportedBoxedSumPat{} -> ErrorWithoutFlag
+ PsErrUnexpectedQualifiedConstructor{} -> ErrorWithoutFlag
+ PsErrTupleSectionInPat{} -> ErrorWithoutFlag
+ PsErrOpFewArgs{} -> ErrorWithoutFlag
+ PsErrVarForTyCon{} -> ErrorWithoutFlag
+ PsErrMalformedEntityString -> ErrorWithoutFlag
+ PsErrDotsInRecordUpdate -> ErrorWithoutFlag
+ PsErrInvalidDataCon{} -> ErrorWithoutFlag
+ PsErrInvalidInfixDataCon{} -> ErrorWithoutFlag
+ PsErrUnpackDataCon -> ErrorWithoutFlag
+ PsErrUnexpectedKindAppInDataCon{} -> ErrorWithoutFlag
+ PsErrInvalidRecordCon{} -> ErrorWithoutFlag
+ PsErrIllegalUnboxedStringInPat{} -> ErrorWithoutFlag
+ PsErrDoNotationInPat{} -> ErrorWithoutFlag
+ PsErrIfThenElseInPat -> ErrorWithoutFlag
+ PsErrLambdaCaseInPat -> ErrorWithoutFlag
+ PsErrCaseInPat -> ErrorWithoutFlag
+ PsErrLetInPat -> ErrorWithoutFlag
+ PsErrLambdaInPat -> ErrorWithoutFlag
+ PsErrArrowExprInPat{} -> ErrorWithoutFlag
+ PsErrArrowCmdInPat{} -> ErrorWithoutFlag
+ PsErrArrowCmdInExpr{} -> ErrorWithoutFlag
+ PsErrViewPatInExpr{} -> ErrorWithoutFlag
+ PsErrLambdaCmdInFunAppCmd{} -> ErrorWithoutFlag
+ PsErrCaseCmdInFunAppCmd{} -> ErrorWithoutFlag
+ PsErrIfCmdInFunAppCmd{} -> ErrorWithoutFlag
+ PsErrLetCmdInFunAppCmd{} -> ErrorWithoutFlag
+ PsErrDoCmdInFunAppCmd{} -> ErrorWithoutFlag
+ PsErrDoInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrMDoInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrLambdaInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrCaseInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrLambdaCaseInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrLetInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrIfInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrProcInFunAppExpr{} -> ErrorWithoutFlag
+ PsErrMalformedTyOrClDecl{} -> ErrorWithoutFlag
+ PsErrIllegalWhereInDataDecl -> ErrorWithoutFlag
+ PsErrIllegalDataTypeContext{} -> ErrorWithoutFlag
+ PsErrPrimStringInvalidChar -> ErrorWithoutFlag
+ PsErrSuffixAT -> ErrorWithoutFlag
+ PsErrPrecedenceOutOfRange{} -> ErrorWithoutFlag
+ PsErrSemiColonsInCondExpr{} -> ErrorWithoutFlag
+ PsErrSemiColonsInCondCmd{} -> ErrorWithoutFlag
+ PsErrAtInPatPos -> ErrorWithoutFlag
+ PsErrParseErrorOnInput{} -> ErrorWithoutFlag
+ PsErrMalformedDecl{} -> ErrorWithoutFlag
+ PsErrUnexpectedTypeAppInDecl{} -> ErrorWithoutFlag
+ PsErrNotADataCon{} -> ErrorWithoutFlag
+ PsErrInferredTypeVarNotAllowed -> ErrorWithoutFlag
+ PsErrIllegalTraditionalRecordSyntax{} -> ErrorWithoutFlag
+ PsErrParseErrorInCmd{} -> ErrorWithoutFlag
+ PsErrInPat{} -> ErrorWithoutFlag
+ PsErrIllegalRoleName{} -> ErrorWithoutFlag
+ PsErrInvalidTypeSignature{} -> ErrorWithoutFlag
+ PsErrUnexpectedTypeInDecl{} -> ErrorWithoutFlag
+ PsErrInvalidPackageName{} -> ErrorWithoutFlag
+ PsErrParseRightOpSectionInPat{} -> ErrorWithoutFlag
+
+ diagnosticHints = \case
+ PsUnknownMessage m -> diagnosticHints m
+ PsWarnTab{} -> [SuggestUseSpaces]
+ PsWarnTransitionalLayout{} -> noHints
+ PsWarnOperatorWhitespaceExtConflict{} -> noHints
+ PsWarnOperatorWhitespace{} -> noHints
+ PsWarnHaddockInvalidPos -> noHints
+ PsWarnHaddockIgnoreMulti -> noHints
+ PsWarnStarBinder -> noHints
+ PsWarnStarIsType -> noHints
+ PsWarnUnrecognisedPragma -> noHints
+ PsWarnImportPreQualified -> noHints
+ PsErrLexer{} -> noHints
+ PsErrCmmLexer -> noHints
+ PsErrCmmParser{} -> noHints
+ PsErrParse token PsErrParseDetails{..} -> case token of
+ "" -> []
+ "$" | not ped_th_enabled -> [SuggestExtension LangExt.TemplateHaskell] -- #7396
+ "<-" | ped_mdo_in_last_100 -> [SuggestExtension LangExt.RecursiveDo]
+ | otherwise -> [SuggestMissingDo]
+ "=" | ped_do_in_last_100 -> [SuggestLetInDo] -- #15849
+ _ | not ped_pat_syn_enabled
+ , ped_pattern_parsed -> [SuggestExtension LangExt.PatternSynonyms] -- #12429
+ | otherwise -> []
+ PsErrTypeAppWithoutSpace{} -> noHints
+ PsErrLazyPatWithoutSpace{} -> noHints
+ PsErrBangPatWithoutSpace{} -> noHints
+ PsErrInvalidInfixHole -> noHints
+ PsErrExpectedHyphen -> noHints
+ PsErrSpaceInSCC -> noHints
+ PsErrEmptyDoubleQuotes{} -> noHints
+ PsErrLambdaCase{} -> noHints
+ PsErrEmptyLambda{} -> noHints
+ PsErrLinearFunction{} -> noHints
+ PsErrMultiWayIf{} -> noHints
+ PsErrOverloadedRecordUpdateNotEnabled{} -> noHints
+ PsErrNumUnderscores{} -> noHints
+ PsErrIllegalBangPattern{} -> noHints
+ PsErrOverloadedRecordDotInvalid{} -> noHints
+ PsErrIllegalPatSynExport -> noHints
+ PsErrOverloadedRecordUpdateNoQualifiedFields -> noHints
+ PsErrExplicitForall{} -> noHints
+ PsErrIllegalQualifiedDo{} -> noHints
+ PsErrQualifiedDoInCmd{} -> noHints
+ PsErrRecordSyntaxInPatSynDecl{} -> noHints
+ PsErrEmptyWhereInPatSynDecl{} -> noHints
+ PsErrInvalidWhereBindInPatSynDecl{} -> noHints
+ PsErrNoSingleWhereBindInPatSynDecl{} -> noHints
+ PsErrDeclSpliceNotAtTopLevel{} -> noHints
+ PsErrMultipleNamesInStandaloneKindSignature{} -> noHints
+ PsErrIllegalExplicitNamespace -> noHints
+ PsErrUnallowedPragma{} -> noHints
+ PsErrImportPostQualified -> noHints
+ PsErrImportQualifiedTwice -> noHints
+ PsErrIllegalImportBundleForm -> noHints
+ PsErrInvalidRuleActivationMarker -> noHints
+ PsErrMissingBlock -> noHints
+ PsErrUnsupportedBoxedSumExpr{} -> noHints
+ PsErrUnsupportedBoxedSumPat{} -> noHints
+ PsErrUnexpectedQualifiedConstructor{} -> noHints
+ PsErrTupleSectionInPat{} -> noHints
+ PsErrOpFewArgs{} -> noHints
+ PsErrVarForTyCon{} -> noHints
+ PsErrMalformedEntityString -> noHints
+ PsErrDotsInRecordUpdate -> noHints
+ PsErrInvalidDataCon{} -> noHints
+ PsErrInvalidInfixDataCon{} -> noHints
+ PsErrUnpackDataCon -> noHints
+ PsErrUnexpectedKindAppInDataCon{} -> noHints
+ PsErrInvalidRecordCon{} -> noHints
+ PsErrIllegalUnboxedStringInPat{} -> noHints
+ PsErrDoNotationInPat{} -> noHints
+ PsErrIfThenElseInPat -> noHints
+ PsErrLambdaCaseInPat -> noHints
+ PsErrCaseInPat -> noHints
+ PsErrLetInPat -> noHints
+ PsErrLambdaInPat -> noHints
+ PsErrArrowExprInPat{} -> noHints
+ PsErrArrowCmdInPat{} -> noHints
+ PsErrArrowCmdInExpr{} -> noHints
+ PsErrViewPatInExpr{} -> noHints
+ PsErrLambdaCmdInFunAppCmd{} -> suggestParensAndBlockArgs
+ PsErrCaseCmdInFunAppCmd{} -> suggestParensAndBlockArgs
+ PsErrIfCmdInFunAppCmd{} -> suggestParensAndBlockArgs
+ PsErrLetCmdInFunAppCmd{} -> suggestParensAndBlockArgs
+ PsErrDoCmdInFunAppCmd{} -> suggestParensAndBlockArgs
+ PsErrDoInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrMDoInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrLambdaInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrCaseInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrLambdaCaseInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrLetInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrIfInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrProcInFunAppExpr{} -> suggestParensAndBlockArgs
+ PsErrMalformedTyOrClDecl{} -> noHints
+ PsErrIllegalWhereInDataDecl -> noHints
+ PsErrIllegalDataTypeContext{} -> noHints
+ PsErrPrimStringInvalidChar -> noHints
+ PsErrSuffixAT -> noHints
+ PsErrPrecedenceOutOfRange{} -> noHints
+ PsErrSemiColonsInCondExpr{} -> noHints
+ PsErrSemiColonsInCondCmd{} -> noHints
+ PsErrAtInPatPos -> noHints
+ PsErrParseErrorOnInput{} -> noHints
+ PsErrMalformedDecl{} -> noHints
+ PsErrUnexpectedTypeAppInDecl{} -> noHints
+ PsErrNotADataCon{} -> noHints
+ PsErrInferredTypeVarNotAllowed -> noHints
+ PsErrIllegalTraditionalRecordSyntax{} -> noHints
+ PsErrParseErrorInCmd{} -> noHints
+ PsErrInPat _ details -> case details of
+ PEIP_RecPattern args YesPatIsRecursive ctx
+ | length args /= 0 -> catMaybes [sug_recdo, sug_missingdo ctx]
+ | otherwise -> catMaybes [sug_missingdo ctx]
+ PEIP_OtherPatDetails ctx -> catMaybes [sug_missingdo ctx]
+ _ -> []
+ where
+ sug_recdo = Just (SuggestExtension LangExt.RecursiveDo)
+ sug_missingdo (ParseContext _ YesIncompleteDoBlock) = Just SuggestMissingDo
+ sug_missingdo _ = Nothing
+ PsErrParseRightOpSectionInPat{} -> noHints
+ PsErrIllegalRoleName{} -> noHints
+ PsErrInvalidTypeSignature{} -> noHints
+ PsErrUnexpectedTypeInDecl{} -> noHints
+ PsErrInvalidPackageName{} -> noHints
+
+suggestParensAndBlockArgs :: [GhcHint]
+suggestParensAndBlockArgs =
+ [SuggestParentheses, SuggestExtension LangExt.BlockArguments]
pp_unexpected_fun_app :: Outputable a => SDoc -> a -> SDoc
pp_unexpected_fun_app e a =
text "Unexpected " <> e <> text " in function application:"
$$ nest 4 (ppr a)
- $$ text "You could write it with parentheses"
- $$ text "Or perhaps you meant to enable BlockArguments?"
+
+parse_error_in_pat :: SDoc
+parse_error_in_pat = text "Parse error in pattern:"
+
+perhapsAsPat :: SDoc
+perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace"
diff --git a/compiler/GHC/Parser/Errors/Types.hs b/compiler/GHC/Parser/Errors/Types.hs
index 293dcc3ee0..d75c223253 100644
--- a/compiler/GHC/Parser/Errors/Types.hs
+++ b/compiler/GHC/Parser/Errors/Types.hs
@@ -1,9 +1,502 @@
+{-# LANGUAGE ExistentialQuantification #-}
module GHC.Parser.Errors.Types where
+import GHC.Prelude
+
+import Data.Typeable
+
+import GHC.Core.TyCon (Role)
+import GHC.Data.FastString
+import GHC.Hs
+import GHC.Parser.Types
import GHC.Types.Error
+import GHC.Types.Name.Occurrence (OccName)
+import GHC.Types.Name.Reader
+import GHC.Unit.Module.Name
+import GHC.Utils.Outputable
+
+-- The type aliases below are useful to make some type signatures a bit more
+-- descriptive, like 'handleWarningsThrowErrors' in 'GHC.Driver.Main'.
+
+type PsWarning = PsMessage -- /INVARIANT/: The diagnosticReason is a Warning reason
+type PsError = PsMessage -- /INVARIANT/: The diagnosticReason is ErrorWithoutFlag
data PsMessage
- = PsUnknownMessage !DiagnosticMessage
- -- ^ Simply rewraps a generic 'DiagnosticMessage'. More
- -- constructors will be added in the future (#18516).
+ =
+ {-| An \"unknown\" message from the parser. This type constructor allows
+ arbitrary messages to be embedded. The typical use case would be GHC plugins
+ willing to emit custom diagnostics.
+ -}
+ forall a. (Diagnostic a, Typeable a) => PsUnknownMessage a
+
+ {-| PsWarnTab is a warning (controlled by the -Wwarn-tabs flag) that occurs
+ when tabulations (tabs) are found within a file.
+
+ Test case(s): parser/should_fail/T12610
+ parser/should_compile/T9723b
+ parser/should_compile/T9723a
+ parser/should_compile/read043
+ parser/should_fail/T16270
+ warnings/should_compile/T9230
+
+ -}
+ | PsWarnTab !Word -- ^ Number of other occurrences other than the first one
+
+ {-| PsWarnTransitionalLayout is a warning (controlled by the
+ -Walternative-layout-rule-transitional flag) that occurs when pipes ('|')
+ or 'where' are at the same depth of an implicit layout block.
+
+ Example(s):
+
+ f :: IO ()
+ f
+ | True = do
+ let x = ()
+ y = ()
+ return ()
+ | True = return ()
+
+ Test case(s): layout/layout006
+ layout/layout003
+ layout/layout001
+
+ -}
+ | PsWarnTransitionalLayout !TransLayoutReason
+
+ -- | Unrecognised pragma
+ | PsWarnUnrecognisedPragma
+
+ -- | Invalid Haddock comment position
+ | PsWarnHaddockInvalidPos
+
+ -- | Multiple Haddock comment for the same entity
+ | PsWarnHaddockIgnoreMulti
+
+ -- | Found binding occurrence of "*" while StarIsType is enabled
+ | PsWarnStarBinder
+
+ -- | Using "*" for "Type" without StarIsType enabled
+ | PsWarnStarIsType
+
+ -- | Pre qualified import with 'WarnPrepositiveQualifiedModule' enabled
+ | PsWarnImportPreQualified
+
+ | PsWarnOperatorWhitespaceExtConflict !OperatorWhitespaceSymbol
+
+ | PsWarnOperatorWhitespace !FastString !OperatorWhitespaceOccurrence
+
+ -- | LambdaCase syntax used without the extension enabled
+ | PsErrLambdaCase
+
+ -- | A lambda requires at least one parameter
+ | PsErrEmptyLambda
+
+ -- | Underscores in literals without the extension enabled
+ | PsErrNumUnderscores !NumUnderscoreReason
+
+ -- | Invalid character in primitive string
+ | PsErrPrimStringInvalidChar
+
+ -- | Missing block
+ | PsErrMissingBlock
+
+ -- | Lexer error
+ | PsErrLexer !LexErr !LexErrKind
+
+ -- | Suffix occurrence of `@`
+ | PsErrSuffixAT
+
+ -- | Parse errors
+ | PsErrParse !String !PsErrParseDetails
+
+ -- | Cmm lexer error
+ | PsErrCmmLexer
+
+ -- | Unsupported boxed sum in expression
+ | PsErrUnsupportedBoxedSumExpr !(SumOrTuple (HsExpr GhcPs))
+
+ -- | Unsupported boxed sum in pattern
+ | PsErrUnsupportedBoxedSumPat !(SumOrTuple (PatBuilder GhcPs))
+
+ -- | Unexpected qualified constructor
+ | PsErrUnexpectedQualifiedConstructor !RdrName
+
+ -- | Tuple section in pattern context
+ | PsErrTupleSectionInPat
+
+ -- | Bang-pattern without BangPattterns enabled
+ | PsErrIllegalBangPattern !(Pat GhcPs)
+
+ -- | Operator applied to too few arguments
+ | PsErrOpFewArgs !StarIsType !RdrName
+
+ -- | Import: multiple occurrences of 'qualified'
+ | PsErrImportQualifiedTwice
+
+ -- | Post qualified import without 'ImportQualifiedPost'
+ | PsErrImportPostQualified
+
+ -- | Explicit namespace keyword without 'ExplicitNamespaces'
+ | PsErrIllegalExplicitNamespace
+
+ -- | Expecting a type constructor but found a variable
+ | PsErrVarForTyCon !RdrName
+
+ -- | Illegal export form allowed by PatternSynonyms
+ | PsErrIllegalPatSynExport
+
+ -- | Malformed entity string
+ | PsErrMalformedEntityString
+
+ -- | Dots used in record update
+ | PsErrDotsInRecordUpdate
+
+ -- | Precedence out of range
+ | PsErrPrecedenceOutOfRange !Int
+
+ -- | Invalid use of record dot syntax `.'
+ | PsErrOverloadedRecordDotInvalid
+
+ -- | `OverloadedRecordUpdate` is not enabled.
+ | PsErrOverloadedRecordUpdateNotEnabled
+
+ -- | Can't use qualified fields when OverloadedRecordUpdate is enabled.
+ | PsErrOverloadedRecordUpdateNoQualifiedFields
+
+ -- | Cannot parse data constructor in a data/newtype declaration
+ | PsErrInvalidDataCon !(HsType GhcPs)
+
+ -- | Cannot parse data constructor in a data/newtype declaration
+ | PsErrInvalidInfixDataCon !(HsType GhcPs) !RdrName !(HsType GhcPs)
+
+ -- | UNPACK applied to a data constructor
+ | PsErrUnpackDataCon
+
+ -- | Unexpected kind application in data/newtype declaration
+ | PsErrUnexpectedKindAppInDataCon !DataConBuilder !(HsType GhcPs)
+
+ -- | Not a record constructor
+ | PsErrInvalidRecordCon !(PatBuilder GhcPs)
+
+ -- | Illegal unboxed string literal in pattern
+ | PsErrIllegalUnboxedStringInPat !(HsLit GhcPs)
+
+ -- | Do-notation in pattern
+ | PsErrDoNotationInPat
+
+ -- | If-then-else syntax in pattern
+ | PsErrIfThenElseInPat
+
+ -- | Lambda-case in pattern
+ | PsErrLambdaCaseInPat
+
+ -- | case..of in pattern
+ | PsErrCaseInPat
+
+ -- | let-syntax in pattern
+ | PsErrLetInPat
+
+ -- | Lambda-syntax in pattern
+ | PsErrLambdaInPat
+
+ -- | Arrow expression-syntax in pattern
+ | PsErrArrowExprInPat !(HsExpr GhcPs)
+
+ -- | Arrow command-syntax in pattern
+ | PsErrArrowCmdInPat !(HsCmd GhcPs)
+
+ -- | Arrow command-syntax in expression
+ | PsErrArrowCmdInExpr !(HsCmd GhcPs)
+
+ -- | View-pattern in expression
+ | PsErrViewPatInExpr !(LHsExpr GhcPs) !(LHsExpr GhcPs)
+
+ -- | Type-application without space before '@'
+ | PsErrTypeAppWithoutSpace !RdrName !(LHsExpr GhcPs)
+
+ -- | Lazy-pattern ('~') without space after it
+ | PsErrLazyPatWithoutSpace !(LHsExpr GhcPs)
+
+ -- | Bang-pattern ('!') without space after it
+ | PsErrBangPatWithoutSpace !(LHsExpr GhcPs)
+
+ -- | Pragma not allowed in this position
+ | PsErrUnallowedPragma !(HsPragE GhcPs)
+
+ -- | Qualified do block in command
+ | PsErrQualifiedDoInCmd !ModuleName
+
+ -- | Invalid infix hole, expected an infix operator
+ | PsErrInvalidInfixHole
+
+ -- | Unexpected semi-colons in conditional expression
+ | PsErrSemiColonsInCondExpr
+ !(HsExpr GhcPs) -- ^ conditional expr
+ !Bool -- ^ "then" semi-colon?
+ !(HsExpr GhcPs) -- ^ "then" expr
+ !Bool -- ^ "else" semi-colon?
+ !(HsExpr GhcPs) -- ^ "else" expr
+
+ -- | Unexpected semi-colons in conditional command
+ | PsErrSemiColonsInCondCmd
+ !(HsExpr GhcPs) -- ^ conditional expr
+ !Bool -- ^ "then" semi-colon?
+ !(HsCmd GhcPs) -- ^ "then" expr
+ !Bool -- ^ "else" semi-colon?
+ !(HsCmd GhcPs) -- ^ "else" expr
+
+ -- | @-operator in a pattern position
+ | PsErrAtInPatPos
+
+ -- | Unexpected lambda command in function application
+ | PsErrLambdaCmdInFunAppCmd !(LHsCmd GhcPs)
+
+ -- | Unexpected case command in function application
+ | PsErrCaseCmdInFunAppCmd !(LHsCmd GhcPs)
+
+ -- | Unexpected if command in function application
+ | PsErrIfCmdInFunAppCmd !(LHsCmd GhcPs)
+
+ -- | Unexpected let command in function application
+ | PsErrLetCmdInFunAppCmd !(LHsCmd GhcPs)
+
+ -- | Unexpected do command in function application
+ | PsErrDoCmdInFunAppCmd !(LHsCmd GhcPs)
+
+ -- | Unexpected do block in function application
+ | PsErrDoInFunAppExpr !(Maybe ModuleName) !(LHsExpr GhcPs)
+
+ -- | Unexpected mdo block in function application
+ | PsErrMDoInFunAppExpr !(Maybe ModuleName) !(LHsExpr GhcPs)
+
+ -- | Unexpected lambda expression in function application
+ | PsErrLambdaInFunAppExpr !(LHsExpr GhcPs)
+
+ -- | Unexpected case expression in function application
+ | PsErrCaseInFunAppExpr !(LHsExpr GhcPs)
+
+ -- | Unexpected lambda-case expression in function application
+ | PsErrLambdaCaseInFunAppExpr !(LHsExpr GhcPs)
+
+ -- | Unexpected let expression in function application
+ | PsErrLetInFunAppExpr !(LHsExpr GhcPs)
+
+ -- | Unexpected if expression in function application
+ | PsErrIfInFunAppExpr !(LHsExpr GhcPs)
+
+ -- | Unexpected proc expression in function application
+ | PsErrProcInFunAppExpr !(LHsExpr GhcPs)
+
+ -- | Malformed head of type or class declaration
+ | PsErrMalformedTyOrClDecl !(LHsType GhcPs)
+
+ -- | Illegal 'where' keyword in data declaration
+ | PsErrIllegalWhereInDataDecl
+
+ -- | Illegal datatype context
+ | PsErrIllegalDataTypeContext !(LHsContext GhcPs)
+
+ -- | Parse error on input
+ | PsErrParseErrorOnInput !OccName
+
+ -- | Malformed ... declaration for ...
+ | PsErrMalformedDecl !SDoc !RdrName
+
+ -- | Unexpected type application in a declaration
+ | PsErrUnexpectedTypeAppInDecl !(LHsType GhcPs) !SDoc !RdrName
+
+ -- | Not a data constructor
+ | PsErrNotADataCon !RdrName
+
+ -- | Record syntax used in pattern synonym declaration
+ | PsErrRecordSyntaxInPatSynDecl !(LPat GhcPs)
+
+ -- | Empty 'where' clause in pattern-synonym declaration
+ | PsErrEmptyWhereInPatSynDecl !RdrName
+
+ -- | Invalid binding name in 'where' clause of pattern-synonym declaration
+ | PsErrInvalidWhereBindInPatSynDecl !RdrName !(HsDecl GhcPs)
+
+ -- | Multiple bindings in 'where' clause of pattern-synonym declaration
+ | PsErrNoSingleWhereBindInPatSynDecl !RdrName !(HsDecl GhcPs)
+
+ -- | Declaration splice not a top-level
+ | PsErrDeclSpliceNotAtTopLevel !(SpliceDecl GhcPs)
+
+ -- | Inferred type variables not allowed here
+ | PsErrInferredTypeVarNotAllowed
+
+ -- | Multiple names in standalone kind signatures
+ | PsErrMultipleNamesInStandaloneKindSignature [LIdP GhcPs]
+
+ -- | Illegal import bundle form
+ | PsErrIllegalImportBundleForm
+
+ -- | Illegal role name
+ | PsErrIllegalRoleName !FastString [Role]
+
+ -- | Invalid type signature
+ | PsErrInvalidTypeSignature !(LHsExpr GhcPs)
+
+ -- | Unexpected type in declaration
+ | PsErrUnexpectedTypeInDecl !(LHsType GhcPs)
+ !SDoc
+ !RdrName
+ [LHsTypeArg GhcPs]
+ !SDoc
+
+ -- | Expected a hyphen
+ | PsErrExpectedHyphen
+
+ -- | Found a space in a SCC
+ | PsErrSpaceInSCC
+
+ -- | Found two single quotes
+ | PsErrEmptyDoubleQuotes !Bool
+ -- ^ Is TH on?
+
+ -- | Invalid package name
+ | PsErrInvalidPackageName !FastString
+
+ -- | Invalid rule activation marker
+ | PsErrInvalidRuleActivationMarker
+
+ -- | Linear function found but LinearTypes not enabled
+ | PsErrLinearFunction
+
+ -- | Multi-way if-expression found but MultiWayIf not enabled
+ | PsErrMultiWayIf
+
+ -- | Explicit forall found but no extension allowing it is enabled
+ | PsErrExplicitForall !Bool
+ -- ^ is Unicode forall?
+
+ -- | Found qualified-do without QualifiedDo enabled
+ | PsErrIllegalQualifiedDo !SDoc
+
+ -- | Cmm parser error
+ | PsErrCmmParser !CmmParserError
+
+ -- | Illegal traditional record syntax
+ --
+ -- TODO: distinguish errors without using SDoc
+ | PsErrIllegalTraditionalRecordSyntax !SDoc
+
+ -- | Parse error in command
+ --
+ -- TODO: distinguish errors without using SDoc
+ | PsErrParseErrorInCmd !SDoc
+
+ -- | Parse error in pattern
+ | PsErrInPat !(PatBuilder GhcPs) !PsErrInPatDetails
+
+ -- | Parse error in right operator section pattern
+ -- TODO: embed the proper operator, if possible
+ | forall infixOcc. (OutputableBndr infixOcc) => PsErrParseRightOpSectionInPat !infixOcc !(PatBuilder GhcPs)
+
+newtype StarIsType = StarIsType Bool
+
+-- | Extra details about a parse error, which helps
+-- us in determining which should be the hints to
+-- suggest.
+data PsErrParseDetails
+ = PsErrParseDetails
+ { ped_th_enabled :: !Bool
+ -- Is 'TemplateHaskell' enabled?
+ , ped_do_in_last_100 :: !Bool
+ -- ^ Is there a 'do' in the last 100 characters?
+ , ped_mdo_in_last_100 :: !Bool
+ -- ^ Is there an 'mdo' in the last 100 characters?
+ , ped_pat_syn_enabled :: !Bool
+ -- ^ Is 'PatternSynonyms' enabled?
+ , ped_pattern_parsed :: !Bool
+ -- ^ Did we parse a \"pattern\" keyword?
+ }
+
+-- | Is the parsed pattern recursive?
+data PatIsRecursive
+ = YesPatIsRecursive
+ | NoPatIsRecursive
+
+data PatIncompleteDoBlock
+ = YesIncompleteDoBlock
+ | NoIncompleteDoBlock
+ deriving Eq
+
+-- | Extra information for the expression GHC is currently inspecting/parsing.
+-- It can be used to generate more informative parser diagnostics and hints.
+data ParseContext
+ = ParseContext
+ { is_infix :: !(Maybe RdrName)
+ -- ^ If 'Just', this is an infix
+ -- pattern with the binded operator name
+ , incomplete_do_block :: !PatIncompleteDoBlock
+ -- ^ Did the parser likely fail due to an incomplete do block?
+ } deriving Eq
+
+data PsErrInPatDetails
+ = PEIP_NegApp
+ -- ^ Negative application pattern?
+ | PEIP_TypeArgs [HsPatSigType GhcPs]
+ -- ^ The list of type arguments for the pattern
+ | PEIP_RecPattern [LPat GhcPs] -- ^ The pattern arguments
+ !PatIsRecursive -- ^ Is the parsed pattern recursive?
+ !ParseContext
+ | PEIP_OtherPatDetails !ParseContext
+
+noParseContext :: ParseContext
+noParseContext = ParseContext Nothing NoIncompleteDoBlock
+
+incompleteDoBlock :: ParseContext
+incompleteDoBlock = ParseContext Nothing YesIncompleteDoBlock
+
+-- | Builds a 'PsErrInPatDetails' with the information provided by the 'ParseContext'.
+fromParseContext :: ParseContext -> PsErrInPatDetails
+fromParseContext = PEIP_OtherPatDetails
+
+data NumUnderscoreReason
+ = NumUnderscore_Integral
+ | NumUnderscore_Float
+ deriving (Show,Eq,Ord)
+
+data LexErrKind
+ = LexErrKind_EOF -- ^ End of input
+ | LexErrKind_UTF8 -- ^ UTF-8 decoding error
+ | LexErrKind_Char !Char -- ^ Error at given character
+ deriving (Show,Eq,Ord)
+
+data LexErr
+ = LexError -- ^ Lexical error
+ | LexUnknownPragma -- ^ Unknown pragma
+ | LexErrorInPragma -- ^ Lexical error in pragma
+ | LexNumEscapeRange -- ^ Numeric escape sequence out of range
+ | LexStringCharLit -- ^ Lexical error in string/character literal
+ | LexStringCharLitEOF -- ^ Unexpected end-of-file in string/character literal
+ | LexUnterminatedComment -- ^ Unterminated `{-'
+ | LexUnterminatedOptions -- ^ Unterminated OPTIONS pragma
+ | LexUnterminatedQQ -- ^ Unterminated quasiquotation
+
+-- | Errors from the Cmm parser
+data CmmParserError
+ = CmmUnknownPrimitive !FastString -- ^ Unknown Cmm primitive
+ | CmmUnknownMacro !FastString -- ^ Unknown macro
+ | CmmUnknownCConv !String -- ^ Unknown calling convention
+ | CmmUnrecognisedSafety !String -- ^ Unrecognised safety
+ | CmmUnrecognisedHint !String -- ^ Unrecognised hint
+
+-- | The operator symbol in the 'PsOperatorWhitespaceExtConflictMessage' diagnostic.
+data OperatorWhitespaceSymbol
+ = OperatorWhitespaceSymbol_PrefixPercent
+ | OperatorWhitespaceSymbol_PrefixDollar
+ | OperatorWhitespaceSymbol_PrefixDollarDollar
+
+-- | The operator occurrence type in the 'PsOperatorWhitespaceMessage' diagnostic.
+data OperatorWhitespaceOccurrence
+ = OperatorWhitespaceOccurrence_Prefix
+ | OperatorWhitespaceOccurrence_Suffix
+ | OperatorWhitespaceOccurrence_TightInfix
+
+data TransLayoutReason
+ = TransLayout_Where -- ^ "`where' clause at the same depth as implicit layout block"
+ | TransLayout_Pipe -- ^ "`|' at the same depth as implicit layout block")
diff --git a/compiler/GHC/Parser/Header.hs b/compiler/GHC/Parser/Header.hs
index 52a98d86dc..daa8bc78a5 100644
--- a/compiler/GHC/Parser/Header.hs
+++ b/compiler/GHC/Parser/Header.hs
@@ -30,8 +30,6 @@ import GHC.Driver.Config
import GHC.Driver.Errors.Types -- Unfortunate, needed due to the fact we throw exceptions!
import GHC.Parser.Errors.Types
-import GHC.Parser.Errors.Ppr
-import GHC.Parser.Errors
import GHC.Parser ( parseHeader )
import GHC.Parser.Lexer
@@ -53,7 +51,6 @@ import GHC.Utils.Exception as Exception
import GHC.Data.StringBuffer
import GHC.Data.Maybe
-import GHC.Data.Bag (Bag, isEmptyBag )
import GHC.Data.FastString
import qualified GHC.Data.Strict as Strict
@@ -79,7 +76,7 @@ getImports :: ParserOpts -- ^ Parser options
-> FilePath -- ^ The original source filename (used for locations
-- in the function result)
-> IO (Either
- (Bag PsError)
+ (Messages PsMessage)
([(Maybe FastString, Located ModuleName)],
[(Maybe FastString, Located ModuleName)],
Located ModuleName))
@@ -95,8 +92,8 @@ getImports popts implicit_prelude buf filename source_filename = do
let (_warns, errs) = getMessages pst
-- don't log warnings: they'll be reported when we parse the file
-- for real. See #2500.
- if not (isEmptyBag errs)
- then throwErrors $ foldPsMessages mkParserErr errs
+ if not (isEmptyMessages errs)
+ then throwErrors (GhcPsMessage <$> errs)
else
let hsmod = unLoc rdr_module
mb_mod = hsmodName hsmod
diff --git a/compiler/GHC/Parser/Lexer.x b/compiler/GHC/Parser/Lexer.x
index f9494afa6a..10c9f2042f 100644
--- a/compiler/GHC/Parser/Lexer.x
+++ b/compiler/GHC/Parser/Lexer.x
@@ -75,6 +75,7 @@ module GHC.Parser.Lexer (
commentToAnnotation,
HdkComment(..),
warnopt,
+ addPsMessage
) where
import GHC.Prelude
@@ -101,17 +102,17 @@ import Data.Map (Map)
import qualified Data.Map as Map
-- compiler
-import GHC.Data.Bag
+import GHC.Utils.Error
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Data.StringBuffer
import GHC.Data.FastString
+import GHC.Types.Error hiding ( getErrorMessages, getMessages )
import GHC.Types.Unique.FM
import GHC.Data.Maybe
import GHC.Data.OrdList
import GHC.Utils.Misc ( readSignificandExponentPair, readHexSignificandExponentPair )
-import GHC.Types.Error ( GhcHint(..) )
import GHC.Types.SrcLoc
import GHC.Types.SourceText
import GHC.Types.Basic ( InlineSpec(..), RuleMatchInfo(..))
@@ -121,7 +122,8 @@ import GHC.Parser.CharClass
import GHC.Parser.Annotation
import GHC.Driver.Flags
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
+import GHC.Parser.Errors.Ppr ()
}
-- -----------------------------------------------------------------------------
@@ -362,7 +364,7 @@ $tab { warnTab }
}
<0,option_prags> {
- "{-#" { warnThen Opt_WarnUnrecognisedPragmas PsWarnUnrecognisedPragma
+ "{-#" { warnThen PsWarnUnrecognisedPragma
(nested_comment lexToken) }
}
@@ -1143,7 +1145,8 @@ hopefully_open_brace span buf len
Layout prev_off _ : _ -> prev_off < offset
_ -> True
if isOK then pop_and open_brace span buf len
- else addFatalError $ PsError PsErrMissingBlock [] (mkSrcSpanPs span)
+ else addFatalError $
+ mkPlainErrorMsgEnvelope (mkSrcSpanPs span) PsErrMissingBlock
pop_and :: Action -> Action
pop_and act span buf len = do _ <- popLexState
@@ -1528,7 +1531,10 @@ docCommentEnd input commentAcc docType buf span = do
commentEnd lexToken input commentAcc finalizeComment buf span
errBrace :: AlexInput -> RealSrcSpan -> P a
-errBrace (AI end _) span = failLocMsgP (realSrcSpanStart span) (psRealLoc end) (PsError (PsErrLexer LexUnterminatedComment LexErrKind_EOF) [])
+errBrace (AI end _) span =
+ failLocMsgP (realSrcSpanStart span)
+ (psRealLoc end)
+ (\srcLoc -> mkPlainErrorMsgEnvelope srcLoc (PsErrLexer LexUnterminatedComment LexErrKind_EOF))
open_brace, close_brace :: Action
open_brace span _str _len = do
@@ -1587,7 +1593,7 @@ varid span buf len =
lambdaCase <- getBit LambdaCaseBit
unless lambdaCase $ do
pState <- getPState
- addError $ PsError PsErrLambdaCase [] (mkSrcSpanPs (last_loc pState))
+ addError $ mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) PsErrLambdaCase
return ITlcase
_ -> return ITcase
maybe_layout keyword
@@ -1619,8 +1625,7 @@ qconsym buf len = ITqconsym $! splitQualName buf len False
varsym_prefix :: Action
varsym_prefix = sym $ \span exts s ->
let warnExtConflict errtok =
- do { addWarning Opt_WarnOperatorWhitespaceExtConflict $
- PsWarnOperatorWhitespaceExtConflict (mkSrcSpanPs span) errtok
+ do { addPsMessage (mkSrcSpanPs span) (PsWarnOperatorWhitespaceExtConflict errtok)
; return (ITvarsym s) }
in
if | s == fsLit "@" ->
@@ -1646,19 +1651,19 @@ varsym_prefix = sym $ \span exts s ->
| s == fsLit "!" -> return ITbang
| s == fsLit "~" -> return ITtilde
| otherwise ->
- do { addWarning Opt_WarnOperatorWhitespace $
- PsWarnOperatorWhitespace (mkSrcSpanPs span) s
- OperatorWhitespaceOccurrence_Prefix
+ do { addPsMessage
+ (mkSrcSpanPs span)
+ (PsWarnOperatorWhitespace s OperatorWhitespaceOccurrence_Prefix)
; return (ITvarsym s) }
-- See Note [Whitespace-sensitive operator parsing]
varsym_suffix :: Action
varsym_suffix = sym $ \span _ s ->
- if | s == fsLit "@" -> failMsgP (PsError PsErrSuffixAT [])
+ if | s == fsLit "@" -> failMsgP (\srcLoc -> mkPlainErrorMsgEnvelope srcLoc $ PsErrSuffixAT)
| otherwise ->
- do { addWarning Opt_WarnOperatorWhitespace $
- PsWarnOperatorWhitespace (mkSrcSpanPs span) s
- OperatorWhitespaceOccurrence_Suffix
+ do { addPsMessage
+ (mkSrcSpanPs span)
+ (PsWarnOperatorWhitespace s OperatorWhitespaceOccurrence_Suffix)
; return (ITvarsym s) }
-- See Note [Whitespace-sensitive operator parsing]
@@ -1668,9 +1673,9 @@ varsym_tight_infix = sym $ \span exts s ->
| s == fsLit ".", OverloadedRecordDotBit `xtest` exts -> return (ITproj False)
| s == fsLit "." -> return ITdot
| otherwise ->
- do { addWarning Opt_WarnOperatorWhitespace $
- PsWarnOperatorWhitespace (mkSrcSpanPs span) s
- OperatorWhitespaceOccurrence_TightInfix
+ do { addPsMessage
+ (mkSrcSpanPs span)
+ (PsWarnOperatorWhitespace s (OperatorWhitespaceOccurrence_TightInfix))
; return (ITvarsym s) }
-- See Note [Whitespace-sensitive operator parsing]
@@ -1726,7 +1731,8 @@ tok_integral itint transint transbuf translen (radix,char_to_int) span buf len =
let src = lexemeToString buf len
when ((not numericUnderscores) && ('_' `elem` src)) $ do
pState <- getPState
- addError $ PsError (PsErrNumUnderscores NumUnderscore_Integral) [] (mkSrcSpanPs (last_loc pState))
+ let msg = PsErrNumUnderscores NumUnderscore_Integral
+ addError $ mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg
return $ L span $ itint (SourceText src)
$! transint $ parseUnsignedInteger
(offsetBytes transbuf buf) (subtract translen len) radix char_to_int
@@ -1767,7 +1773,8 @@ tok_frac drop f span buf len = do
let src = lexemeToString buf (len-drop)
when ((not numericUnderscores) && ('_' `elem` src)) $ do
pState <- getPState
- addError $ PsError (PsErrNumUnderscores NumUnderscore_Float) [] (mkSrcSpanPs (last_loc pState))
+ let msg = PsErrNumUnderscores NumUnderscore_Float
+ addError $ mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg
return (L span $! (f $! src))
tok_float, tok_primfloat, tok_primdouble :: String -> Token
@@ -1946,7 +1953,9 @@ lex_string_prag_comment mkTok span _buf _len
= case alexGetChar i of
Just (c,i') | c == x -> isString i' xs
_other -> False
- err (AI end _) = failLocMsgP (realSrcSpanStart (psRealSpan span)) (psRealLoc end) (PsError (PsErrLexer LexUnterminatedOptions LexErrKind_EOF) [])
+ err (AI end _) = failLocMsgP (realSrcSpanStart (psRealSpan span))
+ (psRealLoc end)
+ (\srcLoc -> mkPlainErrorMsgEnvelope srcLoc $ PsErrLexer LexUnterminatedOptions LexErrKind_EOF)
-- -----------------------------------------------------------------------------
-- Strings & Chars
@@ -1983,7 +1992,8 @@ lex_string s = do
setInput i
when (any (> '\xFF') s') $ do
pState <- getPState
- let err = PsError PsErrPrimStringInvalidChar [] (mkSrcSpanPs (last_loc pState))
+ let msg = PsErrPrimStringInvalidChar
+ let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg
addError err
return (ITprimstring (SourceText s') (unsafeMkByteString s'))
_other ->
@@ -2246,7 +2256,7 @@ quasiquote_error :: RealSrcLoc -> P a
quasiquote_error start = do
(AI end buf) <- getInput
reportLexError start (psRealLoc end) buf
- (\k -> PsError (PsErrLexer LexUnterminatedQQ k) [])
+ (\k srcLoc -> mkPlainErrorMsgEnvelope srcLoc (PsErrLexer LexUnterminatedQQ k))
-- -----------------------------------------------------------------------------
-- Warnings
@@ -2256,9 +2266,9 @@ warnTab srcspan _buf _len = do
addTabWarning (psRealSpan srcspan)
lexToken
-warnThen :: WarningFlag -> (SrcSpan -> PsWarning) -> Action -> Action
-warnThen flag warning action srcspan buf len = do
- addWarning flag (warning (RealSrcSpan (psRealSpan srcspan) Strict.Nothing))
+warnThen :: PsMessage -> Action -> Action
+warnThen warning action srcspan buf len = do
+ addPsMessage (RealSrcSpan (psRealSpan srcspan) Strict.Nothing) warning
action srcspan buf len
-- -----------------------------------------------------------------------------
@@ -2310,6 +2320,10 @@ warnopt f options = f `EnumSet.member` pWarningFlags options
data ParserOpts = ParserOpts
{ pWarningFlags :: EnumSet WarningFlag -- ^ enabled warning flags
, pExtsBitmap :: !ExtsBitmap -- ^ bitmap of permitted extensions
+ , pMakePsMessage :: SrcSpan -> PsMessage -> MsgEnvelope PsMessage
+ -- ^ The function to be used to construct diagnostic messages.
+ -- The idea is to partially-apply 'mkParserMessage' upstream, to
+ -- avoid the dependency on the 'DynFlags' in the Lexer.
}
-- | Haddock comment as produced by the lexer. These are accumulated in
@@ -2324,10 +2338,9 @@ data HdkComment
data PState = PState {
buffer :: StringBuffer,
options :: ParserOpts,
- warnings :: Bag PsWarning,
- errors :: Bag PsError,
- tab_first :: Strict.Maybe RealSrcSpan,
- -- pos of first tab warning in the file
+ warnings :: Messages PsMessage,
+ errors :: Messages PsMessage,
+ tab_first :: Strict.Maybe RealSrcSpan, -- pos of first tab warning in the file
tab_count :: !Word, -- number of tab warnings in the file
last_tk :: Strict.Maybe (PsLocated Token), -- last non-comment token
prev_loc :: PsSpan, -- pos of previous token, including comments,
@@ -2414,12 +2427,12 @@ thenP :: P a -> (a -> P b) -> P b
POk s1 a -> (unP (k a)) s1
PFailed s1 -> PFailed s1
-failMsgP :: (SrcSpan -> PsError) -> P a
+failMsgP :: (SrcSpan -> MsgEnvelope PsMessage) -> P a
failMsgP f = do
pState <- getPState
addFatalError (f (mkSrcSpanPs (last_loc pState)))
-failLocMsgP :: RealSrcLoc -> RealSrcLoc -> (SrcSpan -> PsError) -> P a
+failLocMsgP :: RealSrcLoc -> RealSrcLoc -> (SrcSpan -> MsgEnvelope PsMessage) -> P a
failLocMsgP loc1 loc2 f =
addFatalError (f (RealSrcSpan (mkRealSrcSpan loc1 loc2) Strict.Nothing))
@@ -2757,6 +2770,7 @@ data ExtBits
mkParserOpts
:: EnumSet WarningFlag -- ^ warnings flags enabled
-> EnumSet LangExt.Extension -- ^ permitted language extensions enabled
+ -> (SrcSpan -> PsMessage -> MsgEnvelope PsMessage) -- ^ How to construct diagnostics
-> Bool -- ^ are safe imports on?
-> Bool -- ^ keeping Haddock comment tokens
-> Bool -- ^ keep regular comment tokens
@@ -2768,11 +2782,12 @@ mkParserOpts
-> ParserOpts
-- ^ Given exactly the information needed, set up the 'ParserOpts'
-mkParserOpts warningFlags extensionFlags
+mkParserOpts warningFlags extensionFlags mkMessage
safeImports isHaddock rawTokStream usePosPrags =
ParserOpts {
- pWarningFlags = warningFlags
- , pExtsBitmap = safeHaskellBit .|. langExtBits .|. optBits
+ pWarningFlags = warningFlags
+ , pExtsBitmap = safeHaskellBit .|. langExtBits .|. optBits
+ , pMakePsMessage = mkMessage
}
where
safeHaskellBit = SafeHaskellBit `setBitIf` safeImports
@@ -2845,8 +2860,8 @@ initParserState options buf loc =
PState {
buffer = buf,
options = options,
- errors = emptyBag,
- warnings = emptyBag,
+ errors = emptyMessages,
+ warnings = emptyMessages,
tab_first = Strict.Nothing,
tab_count = 0,
last_tk = Strict.Nothing,
@@ -2893,15 +2908,15 @@ class Monad m => MonadP m where
-- to the accumulator and parsing continues. This allows GHC to report
-- more than one parse error per file.
--
- addError :: PsError -> m ()
+ addError :: MsgEnvelope PsMessage -> m ()
-- | Add a warning to the accumulator.
-- Use 'getMessages' to get the accumulated warnings.
- addWarning :: WarningFlag -> PsWarning -> m ()
+ addWarning :: MsgEnvelope PsMessage -> m ()
-- | Add a fatal error. This will be the last error reported by the parser, and
-- the parser will not produce any result, ending in a 'PFailed' state.
- addFatalError :: PsError -> m a
+ addFatalError :: MsgEnvelope PsMessage -> m a
-- | Check if a given flag is currently set in the bitmap.
getBit :: ExtBits -> m Bool
@@ -2917,12 +2932,13 @@ class Monad m => MonadP m where
instance MonadP P where
addError err
- = P $ \s -> POk s { errors = err `consBag` errors s} ()
+ = P $ \s -> POk s { errors = err `addMessage` errors s} ()
- addWarning option w
- = P $ \s -> if warnopt option (options s)
- then POk (s { warnings = w `consBag` warnings s }) ()
- else POk s ()
+ -- If the warning is meant to be suppressed, GHC will assign
+ -- a `SevIgnore` severity and the message will be discarded,
+ -- so we can simply add it no matter what.
+ addWarning w
+ = P $ \s -> POk (s { warnings = w `addMessage` warnings s }) ()
addFatalError err =
addError err >> P PFailed
@@ -2964,6 +2980,11 @@ getFinalCommentsFor _ = return emptyComments
getEofPos :: P (Strict.Maybe (Strict.Pair RealSrcSpan RealSrcSpan))
getEofPos = P $ \s@(PState { eof_pos = pos }) -> POk s pos
+addPsMessage :: SrcSpan -> PsMessage -> P ()
+addPsMessage srcspan msg = do
+ opts <- options <$> getPState
+ addWarning ((pMakePsMessage opts) srcspan msg)
+
addTabWarning :: RealSrcSpan -> P ()
addTabWarning srcspan
= P $ \s@PState{tab_first=tf, tab_count=tc, options=o} ->
@@ -2976,12 +2997,12 @@ addTabWarning srcspan
-- | Get a bag of the errors that have been accumulated so far.
-- Does not take -Werror into account.
-getErrorMessages :: PState -> Bag PsError
+getErrorMessages :: PState -> Messages PsMessage
getErrorMessages p = errors p
-- | Get the warnings and errors accumulated so far.
-- Does not take -Werror into account.
-getMessages :: PState -> (Bag PsWarning, Bag PsError)
+getMessages :: PState -> (Messages PsMessage, Messages PsMessage)
getMessages p =
let ws = warnings p
-- we add the tabulation warning on the fly because
@@ -2989,9 +3010,12 @@ getMessages p =
ws' = case tab_first p of
Strict.Nothing -> ws
Strict.Just tf ->
- PsWarnTab (RealSrcSpan tf Strict.Nothing) (tab_count p)
- `consBag` ws
+ let msg = mkMsg (RealSrcSpan tf Strict.Nothing) $
+ (PsWarnTab (tab_count p))
+ in msg `addMessage` ws
in (ws', errors p)
+ where
+ mkMsg = pMakePsMessage . options $ p
getContext :: P [LayoutContext]
getContext = P $ \s@PState{context=ctx} -> POk s ctx
@@ -3037,8 +3061,8 @@ srcParseErr
-> StringBuffer -- current buffer (placed just after the last token)
-> Int -- length of the previous token
-> SrcSpan
- -> PsError
-srcParseErr options buf len loc = PsError (PsErrParse token) suggests loc
+ -> MsgEnvelope PsMessage
+srcParseErr options buf len loc = mkPlainErrorMsgEnvelope loc (PsErrParse token details)
where
token = lexemeToString (offsetBytes (-len) buf) len
pattern_ = decodePrevNChars 8 buf
@@ -3047,16 +3071,13 @@ srcParseErr options buf len loc = PsError (PsErrParse token) suggests loc
mdoInLast100 = "mdo" `isInfixOf` last100
th_enabled = ThQuotesBit `xtest` pExtsBitmap options
ps_enabled = PatternSynonymsBit `xtest` pExtsBitmap options
-
- sug c s = if c then Just s else Nothing
- sug_th = sug (not th_enabled && token == "$") (SuggestExtension LangExt.TemplateHaskell) -- #7396
- sug_rdo = sug (token == "<-" && mdoInLast100) (SuggestExtension LangExt.RecursiveDo)
- sug_do = sug (token == "<-" && not mdoInLast100) SuggestMissingDo
- sug_let = sug (token == "=" && doInLast100) SuggestLetInDo -- #15849
- sug_pat = sug (not ps_enabled && pattern_ == "pattern ") (SuggestExtension LangExt.PatternSynonyms) -- #12429
- suggests
- | null token = []
- | otherwise = catMaybes [sug_th, sug_rdo, sug_do, sug_let, sug_pat]
+ details = PsErrParseDetails {
+ ped_th_enabled = th_enabled
+ , ped_do_in_last_100 = doInLast100
+ , ped_mdo_in_last_100 = mdoInLast100
+ , ped_pat_syn_enabled = ps_enabled
+ , ped_pattern_parsed = pattern_ == "pattern "
+ }
-- Report a parse failure, giving the span of the previous token as
-- the location of the error. This is the entry point for errors
@@ -3073,7 +3094,7 @@ lexError e = do
loc <- getRealSrcLoc
(AI end buf) <- getInput
reportLexError loc (psRealLoc end) buf
- (\k -> PsError (PsErrLexer e k) [])
+ (\k srcLoc -> mkPlainErrorMsgEnvelope srcLoc $ PsErrLexer e k)
-- -----------------------------------------------------------------------------
-- This is the top-level function: called from the parser each time a
@@ -3188,8 +3209,9 @@ alternativeLayoutRuleToken t
-- This next case is to handle a transitional issue:
(ITwhere, ALRLayout _ col : ls, _)
| newLine && thisCol == col && transitional ->
- do addWarning Opt_WarnAlternativeLayoutRuleTransitional
- $ PsWarnTransitionalLayout (mkSrcSpanPs thisLoc) TransLayout_Where
+ do addPsMessage
+ (mkSrcSpanPs thisLoc)
+ (PsWarnTransitionalLayout TransLayout_Where)
setALRContext ls
setNextToken t
-- Note that we use lastLoc, as we may need to close
@@ -3198,8 +3220,9 @@ alternativeLayoutRuleToken t
-- This next case is to handle a transitional issue:
(ITvbar, ALRLayout _ col : ls, _)
| newLine && thisCol == col && transitional ->
- do addWarning Opt_WarnAlternativeLayoutRuleTransitional
- $ PsWarnTransitionalLayout (mkSrcSpanPs thisLoc) TransLayout_Pipe
+ do addPsMessage
+ (mkSrcSpanPs thisLoc)
+ (PsWarnTransitionalLayout TransLayout_Pipe)
setALRContext ls
setNextToken t
-- Note that we use lastLoc, as we may need to close
@@ -3322,7 +3345,7 @@ lexToken = do
return (L span ITeof)
AlexError (AI loc2 buf) ->
reportLexError (psRealLoc loc1) (psRealLoc loc2) buf
- (\k -> PsError (PsErrLexer LexError k) [])
+ (\k srcLoc -> mkPlainErrorMsgEnvelope srcLoc $ PsErrLexer LexError k)
AlexSkip inp2 _ -> do
setInput inp2
lexToken
@@ -3336,7 +3359,11 @@ lexToken = do
if (isComment lt') then setLastComment lt else setLastTk lt
return lt
-reportLexError :: RealSrcLoc -> RealSrcLoc -> StringBuffer -> (LexErrKind -> SrcSpan -> PsError) -> P a
+reportLexError :: RealSrcLoc
+ -> RealSrcLoc
+ -> StringBuffer
+ -> (LexErrKind -> SrcSpan -> MsgEnvelope PsMessage)
+ -> P a
reportLexError loc1 loc2 buf f
| atEnd buf = failLocMsgP loc1 loc2 (f LexErrKind_EOF)
| otherwise =
diff --git a/compiler/GHC/Parser/PostProcess.hs b/compiler/GHC/Parser/PostProcess.hs
index 261967be85..e29a8314ff 100644
--- a/compiler/GHC/Parser/PostProcess.hs
+++ b/compiler/GHC/Parser/PostProcess.hs
@@ -58,7 +58,9 @@ module GHC.Parser.PostProcess (
checkPrecP, -- Int -> P Int
checkContext, -- HsType -> P HsContext
checkPattern, -- HsExp -> P HsPat
- checkPattern_hints,
+ checkPattern_details,
+ incompleteDoBlock,
+ ParseContext(..),
checkMonadComp, -- P (HsStmtContext GhcPs)
checkValDef, -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
checkValSigLhs,
@@ -119,12 +121,13 @@ import GHC.Types.Name.Reader
import GHC.Types.Name
import GHC.Unit.Module (ModuleName)
import GHC.Types.Basic
-import GHC.Types.Error ( GhcHint(..) )
+import GHC.Types.Error
import GHC.Types.Fixity
import GHC.Types.SourceText
import GHC.Parser.Types
import GHC.Parser.Lexer
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
+import GHC.Parser.Errors.Ppr ()
import GHC.Utils.Lexeme ( isLexCon )
import GHC.Types.TyThing
import GHC.Core.Type ( unrestrictedFunTyCon, Specificity(..) )
@@ -138,16 +141,14 @@ import GHC.Data.OrdList
import GHC.Utils.Outputable as Outputable
import GHC.Data.FastString
import GHC.Data.Maybe
-import GHC.Data.Bag
+import GHC.Utils.Error
import GHC.Utils.Misc
import Data.Either
import Data.List ( findIndex )
import Data.Foldable
-import GHC.Driver.Flags ( WarningFlag(..) )
import qualified Data.Semigroup as Semi
import GHC.Utils.Panic
import GHC.Utils.Panic.Plain
-import qualified GHC.LanguageExtensions as LangExt
import qualified GHC.Data.Strict as Strict
import Control.Monad
@@ -275,12 +276,14 @@ mkStandaloneKindSig loc lhs rhs anns =
check_lhs_name v@(unLoc->name) =
if isUnqual name && isTcOcc (rdrNameOcc name)
then return v
- else addFatalError $ PsError (PsErrUnexpectedQualifiedConstructor (unLoc v)) [] (getLocA v)
+ else addFatalError $ mkPlainErrorMsgEnvelope (getLocA v) $
+ (PsErrUnexpectedQualifiedConstructor (unLoc v))
check_singular_lhs vs =
case vs of
[] -> panic "mkStandaloneKindSig: empty left-hand side"
[v] -> return v
- _ -> addFatalError $ PsError (PsErrMultipleNamesInStandaloneKindSignature vs) [] (getLoc lhs)
+ _ -> addFatalError $ mkPlainErrorMsgEnvelope (getLoc lhs) $
+ (PsErrMultipleNamesInStandaloneKindSignature vs)
mkTyFamInstEqn :: SrcSpan
-> HsOuterFamEqnTyVarBndrs GhcPs
@@ -409,7 +412,8 @@ mkRoleAnnotDecl loc tycon roles anns
let nearby = fuzzyLookup (unpackFS role)
(mapFst unpackFS possible_roles)
in
- addFatalError $ PsError (PsErrIllegalRoleName role nearby) [] loc_role
+ addFatalError $ mkPlainErrorMsgEnvelope loc_role $
+ (PsErrIllegalRoleName role nearby)
-- | Converts a list of 'LHsTyVarBndr's annotated with their 'Specificity' to
-- binders without annotations. Only accepts specified variables, and errors if
@@ -429,7 +433,8 @@ fromSpecTyVarBndr bndr = case bndr of
where
check_spec :: Specificity -> SrcSpanAnnA -> P ()
check_spec SpecifiedSpec _ = return ()
- check_spec InferredSpec loc = addFatalError $ PsError PsErrInferredTypeVarNotAllowed [] (locA loc)
+ check_spec InferredSpec loc = addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
+ PsErrInferredTypeVarNotAllowed
-- | Add the annotation for a 'where' keyword to existing @HsLocalBinds@
annBinds :: AddEpAnn -> HsLocalBinds GhcPs -> HsLocalBinds GhcPs
@@ -508,7 +513,7 @@ cvBindsAndSigs fb = do
-- called on top-level declarations.
drop_bad_decls [] = return []
drop_bad_decls (L l (SpliceD _ d) : ds) = do
- addError $ PsError (PsErrDeclSpliceNotAtTopLevel d) [] (locA l)
+ addError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrDeclSpliceNotAtTopLevel d
drop_bad_decls ds
drop_bad_decls (d:ds) = (d:) <$> drop_bad_decls ds
@@ -618,14 +623,14 @@ constructor, a type, or a context, we would need unlimited lookahead which
-- | Reinterpret a type constructor, including type operators, as a data
-- constructor.
-- See Note [Parsing data constructors is hard]
-tyConToDataCon :: LocatedN RdrName -> Either PsError (LocatedN RdrName)
+tyConToDataCon :: LocatedN RdrName -> Either (MsgEnvelope PsMessage) (LocatedN RdrName)
tyConToDataCon (L loc tc)
| isTcOcc occ || isDataOcc occ
, isLexCon (occNameFS occ)
= return (L loc (setRdrNameSpace tc srcDataName))
| otherwise
- = Left $ PsError (PsErrNotADataCon tc) [] (locA loc)
+ = Left $ mkPlainErrorMsgEnvelope (locA loc) $ (PsErrNotADataCon tc)
where
occ = rdrNameOcc tc
@@ -666,17 +671,21 @@ mkPatSynMatchGroup (L loc patsyn_name) (L ld decls) =
fromDecl (L loc decl) = extraDeclErr (locA loc) decl
extraDeclErr loc decl =
- addFatalError $ PsError (PsErrNoSingleWhereBindInPatSynDecl patsyn_name decl) [] loc
+ addFatalError $ mkPlainErrorMsgEnvelope loc $
+ (PsErrNoSingleWhereBindInPatSynDecl patsyn_name decl)
wrongNameBindingErr loc decl =
- addFatalError $ PsError (PsErrInvalidWhereBindInPatSynDecl patsyn_name decl) [] loc
+ addFatalError $ mkPlainErrorMsgEnvelope loc $
+ (PsErrInvalidWhereBindInPatSynDecl patsyn_name decl)
wrongNumberErr loc =
- addFatalError $ PsError (PsErrEmptyWhereInPatSynDecl patsyn_name) [] loc
+ addFatalError $ mkPlainErrorMsgEnvelope loc $
+ (PsErrEmptyWhereInPatSynDecl patsyn_name)
recordPatSynErr :: SrcSpan -> LPat GhcPs -> P a
recordPatSynErr loc pat =
- addFatalError $ PsError (PsErrRecordSyntaxInPatSynDecl pat) [] loc
+ addFatalError $ mkPlainErrorMsgEnvelope loc $
+ (PsErrRecordSyntaxInPatSynDecl pat)
mkConDeclH98 :: EpAnn [AddEpAnn] -> LocatedN RdrName -> Maybe [LHsTyVarBndr Specificity GhcPs]
-> Maybe (LHsContext GhcPs) -> HsConDeclH98Details GhcPs
@@ -817,7 +826,7 @@ to make setRdrNameSpace partial, so we just make an Unqual name instead. It
really doesn't matter!
-}
-eitherToP :: MonadP m => Either PsError a -> m a
+eitherToP :: MonadP m => Either (MsgEnvelope PsMessage) a -> m a
-- Adapts the Either monad to the P monad
eitherToP (Left err) = addFatalError err
eitherToP (Right thing) = return thing
@@ -831,9 +840,11 @@ checkTyVars pp_what equals_or_where tc tparms
= do { (tvs, anns) <- fmap unzip $ mapM check tparms
; return (mkHsQTvs tvs, concat anns) }
where
- check (HsTypeArg _ ki@(L loc _)) = addFatalError $ PsError (PsErrUnexpectedTypeAppInDecl ki pp_what (unLoc tc)) [] (locA loc)
+ check (HsTypeArg _ ki@(L loc _)) = addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
+ (PsErrUnexpectedTypeAppInDecl ki pp_what (unLoc tc))
check (HsValArg ty) = chkParens [] emptyComments ty
- check (HsArgPar sp) = addFatalError $ PsError (PsErrMalformedDecl pp_what (unLoc tc)) [] sp
+ check (HsArgPar sp) = addFatalError $ mkPlainErrorMsgEnvelope sp $
+ (PsErrMalformedDecl pp_what (unLoc tc))
-- Keep around an action for adjusting the annotations of extra parens
chkParens :: [AddEpAnn] -> EpAnnComments -> LHsType GhcPs
-> P (LHsTyVarBndr () GhcPs, [AddEpAnn])
@@ -853,7 +864,8 @@ checkTyVars pp_what equals_or_where tc tparms
| isRdrTyVar tv = return (L (widenLocatedAn l an)
(UserTyVar (addAnns ann an cs) () (L ltv tv)))
chk _ _ t@(L loc _)
- = addFatalError $ PsError (PsErrUnexpectedTypeInDecl t pp_what (unLoc tc) tparms equals_or_where) [] (locA loc)
+ = addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
+ (PsErrUnexpectedTypeInDecl t pp_what (unLoc tc) tparms equals_or_where)
whereDots, equalsDots :: SDoc
@@ -865,7 +877,8 @@ checkDatatypeContext :: Maybe (LHsContext GhcPs) -> P ()
checkDatatypeContext Nothing = return ()
checkDatatypeContext (Just c)
= do allowed <- getBit DatatypeContextsBit
- unless allowed $ addError $ PsError (PsErrIllegalDataTypeContext c) [] (getLocA c)
+ unless allowed $ addError $ mkPlainErrorMsgEnvelope (getLocA c) $
+ (PsErrIllegalDataTypeContext c)
type LRuleTyTmVar = Located RuleTyTmVar
data RuleTyTmVar = RuleTyTmVar (EpAnn [AddEpAnn]) (LocatedN RdrName) (Maybe (LHsType GhcPs))
@@ -895,13 +908,15 @@ checkRuleTyVarBndrNames = mapM_ (check . fmap hsTyVarName)
where check (L loc (Unqual occ)) =
-- TODO: don't use string here, OccName has a Unique/FastString
when ((occNameString occ ==) `any` ["forall","family","role"])
- (addFatalError $ PsError (PsErrParseErrorOnInput occ) [] (locA loc))
+ (addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
+ (PsErrParseErrorOnInput occ))
check _ = panic "checkRuleTyVarBndrNames"
checkRecordSyntax :: (MonadP m, Outputable a) => LocatedA a -> m (LocatedA a)
checkRecordSyntax lr@(L loc r)
= do allowed <- getBit TraditionalRecordSyntaxBit
- unless allowed $ addError $ PsError (PsErrIllegalTraditionalRecordSyntax (ppr r)) [] (locA loc)
+ unless allowed $ addError $ mkPlainErrorMsgEnvelope (locA loc) $
+ (PsErrIllegalTraditionalRecordSyntax (ppr r))
return lr
-- | Check if the gadt_constrlist is empty. Only raise parse error for
@@ -910,7 +925,8 @@ checkEmptyGADTs :: Located ([AddEpAnn], [LConDecl GhcPs])
-> P (Located ([AddEpAnn], [LConDecl GhcPs]))
checkEmptyGADTs gadts@(L span (_, [])) -- Empty GADT declaration.
= do gadtSyntax <- getBit GadtSyntaxBit -- GADTs implies GADTSyntax
- unless gadtSyntax $ addError $ PsError PsErrIllegalWhereInDataDecl [] span
+ unless gadtSyntax $ addError $ mkPlainErrorMsgEnvelope span $
+ PsErrIllegalWhereInDataDecl
return gadts
checkEmptyGADTs gadts = return gadts -- Ordinary GADT declaration.
@@ -933,7 +949,7 @@ checkTyClHdr is_cls ty
-- workaround to define '*' despite StarIsType
go _ (HsParTy an (L l (HsStarTy _ isUni))) acc ann' fix
- = do { addWarning Opt_WarnStarBinder (PsWarnStarBinder (locA l))
+ = do { addPsMessage (locA l) PsWarnStarBinder
; let name = mkOccName tcClsName (starSym isUni)
; let a' = newAnns l an
; return (L a' (Unqual name), acc, fix
@@ -955,7 +971,8 @@ checkTyClHdr is_cls ty
| otherwise = getName (tupleTyCon Boxed arity)
-- See Note [Unit tuples] in GHC.Hs.Type (TODO: is this still relevant?)
go l _ _ _ _
- = addFatalError $ PsError (PsErrMalformedTyOrClDecl ty) [] l
+ = addFatalError $ mkPlainErrorMsgEnvelope l $
+ (PsErrMalformedTyOrClDecl ty)
-- Combine the annotations from the HsParTy and HsStarTy into a
-- new one for the LocatedN RdrName
@@ -1003,7 +1020,7 @@ checkCmdBlockArguments :: LHsCmd GhcPs -> PV ()
check err a = do
blockArguments <- getBit BlockArgumentsBit
unless blockArguments $
- addError $ PsError (err a) [] (getLocA a)
+ addError $ mkPlainErrorMsgEnvelope (getLocA a) $ (err a)
-- | Validate the context constraints and break up a context into a list
-- of predicates.
@@ -1077,8 +1094,8 @@ checkImportDecl mPre mPost = do
checkPattern :: LocatedA (PatBuilder GhcPs) -> P (LPat GhcPs)
checkPattern = runPV . checkLPat
-checkPattern_hints :: [GhcHint] -> PV (LocatedA (PatBuilder GhcPs)) -> P (LPat GhcPs)
-checkPattern_hints hints pp = runPV_hints hints (pp >>= checkLPat)
+checkPattern_details :: ParseContext -> PV (LocatedA (PatBuilder GhcPs)) -> P (LPat GhcPs)
+checkPattern_details extraDetails pp = runPV_details extraDetails (pp >>= checkLPat)
checkLPat :: LocatedA (PatBuilder GhcPs) -> PV (LPat GhcPs)
checkLPat e@(L l _) = checkPat l e [] []
@@ -1092,11 +1109,10 @@ checkPat loc (L l e@(PatBuilderVar (L ln c))) tyargs args
, pat_args = PrefixCon tyargs args
}
| not (null tyargs) =
- add_hint TypeApplicationsInPatternsOnlyDataCons $
- patFail (locA l) (ppr e <+> hsep [text "@" <> ppr t | t <- tyargs])
- | not (null args) && patIsRec c =
- add_hint (SuggestExtension LangExt.RecursiveDo) $
- patFail (locA l) (ppr e)
+ patFail (locA l) . PsErrInPat e $ PEIP_TypeArgs tyargs
+ | (not (null args) && patIsRec c) = do
+ ctx <- askParseContext
+ patFail (locA l) . PsErrInPat e $ PEIP_RecPattern args YesPatIsRecursive ctx
checkPat loc (L _ (PatBuilderAppType f t)) tyargs args =
checkPat loc f (t : tyargs) args
checkPat loc (L _ (PatBuilderApp f e)) [] args = do
@@ -1105,7 +1121,9 @@ checkPat loc (L _ (PatBuilderApp f e)) [] args = do
checkPat loc (L l e) [] [] = do
p <- checkAPat loc e
return (L l p)
-checkPat loc e _ _ = patFail (locA loc) (ppr e)
+checkPat loc e _ _ = do
+ details <- fromParseContext <$> askParseContext
+ patFail (locA loc) (PsErrInPat (unLoc e) details)
checkAPat :: SrcSpanAnnA -> PatBuilder GhcPs -> PV (Pat GhcPs)
checkAPat loc e0 = do
@@ -1130,7 +1148,7 @@ checkAPat loc e0 = do
-- Improve error messages for the @-operator when the user meant an @-pattern
PatBuilderOpApp _ op _ _ | opIsAt (unLoc op) -> do
- addError $ PsError PsErrAtInPatPos [] (getLocA op)
+ addError $ mkPlainErrorMsgEnvelope (getLocA op) PsErrAtInPatPos
return (WildPat noExtField)
PatBuilderOpApp l (L cl c) r anns
@@ -1147,7 +1165,9 @@ checkAPat loc e0 = do
p <- checkLPat e
return (ParPat (EpAnn (spanAsAnchor (locA loc)) NoEpAnns emptyComments) lpar p rpar)
- _ -> patFail (locA loc) (ppr e0)
+ _ -> do
+ details <- fromParseContext <$> askParseContext
+ patFail (locA loc) (PsErrInPat e0 details)
placeHolderPunRhs :: DisambECP b => PV (LocatedA b)
-- The RHS of a punned record field will be filled in by the renamer
@@ -1164,8 +1184,8 @@ checkPatField :: LHsRecField GhcPs (LocatedA (PatBuilder GhcPs))
checkPatField (L l fld) = do p <- checkLPat (hfbRHS fld)
return (L l (fld { hfbRHS = p }))
-patFail :: SrcSpan -> SDoc -> PV a
-patFail loc e = addFatalError $ PsError (PsErrParseErrorInPat e) [] loc
+patFail :: SrcSpan -> PsMessage -> PV a
+patFail loc msg = addFatalError $ mkPlainErrorMsgEnvelope loc $ msg
patIsRec :: RdrName -> Bool
patIsRec e = e == mkUnqual varName (fsLit "rec")
@@ -1204,7 +1224,7 @@ checkFunBind :: SrcStrictness
-> Located (GRHSs GhcPs (LHsExpr GhcPs))
-> P (HsBind GhcPs)
checkFunBind strictness locF ann fun is_infix pats (L _ grhss)
- = do ps <- runPV_hints param_hints (mapM checkLPat pats)
+ = do ps <- runPV_details extraDetails (mapM checkLPat pats)
let match_span = noAnnSrcSpan $ locF
cs <- getCommentsFor locF
return (makeFunBind fun (L (noAnnSrcSpan $ locA match_span)
@@ -1218,9 +1238,9 @@ checkFunBind strictness locF ann fun is_infix pats (L _ grhss)
-- The span of the match covers the entire equation.
-- That isn't quite right, but it'll do for now.
where
- param_hints
- | Infix <- is_infix = [SuggestInfixBindMaybeAtPat (unLoc fun)]
- | otherwise = []
+ extraDetails
+ | Infix <- is_infix = ParseContext (Just $ unLoc fun) NoIncompleteDoBlock
+ | otherwise = noParseContext
makeFunBind :: LocatedN RdrName -> LocatedL [LMatch GhcPs (LHsExpr GhcPs)]
-> HsBind GhcPs
@@ -1260,11 +1280,11 @@ checkValSigLhs (L _ (HsVar _ lrdr@(L _ v)))
= return lrdr
checkValSigLhs lhs@(L l _)
- = addFatalError $ PsError (PsErrInvalidTypeSignature lhs) [] (locA l)
+ = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrInvalidTypeSignature lhs
checkDoAndIfThenElse
:: (Outputable a, Outputable b, Outputable c)
- => (a -> Bool -> b -> Bool -> c -> PsErrorDesc)
+ => (a -> Bool -> b -> Bool -> c -> PsMessage)
-> LocatedA a -> Bool -> LocatedA b -> Bool -> LocatedA c -> PV ()
checkDoAndIfThenElse err guardExpr semiThen thenExpr semiElse elseExpr
| semiThen || semiElse = do
@@ -1274,7 +1294,7 @@ checkDoAndIfThenElse err guardExpr semiThen thenExpr semiElse elseExpr
semiElse (unLoc elseExpr)
loc = combineLocs (reLoc guardExpr) (reLoc elseExpr)
- unless doAndIfThenElse $ addError (PsError e [] loc)
+ unless doAndIfThenElse $ addError (mkPlainErrorMsgEnvelope loc e)
| otherwise = return ()
isFunLhs :: LocatedA (PatBuilder GhcPs)
@@ -1390,7 +1410,7 @@ instance DisambInfixOp (HsExpr GhcPs) where
instance DisambInfixOp RdrName where
mkHsConOpPV (L l v) = return $ L l v
mkHsVarOpPV (L l v) = return $ L l v
- mkHsInfixHolePV l _ = addFatalError $ PsError PsErrInvalidInfixHole [] l
+ mkHsInfixHolePV l _ = addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrInvalidInfixHole
type AnnoBody b
= ( Anno (GRHS GhcPs (LocatedA (Body b GhcPs))) ~ SrcSpan
@@ -1554,7 +1574,8 @@ instance DisambECP (HsCmd GhcPs) where
type Body (HsCmd GhcPs) = HsCmd
ecpFromCmd' = return
ecpFromExp' (L l e) = cmdFail (locA l) (ppr e)
- mkHsProjUpdatePV l _ _ _ _ = addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
+ mkHsProjUpdatePV l _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l $
+ PsErrOverloadedRecordDotInvalid
mkHsLamPV l mg = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdLam NoExtField (mg cs))
@@ -1590,7 +1611,7 @@ instance DisambECP (HsCmd GhcPs) where
mkHsDoPV l Nothing stmts anns = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdDo (EpAnn (spanAsAnchor l) anns cs) stmts)
- mkHsDoPV l (Just m) _ _ = addFatalError $ PsError (PsErrQualifiedDoInCmd m) [] l
+ mkHsDoPV l (Just m) _ _ = addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrQualifiedDoInCmd m
mkHsParPV l lpar c rpar = do
cs <- getCommentsFor l
return $ L (noAnnSrcSpan l) (HsCmdPar (EpAnn (spanAsAnchor l) NoEpAnns cs) lpar c rpar)
@@ -1605,7 +1626,7 @@ instance DisambECP (HsCmd GhcPs) where
mkHsRecordPV _ l _ a (fbinds, ddLoc) _ = do
let (fs, ps) = partitionEithers fbinds
if not (null ps)
- then addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
+ then addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrOverloadedRecordDotInvalid
else cmdFail l $ ppr a <+> ppr (mk_rec_fields fs ddLoc)
mkHsNegAppPV l a _ = cmdFail l (text "-" <> ppr a)
mkHsSectionR_PV l op c = cmdFail l $
@@ -1624,17 +1645,17 @@ instance DisambECP (HsCmd GhcPs) where
rejectPragmaPV _ = return ()
cmdFail :: SrcSpan -> SDoc -> PV a
-cmdFail loc e = addFatalError $ PsError (PsErrParseErrorInCmd e) [] loc
+cmdFail loc e = addFatalError $ mkPlainErrorMsgEnvelope loc $ PsErrParseErrorInCmd e
checkLamMatchGroup :: SrcSpan -> MatchGroup GhcPs (LHsExpr GhcPs) -> PV ()
checkLamMatchGroup l (MG { mg_alts = (L _ (matches:_))}) = do
- when (null (hsLMatchPats matches)) $ addError $ PsError PsErrEmptyLambda [] l
+ when (null (hsLMatchPats matches)) $ addError $ mkPlainErrorMsgEnvelope l PsErrEmptyLambda
checkLamMatchGroup _ _ = return ()
instance DisambECP (HsExpr GhcPs) where
type Body (HsExpr GhcPs) = HsExpr
ecpFromCmd' (L l c) = do
- addError $ PsError (PsErrArrowCmdInExpr c) [] (locA l)
+ addError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrArrowCmdInExpr c
return (L l (hsHoleExpr noAnn))
ecpFromExp' = return
mkHsProjUpdatePV l fields arg isPun anns = do
@@ -1708,19 +1729,20 @@ instance DisambECP (HsExpr GhcPs) where
mkHsSectionR_PV l op e = do
cs <- getCommentsFor l
return $ L l (SectionR (comment (realSrcSpan l) cs) op e)
- mkHsViewPatPV l a b _ = addError (PsError (PsErrViewPatInExpr a b) [] l)
+ mkHsViewPatPV l a b _ = addError (mkPlainErrorMsgEnvelope l $ PsErrViewPatInExpr a b)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
- mkHsAsPatPV l v e _ = addError (PsError (PsErrTypeAppWithoutSpace (unLoc v) e) [] l)
+ mkHsAsPatPV l v e _ = addError (mkPlainErrorMsgEnvelope l $ PsErrTypeAppWithoutSpace (unLoc v) e)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
- mkHsLazyPatPV l e _ = addError (PsError (PsErrLazyPatWithoutSpace e) [] l)
+ mkHsLazyPatPV l e _ = addError (mkPlainErrorMsgEnvelope l $ PsErrLazyPatWithoutSpace e)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
- mkHsBangPatPV l e _ = addError (PsError (PsErrBangPatWithoutSpace e) [] l)
+ mkHsBangPatPV l e _ = addError (mkPlainErrorMsgEnvelope l $ PsErrBangPatWithoutSpace e)
>> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn))
mkSumOrTuplePV = mkSumOrTupleExpr
rejectPragmaPV (L _ (OpApp _ _ _ e)) =
-- assuming left-associative parsing of operators
rejectPragmaPV e
- rejectPragmaPV (L l (HsPragE _ prag _)) = addError $ PsError (PsErrUnallowedPragma prag) [] (locA l)
+ rejectPragmaPV (L l (HsPragE _ prag _)) = addError $ mkPlainErrorMsgEnvelope (locA l) $
+ (PsErrUnallowedPragma prag)
rejectPragmaPV _ = return ()
hsHoleExpr :: EpAnn EpAnnUnboundVar -> HsExpr GhcPs
@@ -1733,19 +1755,19 @@ type instance Anno (StmtLR GhcPs GhcPs (LocatedA (PatBuilder GhcPs))) = SrcSpanA
instance DisambECP (PatBuilder GhcPs) where
type Body (PatBuilder GhcPs) = PatBuilder
- ecpFromCmd' (L l c) = addFatalError $ PsError (PsErrArrowCmdInPat c) [] (locA l)
- ecpFromExp' (L l e) = addFatalError $ PsError (PsErrArrowExprInPat e) [] (locA l)
- mkHsLamPV l _ = addFatalError $ PsError PsErrLambdaInPat [] l
- mkHsLetPV l _ _ _ = addFatalError $ PsError PsErrLetInPat [] l
- mkHsProjUpdatePV l _ _ _ _ = addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
+ ecpFromCmd' (L l c) = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrArrowCmdInPat c
+ ecpFromExp' (L l e) = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrArrowExprInPat e
+ mkHsLamPV l _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrLambdaInPat
+ mkHsLetPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrLetInPat
+ mkHsProjUpdatePV l _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrOverloadedRecordDotInvalid
type InfixOp (PatBuilder GhcPs) = RdrName
superInfixOp m = m
mkHsOpAppPV l p1 op p2 = do
cs <- getCommentsFor l
let anns = EpAnn (spanAsAnchor l) [] cs
return $ L (noAnnSrcSpan l) $ PatBuilderOpApp p1 op p2 anns
- mkHsCasePV l _ _ _ = addFatalError $ PsError PsErrCaseInPat [] l
- mkHsLamCasePV l _ _ = addFatalError $ PsError PsErrLambdaCaseInPat [] l
+ mkHsCasePV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrCaseInPat
+ mkHsLamCasePV l _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrLambdaCaseInPat
type FunArg (PatBuilder GhcPs) = PatBuilder GhcPs
superFunArg m = m
mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2)
@@ -1753,8 +1775,8 @@ instance DisambECP (PatBuilder GhcPs) where
cs <- getCommentsFor (locA l)
let anns = EpAnn (spanAsAnchor (combineSrcSpans la (getLocA t))) (EpaSpan (realSrcSpan la)) cs
return $ L l (PatBuilderAppType p (mkHsPatSigType anns t))
- mkHsIfPV l _ _ _ _ _ _ = addFatalError $ PsError PsErrIfTheElseInPat [] l
- mkHsDoPV l _ _ _ = addFatalError $ PsError PsErrDoNotationInPat [] l
+ mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat
+ mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat
mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar)
mkHsVarPV v@(getLoc -> l) = return $ L (na2la l) (PatBuilderVar v)
mkHsLitPV lit@(L l a) = do
@@ -1774,7 +1796,7 @@ instance DisambECP (PatBuilder GhcPs) where
mkHsRecordPV _ l _ a (fbinds, ddLoc) anns = do
let (fs, ps) = partitionEithers fbinds
if not (null ps)
- then addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] l
+ then addFatalError $ mkPlainErrorMsgEnvelope l PsErrOverloadedRecordDotInvalid
else do
cs <- getCommentsFor l
r <- mkPatRec a (mk_rec_fields fs ddLoc) (EpAnn (spanAsAnchor l) anns cs)
@@ -1782,11 +1804,11 @@ instance DisambECP (PatBuilder GhcPs) where
mkHsNegAppPV l (L lp p) anns = do
lit <- case p of
PatBuilderOverLit pos_lit -> return (L (locA lp) pos_lit)
- _ -> patFail l (text "-" <> ppr p)
+ _ -> patFail l $ PsErrInPat p PEIP_NegApp
cs <- getCommentsFor l
let an = EpAnn (spanAsAnchor l) anns cs
return $ L (noAnnSrcSpan l) (PatBuilderPat (mkNPat lit (Just noSyntaxExpr) an))
- mkHsSectionR_PV l op p = patFail l (pprInfixOcc (unLoc op) <> ppr p)
+ mkHsSectionR_PV l op p = patFail l (PsErrParseRightOpSectionInPat (unLoc op) (unLoc p))
mkHsViewPatPV l a b anns = do
p <- checkLPat b
cs <- getCommentsFor l
@@ -1812,7 +1834,8 @@ checkUnboxedStringLitPat :: Located (HsLit GhcPs) -> PV ()
checkUnboxedStringLitPat (L loc lit) =
case lit of
HsStringPrim _ _ -- Trac #13260
- -> addFatalError $ PsError (PsErrIllegalUnboxedStringInPat lit) [] loc
+ -> addFatalError $ mkPlainErrorMsgEnvelope loc $
+ (PsErrIllegalUnboxedStringInPat lit)
_ -> return ()
mkPatRec ::
@@ -1829,7 +1852,8 @@ mkPatRec (unLoc -> PatBuilderVar c) (HsRecFields fs dd) anns
, pat_args = RecCon (HsRecFields fs dd)
}
mkPatRec p _ _ =
- addFatalError $ PsError (PsErrInvalidRecordCon (unLoc p)) [] (getLocA p)
+ addFatalError $ mkPlainErrorMsgEnvelope (getLocA p) $
+ (PsErrInvalidRecordCon (unLoc p))
-- | Disambiguate constructs that may appear when we do not know
-- ahead of time whether we are parsing a type or a newtype/data constructor.
@@ -1892,7 +1916,8 @@ instance DisambTD DataConBuilder where
panic "mkHsAppTyPV: InfixDataConBuilder"
mkHsAppKindTyPV lhs l_at ki =
- addFatalError $ PsError (PsErrUnexpectedKindAppInDataCon (unLoc lhs) (unLoc ki)) [] l_at
+ addFatalError $ mkPlainErrorMsgEnvelope l_at $
+ (PsErrUnexpectedKindAppInDataCon (unLoc lhs) (unLoc ki))
mkHsOpTyPV lhs tc rhs = do
check_no_ops (unLoc rhs) -- check the RHS because parsing type operators is right-associative
@@ -1902,7 +1927,8 @@ instance DisambTD DataConBuilder where
l = combineLocsA lhs rhs
check_no_ops (HsBangTy _ _ t) = check_no_ops (unLoc t)
check_no_ops (HsOpTy{}) =
- addError $ PsError (PsErrInvalidInfixDataCon (unLoc lhs) (unLoc tc) (unLoc rhs)) [] (locA l)
+ addError $ mkPlainErrorMsgEnvelope (locA l) $
+ (PsErrInvalidInfixDataCon (unLoc lhs) (unLoc tc) (unLoc rhs))
check_no_ops _ = return ()
mkUnpackednessPV unpk constr_stuff
@@ -1913,7 +1939,7 @@ instance DisambTD DataConBuilder where
let l = combineLocsA (reLocA unpk) constr_stuff
return $ L l (InfixDataConBuilder lhs' data_con rhs)
| otherwise =
- do addError $ PsError PsErrUnpackDataCon [] (getLoc unpk)
+ do addError $ mkPlainErrorMsgEnvelope (getLoc unpk) PsErrUnpackDataCon
return constr_stuff
tyToDataConBuilder :: LHsType GhcPs -> PV (LocatedA DataConBuilder)
@@ -1924,7 +1950,8 @@ tyToDataConBuilder (L l (HsTupleTy _ HsBoxedOrConstraintTuple ts)) = do
let data_con = L (l2l l) (getRdrName (tupleDataCon Boxed (length ts)))
return $ L l (PrefixDataConBuilder (toOL ts) data_con)
tyToDataConBuilder t =
- addFatalError $ PsError (PsErrInvalidDataCon (unLoc t)) [] (getLocA t)
+ addFatalError $ mkPlainErrorMsgEnvelope (getLocA t) $
+ (PsErrInvalidDataCon (unLoc t))
{- Note [Ambiguous syntactic categories]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2373,7 +2400,7 @@ checkPrecP
checkPrecP (L l (_,i)) (L _ ol)
| 0 <= i, i <= maxPrecedence = pure ()
| all specialOp ol = pure ()
- | otherwise = addFatalError $ PsError (PsErrPrecedenceOutOfRange i) [] l
+ | otherwise = addFatalError $ mkPlainErrorMsgEnvelope l (PsErrPrecedenceOutOfRange i)
where
-- If you change this, consider updating Note [Fixity of (->)] in GHC/Types.hs
specialOp op = unLoc op `elem` [ eqTyCon_RDR
@@ -2391,10 +2418,12 @@ mkRecConstrOrUpdate _ (L _ (HsVar _ (L l c))) _lrec (fbinds,dd) anns
= do
let (fs, ps) = partitionEithers fbinds
if not (null ps)
- then addFatalError $ PsError PsErrOverloadedRecordDotInvalid [] (getLocA (head ps))
+ then addFatalError $ mkPlainErrorMsgEnvelope (getLocA (head ps)) $
+ PsErrOverloadedRecordDotInvalid
else return (mkRdrRecordCon (L l c) (mk_rec_fields fs dd) anns)
mkRecConstrOrUpdate overloaded_update exp _ (fs,dd) anns
- | Just dd_loc <- dd = addFatalError $ PsError PsErrDotsInRecordUpdate [] dd_loc
+ | Just dd_loc <- dd = addFatalError $ mkPlainErrorMsgEnvelope dd_loc $
+ PsErrDotsInRecordUpdate
| otherwise = mkRdrRecordUpd overloaded_update exp fs anns
mkRdrRecordUpd :: Bool -> LHsExpr GhcPs -> [Fbind (HsExpr GhcPs)] -> EpAnn [AddEpAnn] -> PV (HsExpr GhcPs)
@@ -2408,7 +2437,7 @@ mkRdrRecordUpd overloaded_on exp@(L loc _) fbinds anns = do
case overloaded_on of
False | not $ null ps ->
-- A '.' was found in an update and OverloadedRecordUpdate isn't on.
- addFatalError $ PsError PsErrOverloadedRecordUpdateNotEnabled [] (locA loc)
+ addFatalError $ mkPlainErrorMsgEnvelope (locA loc) PsErrOverloadedRecordUpdateNotEnabled
False ->
-- This is just a regular record update.
return RecordUpd {
@@ -2422,7 +2451,8 @@ mkRdrRecordUpd overloaded_on exp@(L loc _) fbinds anns = do
]
if not $ null qualifiedFields
then
- addFatalError $ PsError PsErrOverloadedRecordUpdateNoQualifiedFields [] (getLoc (head qualifiedFields))
+ addFatalError $ mkPlainErrorMsgEnvelope (getLoc (head qualifiedFields)) $
+ PsErrOverloadedRecordUpdateNoQualifiedFields
else -- This is a RecordDotSyntax update.
return RecordUpd {
rupd_ext = anns
@@ -2505,7 +2535,8 @@ mkImport cconv safety (L loc (StringLiteral esrc entity _), v, ty) =
mkCImport = do
let e = unpackFS entity
case parseCImport cconv safety (mkExtName (unLoc v)) e (L loc esrc) of
- Nothing -> addFatalError $ PsError PsErrMalformedEntityString [] loc
+ Nothing -> addFatalError $ mkPlainErrorMsgEnvelope loc $
+ PsErrMalformedEntityString
Just importSpec -> returnSpec importSpec
-- currently, all the other import conventions only support a symbol name in
@@ -2646,12 +2677,14 @@ mkModuleImpExp anns (L l specname) subs = do
in (\newName
-> IEThingWith ann (L l newName) pos ies)
<$> nameT
- else addFatalError $ PsError PsErrIllegalPatSynExport [] (locA l)
+ else addFatalError $ mkPlainErrorMsgEnvelope (locA l) $
+ PsErrIllegalPatSynExport
where
name = ieNameVal specname
nameT =
if isVarNameSpace (rdrNameSpace name)
- then addFatalError $ PsError (PsErrVarForTyCon name) [] (locA l)
+ then addFatalError $ mkPlainErrorMsgEnvelope (locA l) $
+ (PsErrVarForTyCon name)
else return $ ieNameFromSpec specname
ieNameVal (ImpExpQcName ln) = unLoc ln
@@ -2668,7 +2701,8 @@ mkTypeImpExp :: LocatedN RdrName -- TcCls or Var name space
-> P (LocatedN RdrName)
mkTypeImpExp name =
do allowed <- getBit ExplicitNamespacesBit
- unless allowed $ addError $ PsError PsErrIllegalExplicitNamespace [] (getLocA name)
+ unless allowed $ addError $ mkPlainErrorMsgEnvelope (getLocA name) $
+ PsErrIllegalExplicitNamespace
return (fmap (`setRdrNameSpace` tcClsName) name)
checkImportSpec :: LocatedL [LIE GhcPs] -> P (LocatedL [LIE GhcPs])
@@ -2678,7 +2712,7 @@ checkImportSpec ie@(L _ specs) =
(l:_) -> importSpecError (locA l)
where
importSpecError l =
- addFatalError $ PsError PsErrIllegalImportBundleForm [] l
+ addFatalError $ mkPlainErrorMsgEnvelope l PsErrIllegalImportBundleForm
-- In the correct order
mkImpExpSubSpec :: [LocatedA ImpExpQcSpec] -> P ([AddEpAnn], ImpExpSubSpec)
@@ -2699,21 +2733,24 @@ isImpExpQcWildcard _ = False
warnPrepositiveQualifiedModule :: SrcSpan -> P ()
warnPrepositiveQualifiedModule span =
- addWarning Opt_WarnPrepositiveQualifiedModule (PsWarnImportPreQualified span)
+ addPsMessage span PsWarnImportPreQualified
failOpNotEnabledImportQualifiedPost :: SrcSpan -> P ()
-failOpNotEnabledImportQualifiedPost loc = addError $ PsError PsErrImportPostQualified [] loc
+failOpNotEnabledImportQualifiedPost loc =
+ addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified
failOpImportQualifiedTwice :: SrcSpan -> P ()
-failOpImportQualifiedTwice loc = addError $ PsError PsErrImportQualifiedTwice [] loc
+failOpImportQualifiedTwice loc =
+ addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice
warnStarIsType :: SrcSpan -> P ()
-warnStarIsType span = addWarning Opt_WarnStarIsType (PsWarnStarIsType span)
+warnStarIsType span = addPsMessage span PsWarnStarIsType
failOpFewArgs :: MonadP m => LocatedN RdrName -> m a
failOpFewArgs (L loc op) =
do { star_is_type <- getBit StarIsTypeBit
- ; addFatalError $ PsError (PsErrOpFewArgs (StarIsType star_is_type) op) [] (locA loc) }
+ ; addFatalError $ mkPlainErrorMsgEnvelope (locA loc) $
+ (PsErrOpFewArgs (StarIsType star_is_type) op) }
-----------------------------------------------------------------------------
-- Misc utils
@@ -2721,13 +2758,13 @@ failOpFewArgs (L loc op) =
data PV_Context =
PV_Context
{ pv_options :: ParserOpts
- , pv_hints :: [GhcHint] -- See Note [Parser-Validator Hint]
+ , pv_details :: ParseContext -- See Note [Parser-Validator Details]
}
data PV_Accum =
PV_Accum
- { pv_warnings :: Bag PsWarning
- , pv_errors :: Bag PsError
+ { pv_warnings :: Messages PsMessage
+ , pv_errors :: Messages PsMessage
, pv_header_comments :: Strict.Maybe [LEpaComment]
, pv_comment_q :: [LEpaComment]
}
@@ -2769,15 +2806,18 @@ instance Monad PV where
PV_Failed acc' -> PV_Failed acc'
runPV :: PV a -> P a
-runPV = runPV_hints []
+runPV = runPV_details noParseContext
-runPV_hints :: [GhcHint] -> PV a -> P a
-runPV_hints hints m =
+askParseContext :: PV ParseContext
+askParseContext = PV $ \(PV_Context _ details) acc -> PV_Ok acc details
+
+runPV_details :: ParseContext -> PV a -> P a
+runPV_details details m =
P $ \s ->
let
pv_ctx = PV_Context
{ pv_options = options s
- , pv_hints = hints }
+ , pv_details = details }
pv_acc = PV_Accum
{ pv_warnings = warnings s
, pv_errors = errors s
@@ -2792,22 +2832,14 @@ runPV_hints hints m =
PV_Ok acc' a -> POk (mkPState acc') a
PV_Failed acc' -> PFailed (mkPState acc')
-add_hint :: GhcHint -> PV a -> PV a
-add_hint hint m =
- let modifyHint ctx = ctx{pv_hints = pv_hints ctx ++ [hint]} in
- PV (\ctx acc -> unPV m (modifyHint ctx) acc)
-
instance MonadP PV where
- addError err@(PsError e hints loc) =
- PV $ \ctx acc ->
- let err' | null (pv_hints ctx) = err
- | otherwise = PsError e (hints ++ pv_hints ctx) loc
- in PV_Ok acc{pv_errors = err' `consBag` pv_errors acc} ()
- addWarning option w =
- PV $ \ctx acc ->
- if warnopt option (pv_options ctx)
- then PV_Ok acc{pv_warnings= w `consBag` pv_warnings acc} ()
- else PV_Ok acc ()
+ addError err =
+ PV $ \_ctx acc -> PV_Ok acc{pv_errors = err `addMessage` pv_errors acc} ()
+ addWarning w =
+ PV $ \_ctx acc ->
+ -- No need to check for the warning flag to be set, GHC will correctly discard suppressed
+ -- diagnostics.
+ PV_Ok acc{pv_warnings= w `addMessage` pv_warnings acc} ()
addFatalError err =
addError err >> PV (const PV_Failed)
getBit ext =
@@ -2834,9 +2866,9 @@ instance MonadP PV where
pv_comment_q = comment_q'
} (EpaCommentsBalanced (Strict.fromMaybe [] header_comments') (reverse newAnns))
-{- Note [Parser-Validator Hint]
+{- Note [Parser-Validator Details]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A PV computation is parametrized by a hint for error messages, which can be set
+A PV computation is parametrized by some 'ParseContext' for diagnostic messages, which can be set
depending on validation context. We use this in checkPattern to fix #984.
Consider this example, where the user has forgotten a 'do':
@@ -2863,16 +2895,17 @@ Note that this fragment is parsed as a pattern:
_ ->
result
-We attempt to detect such cases and add a hint to the error messages:
+We attempt to detect such cases and add a hint to the diagnostic messages:
T984.hs:6:9:
Parse error in pattern: case () of { _ -> result }
Possibly caused by a missing 'do'?
-The "Possibly caused by a missing 'do'?" suggestion is the hint that is passed
-as the 'pv_hints' field 'PV_Context'. When validating in a context other than
-'bindpat' (a pattern to the left of <-), we set the hint to 'empty' and it has
-no effect on the error messages.
+The "Possibly caused by a missing 'do'?" suggestion is the hint that is computed
+out of the 'ParseContext', which are read by functions like 'patFail' when
+constructing the 'PsParseErrorInPatDetails' data structure. When validating in a
+context other than 'bindpat' (a pattern to the left of <-), we set the
+details to 'noParseContext' and it has no effect on the diagnostic messages.
-}
@@ -2881,7 +2914,7 @@ hintBangPat :: SrcSpan -> Pat GhcPs -> PV ()
hintBangPat span e = do
bang_on <- getBit BangPatBit
unless bang_on $
- addError $ PsError (PsErrIllegalBangPattern e) [] span
+ addError $ mkPlainErrorMsgEnvelope span $ PsErrIllegalBangPattern e
mkSumOrTupleExpr :: SrcSpanAnnA -> Boxity -> SumOrTuple (HsExpr GhcPs)
-> [AddEpAnn]
@@ -2907,7 +2940,7 @@ mkSumOrTupleExpr l Unboxed (Sum alt arity e barsp barsa) anns = do
cs <- getCommentsFor (locA l)
return $ L l (ExplicitSum (EpAnn (spanAsAnchor $ locA l) an cs) alt arity e)
mkSumOrTupleExpr l Boxed a@Sum{} _ =
- addFatalError $ PsError (PsErrUnsupportedBoxedSumExpr a) [] (locA l)
+ addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrUnsupportedBoxedSumExpr a
mkSumOrTuplePat
:: SrcSpanAnnA -> Boxity -> SumOrTuple (PatBuilder GhcPs) -> [AddEpAnn]
@@ -2923,7 +2956,8 @@ mkSumOrTuplePat l boxity (Tuple ps) anns = do
-- Ignore the element location so that the error message refers to the
-- entire tuple. See #19504 (and the discussion) for details.
toTupPat p = case p of
- Left _ -> addFatalError $ PsError PsErrTupleSectionInPat [] (locA l)
+ Left _ -> addFatalError $
+ mkPlainErrorMsgEnvelope (locA l) PsErrTupleSectionInPat
Right p' -> checkLPat p'
-- Sum
@@ -2933,7 +2967,8 @@ mkSumOrTuplePat l Unboxed (Sum alt arity p barsb barsa) anns = do
let an = EpAnn (spanAsAnchor $ locA l) (EpAnnSumPat anns barsb barsa) cs
return $ L l (PatBuilderPat (SumPat an p' alt arity))
mkSumOrTuplePat l Boxed a@Sum{} _ =
- addFatalError $ PsError (PsErrUnsupportedBoxedSumPat a) [] (locA l)
+ addFatalError $
+ mkPlainErrorMsgEnvelope (locA l) $ PsErrUnsupportedBoxedSumPat a
mkLHsOpTy :: LHsType GhcPs -> LocatedN RdrName -> LHsType GhcPs -> LHsType GhcPs
mkLHsOpTy x op y =
diff --git a/compiler/GHC/Parser/PostProcess/Haddock.hs b/compiler/GHC/Parser/PostProcess/Haddock.hs
index 301e902f8b..88988b2ea6 100644
--- a/compiler/GHC/Parser/PostProcess/Haddock.hs
+++ b/compiler/GHC/Parser/PostProcess/Haddock.hs
@@ -54,7 +54,6 @@ import GHC.Prelude hiding (mod)
import GHC.Hs
import GHC.Types.SrcLoc
-import GHC.Driver.Flags ( WarningFlag(..) )
import GHC.Utils.Panic
import GHC.Data.Bag
@@ -71,7 +70,7 @@ import Data.Coerce
import qualified Data.Monoid
import GHC.Parser.Lexer
-import GHC.Parser.Errors
+import GHC.Parser.Errors.Types
import GHC.Utils.Misc (mergeListsBy, filterOut, mapLastM, (<&&>))
import qualified GHC.Data.Strict as Strict
@@ -193,9 +192,9 @@ addHaddockToModule lmod = do
reportHdkWarning :: HdkWarn -> P ()
reportHdkWarning (HdkWarnInvalidComment (L l _)) =
- addWarning Opt_WarnInvalidHaddock $ PsWarnHaddockInvalidPos (mkSrcSpanPs l)
+ addPsMessage (mkSrcSpanPs l) PsWarnHaddockInvalidPos
reportHdkWarning (HdkWarnExtraComment (L l _)) =
- addWarning Opt_WarnInvalidHaddock $ PsWarnHaddockIgnoreMulti l
+ addPsMessage l PsWarnHaddockIgnoreMulti
collectHdkWarnings :: HdkSt -> [HdkWarn]
collectHdkWarnings HdkSt{ hdk_st_pending, hdk_st_warnings } =
diff --git a/compiler/GHC/Types/Hint.hs b/compiler/GHC/Types/Hint.hs
index 23e00acfd8..51cd77b33a 100644
--- a/compiler/GHC/Types/Hint.hs
+++ b/compiler/GHC/Types/Hint.hs
@@ -5,7 +5,6 @@ module GHC.Types.Hint where
import GHC.Prelude
import GHC.Utils.Outputable
-import GHC.Types.Name.Reader
import GHC.LanguageExtensions
import Data.Typeable
import GHC.Unit.Module (ModuleName, Module)
@@ -47,12 +46,6 @@ data GhcHint
Test cases: None (that explicitly test this particular hint is emitted).
-}
| SuggestLetInDo
- -- FIXME(adn) This is not a hint but was migrated from the old \"PsHint\" type.
- -- It will be removed in a further refactoring as part of #18516.
- | SuggestInfixBindMaybeAtPat !RdrName
- -- FIXME(adn) This is not a hint but was migrated from the old \"PsHint\" type.
- -- It will be removed in a further refactoring as part of #18516.
- | TypeApplicationsInPatternsOnlyDataCons
{-| Suggests to add an \".hsig\" signature file to the Cabal manifest.
Triggered by: 'GHC.Driver.Errors.Types.DriverUnexpectedSignature', if Cabal
@@ -75,6 +68,20 @@ data GhcHint
Test case(s): driver/T12955
-}
| SuggestSignatureInstantiations !ModuleName [InstantiationSuggestion]
+ {-| Suggests to use spaces instead of tabs.
+
+ Triggered by: 'GHC.Parser.Errors.Types.PsWarnTab'.
+
+ Examples: None
+ Test Case(s): None
+ -}
+ | SuggestUseSpaces
+ {-| Suggests wrapping an expression in parentheses
+
+ Examples: None
+ Test Case(s): None
+ -}
+ | SuggestParentheses
instance Outputable GhcHint where
@@ -88,15 +95,6 @@ instance Outputable GhcHint where
SuggestLetInDo
-> text "Perhaps you need a 'let' in a 'do' block?"
$$ text "e.g. 'let x = 5' instead of 'x = 5'"
- SuggestInfixBindMaybeAtPat fun
- -> text "In a function binding for the"
- <+> quotes (ppr fun)
- <+> text "operator."
- $$ if opIsAt fun
- then perhapsAsPat
- else empty
- TypeApplicationsInPatternsOnlyDataCons
- -> text "Type applications in patterns are only allowed on data constructors."
SuggestAddSignatureCabalFile pi_mod_name
-> text "Try adding" <+> quotes (ppr pi_mod_name)
<+> text "to the"
@@ -111,10 +109,10 @@ instance Outputable GhcHint where
in text "Try passing -instantiated-with=\"" <>
suggested_instantiated_with <> text "\"" $$
text "replacing <" <> ppr pi_mod_name <> text "> as necessary."
-
-perhapsAsPat :: SDoc
-perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace"
-
+ SuggestUseSpaces
+ -> text "Please use spaces instead."
+ SuggestParentheses
+ -> text "Use parentheses."
-- | An 'InstantiationSuggestion' for a '.hsig' file. This is generated
-- by GHC in case of a 'DriverUnexpectedSignature' and suggests a way