Commit a5aaceec authored by Sylvain Henry's avatar Sylvain Henry Committed by Marge Bot
Browse files

Use ADTs for parser errors/warnings

Haskell and Cmm parsers/lexers now report errors and warnings using ADTs
defined in GHC.Parser.Errors. They can be printed using functions in
GHC.Parser.Errors.Ppr.

Some of the errors provide hints with a separate ADT (e.g. to suggest to
turn on some extension). For now, however, hints are not consistent
across all messages. For example some errors contain the hints in the
main message. I didn't want to change any message with this patch. I
expect these changes to be discussed and implemented later.

Surprisingly, this patch enhances performance. On CI
(x86_64/deb9/hadrian, ghc/alloc):

   parsing001         -11.5%
   T13719             -2.7%
   MultiLayerModules  -3.5%
   Naperian           -3.1%

Bump haddock submodule

Metric Decrease:
    MultiLayerModules
    Naperian
    T13719
    parsing001
parent dca1cb22
......@@ -357,6 +357,7 @@ import GHC.Data.FastString
import qualified GHC.Parser as Parser
import GHC.Parser.Lexer
import GHC.Parser.Annotation
import GHC.Parser.Errors.Ppr
import qualified GHC.LanguageExtensions as LangExt
import GHC.Types.Name.Env
import GHC.Tc.Module
......@@ -1430,10 +1431,8 @@ getTokenStream mod = do
(sourceFile, source, dflags) <- getModuleSourceAndFlags mod
let startLoc = mkRealSrcLoc (mkFastString sourceFile) 1 1
case lexTokenStream (initParserOpts dflags) source startLoc of
POk _ ts -> return ts
PFailed pst ->
do dflags <- getDynFlags
throwErrors (getErrorMessages pst dflags)
POk _ ts -> return ts
PFailed pst -> throwErrors (fmap pprError (getErrorMessages pst))
-- | Give even more information on the source than 'getTokenStream'
-- This function allows reconstructing the source completely with
......@@ -1443,10 +1442,8 @@ getRichTokenStream mod = do
(sourceFile, source, dflags) <- getModuleSourceAndFlags mod
let startLoc = mkRealSrcLoc (mkFastString sourceFile) 1 1
case lexTokenStream (initParserOpts dflags) source startLoc of
POk _ ts -> return $ addSourceToTokens startLoc source ts
PFailed pst ->
do dflags <- getDynFlags
throwErrors (getErrorMessages pst dflags)
POk _ ts -> return $ addSourceToTokens startLoc source ts
PFailed pst -> throwErrors (fmap pprError (getErrorMessages pst))
-- | Given a source location and a StringBuffer corresponding to this
-- location, return a rich token stream with the source associated to the
......@@ -1620,12 +1617,12 @@ parser str dflags filename =
case unP Parser.parseModule (initParserState (initParserOpts dflags) buf loc) of
PFailed pst ->
let (warns,errs) = getMessages pst dflags in
(warns, Left errs)
let (warns,errs) = getMessages pst in
(fmap pprWarning warns, Left (fmap pprError errs))
POk pst rdr_module ->
let (warns,_) = getMessages pst dflags in
(warns, Right rdr_module)
let (warns,_) = getMessages pst in
(fmap pprWarning warns, Right rdr_module)
-- -----------------------------------------------------------------------------
-- | Find the package environment (if one exists)
......
......@@ -78,6 +78,7 @@ module GHC.Builtin.Types (
unboxedUnitTy,
unboxedUnitTyCon, unboxedUnitDataCon,
unboxedTupleKind, unboxedSumKind,
filterCTuple,
-- ** Constraint tuples
cTupleTyCon, cTupleTyConName, cTupleTyConNames, isCTupleTyConName,
......@@ -2029,3 +2030,11 @@ naturalNSDataCon = pcDataCon naturalNSDataConName [] [wordPrimTy] naturalTyCon
naturalNBDataCon :: DataCon
naturalNBDataCon = pcDataCon naturalNBDataConName [] [byteArrayPrimTy] naturalTyCon
-- | Replaces constraint tuple names with corresponding boxed ones.
filterCTuple :: RdrName -> RdrName
filterCTuple (Exact n)
| Just arity <- cTupleTyConNameArity_maybe n
= Exact $ tupleTyConName BoxedTuple arity
filterCTuple rdr = rdr
......@@ -26,6 +26,7 @@ import GHC.Types.Unique.FM
import GHC.Data.StringBuffer
import GHC.Data.FastString
import GHC.Parser.CharClass
import GHC.Parser.Errors
import GHC.Utils.Misc
--import TRACE
......@@ -325,7 +326,7 @@ 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) "lexical error"
AlexError (loc2,_) -> liftP $ failLocMsgP (psRealLoc loc1) (psRealLoc loc2) (Error ErrCmmLexer [])
AlexSkip inp2 _ -> do
setInput inp2
lexToken
......
......@@ -26,6 +26,8 @@ import Control.Monad
import GHC.Driver.Session
import GHC.Parser.Lexer
import GHC.Parser.Errors
import GHC.Types.SrcLoc
newtype PD a = PD { unPD :: DynFlags -> PState -> ParseResult a }
......@@ -42,7 +44,7 @@ instance Monad PD where
liftP :: P a -> PD a
liftP (P f) = PD $ \_ s -> f s
failMsgPD :: String -> PD a
failMsgPD :: (SrcSpan -> Error) -> PD a
failMsgPD = liftP . failMsgP
returnPD :: a -> PD a
......
......@@ -239,6 +239,7 @@ import qualified GHC.Cmm.Monad as PD
import GHC.Cmm.CallConv
import GHC.Runtime.Heap.Layout
import GHC.Parser.Lexer
import GHC.Parser.Errors
import GHC.Types.CostCentre
import GHC.Types.ForeignCall
......@@ -257,7 +258,7 @@ import GHC.Utils.Panic
import GHC.Settings.Constants
import GHC.Utils.Outputable
import GHC.Types.Basic
import GHC.Data.Bag ( emptyBag, unitBag )
import GHC.Data.Bag ( Bag, emptyBag, unitBag, isEmptyBag )
import GHC.Types.Var
import Control.Monad
......@@ -899,7 +900,7 @@ getLit _ = panic "invalid literal" -- TODO messy failure
nameToMachOp :: FastString -> PD (Width -> MachOp)
nameToMachOp name =
case lookupUFM machOps name of
Nothing -> failMsgPD ("unknown primitive " ++ unpackFS name)
Nothing -> failMsgPD $ Error (ErrCmmParser (CmmUnknownPrimitive name)) []
Just m -> return m
exprOp :: FastString -> [CmmParse CmmExpr] -> PD (CmmParse CmmExpr)
......@@ -1061,12 +1062,12 @@ parseSafety :: String -> PD Safety
parseSafety "safe" = return PlaySafe
parseSafety "unsafe" = return PlayRisky
parseSafety "interruptible" = return PlayInterruptible
parseSafety str = failMsgPD ("unrecognised safety: " ++ str)
parseSafety str = failMsgPD $ Error (ErrCmmParser (CmmUnrecognisedSafety str)) []
parseCmmHint :: String -> PD ForeignHint
parseCmmHint "ptr" = return AddrHint
parseCmmHint "signed" = return SignedHint
parseCmmHint str = failMsgPD ("unrecognised hint: " ++ str)
parseCmmHint str = failMsgPD $ Error (ErrCmmParser (CmmUnrecognisedHint str)) []
-- labels are always pointers, so we might as well infer the hint
inferCmmHint :: CmmExpr -> ForeignHint
......@@ -1093,7 +1094,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 ("unknown macro: " ++ unpackFS fun)
Nothing -> failMsgPD $ Error (ErrCmmParser (CmmUnknownMacro fun)) []
Just fcode -> return $ do
args <- sequence args_code
code (fcode args)
......@@ -1194,9 +1195,9 @@ foreignCall
-> PD (CmmParse ())
foreignCall conv_string results_code expr_code args_code safety ret
= do conv <- case conv_string of
"C" -> return CCallConv
"C" -> return CCallConv
"stdcall" -> return StdCallConv
_ -> failMsgPD ("unknown calling convention: " ++ conv_string)
_ -> failMsgPD $ Error (ErrCmmParser (CmmUnknownCConv conv_string)) []
return $ do
platform <- getPlatform
results <- sequence results_code
......@@ -1274,7 +1275,7 @@ primCall results_code name args_code
= do
platform <- PD.getPlatform
case lookupUFM (callishMachOps platform) name of
Nothing -> failMsgPD ("unknown primitive " ++ unpackFS name)
Nothing -> failMsgPD $ Error (ErrCmmParser (CmmUnknownPrimitive name)) []
Just f -> return $ do
results <- sequence results_code
args <- sequence args_code
......@@ -1428,8 +1429,8 @@ initEnv profile = listToUFM [
]
where platform = profilePlatform profile
parseCmmFile :: DynFlags -> FilePath -> IO (Messages, Maybe CmmGroup)
parseCmmFile dflags filename = withTiming dflags (text "ParseCmm"<+>brackets (text filename)) (\_ -> ()) $ do
parseCmmFile :: DynFlags -> FilePath -> IO (Bag Warning, Bag Error, Maybe CmmGroup)
parseCmmFile dflags filename = do
buf <- hGetStringBuffer filename
let
init_loc = mkRealSrcLoc (mkFastString filename) 1 1
......@@ -1438,16 +1439,17 @@ parseCmmFile dflags filename = withTiming dflags (text "ParseCmm"<+>brackets (te
-- reset the lex_state: the Lexer monad leaves some stuff
-- in there we don't want.
case unPD cmmParse dflags init_state of
PFailed pst ->
return (getMessages pst dflags, Nothing)
PFailed pst -> do
let (warnings,errors) = getMessages pst
return (warnings, errors, Nothing)
POk pst code -> do
st <- initC
let fcode = getCmm $ unEC code "global" (initEnv (targetProfile dflags)) [] >> return ()
(cmm,_) = runC dflags no_module st fcode
let ms = getMessages pst dflags
if (errorsFound dflags ms)
then return (ms, Nothing)
else return (ms, Just cmm)
(warnings,errors) = getMessages pst
if not (isEmptyBag errors)
then return (warnings, errors, Nothing)
else return (warnings, errors, Just cmm)
where
no_module = panic "parseCmmFile: no module"
}
......@@ -24,6 +24,7 @@ import GHC.Prelude
import GHC.Driver.Backpack.Syntax
import GHC.Parser.Annotation
import GHC.Parser.Errors.Ppr
import GHC hiding (Failed, Succeeded)
import GHC.Parser
import GHC.Parser.Lexer
......@@ -85,7 +86,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 (getErrorMessages pst dflags)
PFailed pst -> throwErrors (fmap pprError (getErrorMessages pst))
POk _ pkgname_bkp -> do
-- OK, so we have an LHsUnit PackageName, but we want an
-- LHsUnit HsComponentId. So let's rename it.
......
......@@ -101,6 +101,8 @@ import GHC.Utils.Panic
import GHC.Core.ConLike
import GHC.Parser.Annotation
import GHC.Parser.Errors
import GHC.Parser.Errors.Ppr
import GHC.Unit
import GHC.Unit.State
import GHC.Types.Name.Reader
......@@ -177,7 +179,7 @@ import qualified Data.Set as S
import Data.Set (Set)
import Data.Functor
import Control.DeepSeq (force)
import Data.Bifunctor (first)
import Data.Bifunctor (first, bimap)
import GHC.Iface.Ext.Ast ( mkHieFile )
import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module )
......@@ -237,15 +239,19 @@ handleWarnings = do
-- | log warning in the monad, and if there are errors then
-- throw a SourceError exception.
logWarningsReportErrors :: Messages -> Hsc ()
logWarningsReportErrors (warns,errs) = do
logWarningsReportErrors :: (Bag Warning, Bag Error) -> Hsc ()
logWarningsReportErrors (warnings,errors) = do
let warns = fmap pprWarning warnings
errs = fmap pprError errors
logWarnings warns
when (not $ isEmptyBag errs) $ throwErrors errs
-- | Log warnings and throw errors, assuming the messages
-- contain at least one error (e.g. coming from PFailed)
handleWarningsThrowErrors :: Messages -> Hsc a
handleWarningsThrowErrors (warns, errs) = do
handleWarningsThrowErrors :: (Bag Warning, Bag Error) -> Hsc a
handleWarningsThrowErrors (warnings, errors) = do
let warns = fmap pprWarning warnings
errs = fmap pprError errors
logWarnings warns
dflags <- getDynFlags
(wWarns, wErrs) <- warningsToMessages dflags <$> getWarnings
......@@ -356,9 +362,9 @@ hscParse' mod_summary
case unP parseMod (initParserState (initParserOpts dflags) buf loc) of
PFailed pst ->
handleWarningsThrowErrors (getMessages pst dflags)
handleWarningsThrowErrors (getMessages pst)
POk pst rdr_module -> do
let (warns, errs) = getMessages pst dflags
let (warns, errs) = bimap (fmap pprWarning) (fmap pprError) (getMessages pst)
logWarnings warns
liftIO $ dumpIfSet_dyn dflags Opt_D_dump_parsed "Parser"
FormatHaskell (ppr rdr_module)
......@@ -1496,7 +1502,11 @@ hscCompileCmmFile hsc_env filename output_filename = runHsc hsc_env $ do
let dflags = hsc_dflags hsc_env
home_unit = mkHomeUnitFromFlags dflags
platform = targetPlatform dflags
cmm <- ioMsgMaybe $ parseCmmFile dflags filename
cmm <- ioMsgMaybe
$ do
(warns,errs,cmm) <- withTiming dflags (text "ParseCmm"<+>brackets (text filename)) (\_ -> ())
$ parseCmmFile dflags filename
return ((fmap pprWarning warns, fmap pprError errs), cmm)
liftIO $ do
dumpIfSet_dyn dflags Opt_D_dump_cmm_verbose_by_proc "Parsed Cmm" FormatCMM (pdoc platform cmm)
let -- Make up a module name to give the NCG. We can't pass bottom here
......@@ -1878,10 +1888,10 @@ hscParseThingWithLocation source linenumber parser str
case unP parser (initParserState (initParserOpts dflags) buf loc) of
PFailed pst -> do
handleWarningsThrowErrors (getMessages pst dflags)
handleWarningsThrowErrors (getMessages pst)
POk pst thing -> do
logWarningsReportErrors (getMessages pst dflags)
logWarningsReportErrors (getMessages pst)
liftIO $ dumpIfSet_dyn dflags Opt_D_dump_parsed "Parser"
FormatHaskell (ppr thing)
liftIO $ dumpIfSet_dyn dflags Opt_D_dump_parsed_ast "Parser AST"
......
......@@ -45,6 +45,7 @@ import GHC.Utils.Error
import GHC.Driver.Finder
import GHC.Driver.Monad
import GHC.Parser.Header
import GHC.Parser.Errors.Ppr
import GHC.Driver.Types
import GHC.Unit
import GHC.Unit.State
......@@ -94,6 +95,7 @@ import Data.Foldable (toList)
import Data.Maybe
import Data.Ord ( comparing )
import Data.Time
import Data.Bifunctor (first)
import System.Directory
import System.FilePath
import System.IO ( fixIO )
......@@ -2669,7 +2671,9 @@ getPreprocessedImports hsc_env src_fn mb_phase maybe_buf = do
<- ExceptT $ preprocess hsc_env src_fn (fst <$> maybe_buf) mb_phase
pi_hspp_buf <- liftIO $ hGetStringBuffer pi_hspp_fn
(pi_srcimps, pi_theimps, L pi_mod_name_loc pi_mod_name)
<- ExceptT $ getImports pi_local_dflags pi_hspp_buf pi_hspp_fn src_fn
<- ExceptT $ do
mimps <- getImports pi_local_dflags pi_hspp_buf pi_hspp_fn src_fn
return (first (fmap pprError) mimps)
return PreprocessedImports {..}
......
......@@ -45,6 +45,7 @@ import GHC.Unit.State
import GHC.Platform.Ways
import GHC.Platform.ArchOS
import GHC.Parser.Header
import GHC.Parser.Errors.Ppr
import GHC.Driver.Phases
import GHC.SysTools
import GHC.SysTools.ExtraObj
......@@ -1117,7 +1118,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
buf <- hGetStringBuffer input_fn
eimps <- getImports dflags buf input_fn (basename <.> suff)
case eimps of
Left errs -> throwErrors errs
Left errs -> throwErrors (fmap pprError errs)
Right (src_imps,imps,L _ mod_name) -> return
(Just buf, mod_name, imps, src_imps)
......
......@@ -85,6 +85,7 @@ import GHC.Parser.PostProcess
import GHC.Parser.PostProcess.Haddock
import GHC.Parser.Lexer
import GHC.Parser.Annotation
import GHC.Parser.Errors
import GHC.Tc.Types.Evidence ( emptyTcEvBinds )
......@@ -797,7 +798,7 @@ HYPHEN :: { [AddAnn] }
| PREFIX_MINUS { [mj AnnMinus $1 ] }
| VARSYM {% if (getVARSYM $1 == fsLit "-")
then return [mj AnnMinus $1]
else do { addError (getLoc $1) $ text "Expected a hyphen"
else do { addError $ Error ErrExpectedHyphen [] (getLoc $1)
; return [] } }
......@@ -1094,10 +1095,7 @@ maybe_safe :: { ([AddAnn],Bool) }
maybe_pkg :: { ([AddAnn],Maybe StringLiteral) }
: STRING {% do { let { pkgFS = getSTRING $1 }
; unless (looksLikePackageName (unpackFS pkgFS)) $
addError (getLoc $1) $ vcat [
text "Parse error" <> colon <+> quotes (ppr pkgFS),
text "Version number or non-alphanumeric" <+>
text "character in package name"]
addError $ Error (ErrInvalidPackageName pkgFS) [] (getLoc $1)
; return ([mj AnnPackageName $1], Just (StringLiteral (getSTRINGs $1) pkgFS)) } }
| {- empty -} { ([],Nothing) }
......@@ -1798,7 +1796,7 @@ rule_activation_marker :: { [AddAnn] }
: PREFIX_TILDE { [mj AnnTilde $1] }
| VARSYM {% if (getVARSYM $1 == fsLit "~")
then return [mj AnnTilde $1]
else do { addError (getLoc $1) $ text "Invalid rule activation marker"
else do { addError $ Error ErrInvalidRuleActivationMarker [] (getLoc $1)
; return [] } }
rule_explicit_activation :: { ([AddAnn]
......@@ -3216,7 +3214,7 @@ pat : exp {% (checkPattern <=< runPV) (unECP $1) }
bindpat :: { LPat GhcPs }
bindpat : exp {% -- See Note [Parser-Validator Hint] in GHC.Parser.PostProcess
checkPattern_msg (text "Possibly caused by a missing 'do'?")
checkPattern_hints [SuggestMissingDo]
(unECP $1) }
apat :: { LPat GhcPs }
......@@ -3840,10 +3838,9 @@ hasE _ = False
getSCC :: Located Token -> P FastString
getSCC lt = do let s = getSTRING lt
err = "Spaces are not allowed in SCCs"
-- We probably actually want to be more restrictive than this
if ' ' `elem` unpackFS s
then addFatalError (getLoc lt) (text err)
then addFatalError $ Error ErrSpaceInSCC [] (getLoc lt)
else return s
-- Utilities for combining source spans
......@@ -3928,8 +3925,7 @@ fileSrcSpan = do
hintLinear :: MonadP m => SrcSpan -> m ()
hintLinear span = do
linearEnabled <- getBit LinearTypesBit
unless linearEnabled $ addError span $
text "Enable LinearTypes to allow linear functions"
unless linearEnabled $ addError $ Error ErrLinearFunction [] span
-- Does this look like (a %m)?
looksLikeMult :: LHsType GhcPs -> Located RdrName -> LHsType GhcPs -> Bool
......@@ -3948,22 +3944,14 @@ looksLikeMult ty1 l_op ty2
hintMultiWayIf :: SrcSpan -> P ()
hintMultiWayIf span = do
mwiEnabled <- getBit MultiWayIfBit
unless mwiEnabled $ addError span $
text "Multi-way if-expressions need MultiWayIf turned on"
unless mwiEnabled $ addError $ Error ErrMultiWayIf [] span
-- Hint about explicit-forall
hintExplicitForall :: Located Token -> P ()
hintExplicitForall tok = do
forall <- getBit ExplicitForallBit
rulePrag <- getBit InRulePragBit
unless (forall || rulePrag) $ addError (getLoc tok) $ vcat
[ text "Illegal symbol" <+> quotes forallSymDoc <+> text "in type"
, text "Perhaps you intended to use RankNTypes or a similar language"
, text "extension to enable explicit-forall syntax:" <+>
forallSymDoc <+> text "<tvs>. <type>"
]
where
forallSymDoc = text (forallSym (isUnicode tok))
unless (forall || rulePrag) $ addError $ Error (ErrExplicitForall (isUnicode tok)) [] (getLoc tok)
-- Hint about qualified-do
hintQualifiedDo :: Located Token -> P ()
......@@ -3971,10 +3959,7 @@ hintQualifiedDo tok = do
qualifiedDo <- getBit QualifiedDoBit
case maybeQDoDoc of
Just qdoDoc | not qualifiedDo ->
addError (getLoc tok) $ vcat
[ text "Illegal qualified" <+> quotes qdoDoc <+> text "block"
, text "Perhaps you intended to use QualifiedDo"
]
addError $ Error (ErrIllegalQualifiedDo qdoDoc) [] (getLoc tok)
_ -> return ()
where
maybeQDoDoc = case unLoc tok of
......@@ -3988,17 +3973,7 @@ hintQualifiedDo tok = do
reportEmptyDoubleQuotes :: SrcSpan -> P a
reportEmptyDoubleQuotes span = do
thQuotes <- getBit ThQuotesBit
if thQuotes
then addFatalError span $ vcat
[ text "Parser error on `''`"
, text "Character literals may not be empty"
, text "Or perhaps you intended to use quotation syntax of TemplateHaskell,"
, text "but the type variable or constructor is missing"
]
else addFatalError span $ vcat
[ text "Parser error on `''`"
, text "Character literals may not be empty"
]
addFatalError $ Error (ErrEmptyDoubleQuotes thQuotes) [] span
{-
%************************************************************************
......
......@@ -197,10 +197,9 @@ getAndRemoveAnnotationComments anns span =
-- various syntactic keywords that are not captured in the existing
-- AST.
--
-- The annotations, together with original source comments are made
-- available in the @'pm_annotations'@ field of @'GHC.ParsedModule'@.
-- Comments are only retained if @'Opt_KeepRawTokenStream'@ is set in
-- @'GHC.Driver.Session.DynFlags'@ before parsing.
-- The annotations, together with original source comments are made available in
-- the @'pm_annotations'@ field of @'GHC.Driver.Types.HsParsedModule'@.
-- Comments are only retained if @'Opt_KeepRawTokenStream'@ is set.
--
-- The wiki page describing this feature is
-- https://gitlab.haskell.org/ghc/ghc/wikis/api-annotations
......
module GHC.Parser.Errors
( Warning(..)
, TransLayoutReason(..)
, NumUnderscoreReason(..)
, Error(..)
, ErrorDesc(..)
, LexErr(..)
, CmmParserError(..)
, LexErrKind(..)
, Hint(..)
, StarIsType (..)
)
where
import GHC.Prelude
import GHC.Types.SrcLoc
import GHC.Types.Name.Reader (RdrName)
import GHC.Types.Name.Occurrence (OccName)
import GHC.Parser.Types
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.Utils.Outputable (SDoc)
import GHC.Data.FastString
import GHC.Unit.Module.Name
data Warning
-- | Warn when tabulations are found
= WarnTab
{ tabFirst :: !SrcSpan -- ^ First occurence of a tab
, tabCount :: !Word -- ^ Number of other occurences
}
| WarnTransitionalLayout !SrcSpan !TransLayoutReason
-- ^ Transitional layout warnings
| WarnUnrecognisedPragma !SrcSpan
-- ^ Unrecognised pragma
| WarnHaddockInvalidPos !SrcSpan
-- ^ Invalid Haddock comment position
| WarnHaddockIgnoreMulti !SrcSpan
-- ^ Multiple Haddock comment for the same entity
| WarnStarBinder !SrcSpan
-- ^ Found binding occurence of "*" while StarIsType is enabled
| WarnStarIsType !SrcSpan
-- ^ Using "*" for "Type" without StarIsType enabled
| WarnImportPreQualified !SrcSpan
-- ^ Pre qualified import with 'WarnPrepositiveQualifiedModule' enabled
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 Error = Error
{ errDesc :: !ErrorDesc -- ^ Error description
, errHints :: ![Hint] -- ^ Hints
, errLoc :: !SrcSpan -- ^ Error position
}
data ErrorDesc
= ErrLambdaCase
-- ^ LambdaCase syntax used without the extension enabled
| ErrNumUnderscores !NumUnderscoreReason
-- ^ Underscores in literals without the extension enabled
| ErrPrimStringInvalidChar
-- ^ Invalid character in primitive string
| ErrMissingBlock
-- ^ Missing block
| ErrLexer !LexErr !LexErrKind
-- ^ Lexer error
| ErrSuffixAT
-- ^ Suffix occurence of `@`
| ErrParse !String
-- ^ Parse errors
| ErrCmmLexer
-- ^ Cmm lexer error
| ErrUnsupportedBoxedSumExpr !(SumOrTuple (HsExpr GhcPs))
-- ^ Unsupported boxed sum in expression
| ErrUnsupportedBoxedSumPat !(SumOrTuple (PatBuilder GhcPs))
-- ^ Unsupported boxed sum in pattern
| ErrUnexpectedQualifiedConstructor !RdrName
-- ^ Unexpected qualified constructor
| ErrTupleSectionInPat
-- ^ Tuple section in pattern context
| ErrIllegalBangPattern !(Pat GhcPs)
-- ^ Bang-pattern without BangPattterns enabled
| ErrOpFewArgs !StarIsType !RdrName
-- ^ Operator applied to too few arguments
| ErrImportQualifiedTwice
-- ^ Import: multiple occurrences of 'qualified'
| ErrImportPostQualified
-- ^ Post qualified import without 'ImportQualifiedPost'
| ErrIllegalExplicitNamespace
-- ^ Explicit namespace keyword without 'ExplicitNamespaces'
| ErrVarForTyCon !RdrName
-- ^ Expecting a type constructor but found a variable
| ErrIllegalPatSynExport
-- ^ Illegal export form allowed by PatternSynonyms
| ErrMalformedEntityString
-- ^ Malformed entity string
| ErrDotsInRecordUpdate
-- ^ Dots used in record update
| ErrPrecedenceOutOfRange !Int
-- ^ Precedence out of range
| ErrInvalidDataCon !(HsType GhcPs)
-- ^ Cannot parse data constructor in a data/newtype declaration
| ErrInvalidInfixDataCon !(HsType GhcPs) !Rdr