[Git][ghc/ghc][master] Convert diagnostics in GHC.Rename.Expr to proper TcRnMessage (#20115)
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Thu Nov 24 22:25:14 UTC 2022
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
86ff1523 by Andrei Borzenkov at 2022-11-24T17:24:51-05:00
Convert diagnostics in GHC.Rename.Expr to proper TcRnMessage (#20115)
Problem: avoid usage of TcRnMessageUnknown
Solution:
The following `TcRnMessage` messages has been introduced:
TcRnNoRebindableSyntaxRecordDot
TcRnNoFieldPunsRecordDot
TcRnIllegalStaticExpression
TcRnIllegalStaticFormInSplice
TcRnListComprehensionDuplicateBinding
TcRnEmptyStmtsGroup
TcRnLastStmtNotExpr
TcRnUnexpectedStatementInContext
TcRnIllegalTupleSection
TcRnIllegalImplicitParameterBindings
TcRnSectionWithoutParentheses
Co-authored-by: sheaf <sam.derbyshire at gmail.com>
- - - - -
29 changed files:
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Expr.hs-boot
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Types/Error/Codes.hs
- testsuite/tests/ghci/prog011/prog011.stderr
- testsuite/tests/parser/should_fail/NondecreasingIndentationFail.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail12.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail5.stderr
- testsuite/tests/parser/should_fail/T3811g.stderr
- testsuite/tests/parser/should_fail/readFail028.stderr
- testsuite/tests/parser/should_fail/readFail038.stderr
- testsuite/tests/parser/should_fail/readFail042.stderr
- testsuite/tests/parser/should_fail/readFail043.stderr
- + testsuite/tests/rename/should_fail/RnEmptyStatementGroup1.hs
- + testsuite/tests/rename/should_fail/RnEmptyStatementGroup1.stderr
- + testsuite/tests/rename/should_fail/RnImplicitBindInMdoNotation.hs
- + testsuite/tests/rename/should_fail/RnImplicitBindInMdoNotation.stderr
- testsuite/tests/rename/should_fail/T20147.stderr
- testsuite/tests/rename/should_fail/T2490.stderr
- testsuite/tests/rename/should_fail/T5657.stderr
- testsuite/tests/rename/should_fail/T6060.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/rename/should_fail/rnfail056.stderr
- testsuite/tests/th/T14204.stderr
- testsuite/tests/th/TH_StaticPointers02.stderr
- testsuite/tests/typecheck/should_fail/tcfail092.stderr
Changes:
=====================================
compiler/GHC/Hs/Expr.hs
=====================================
@@ -2078,6 +2078,16 @@ pprStmtContext (TransStmtCtxt c) =
ifPprDebug (sep [text "transformed branch of", pprAStmtContext c])
(pprStmtContext c)
+pprStmtCat :: Stmt (GhcPass p) body -> SDoc
+pprStmtCat (TransStmt {}) = text "transform"
+pprStmtCat (LastStmt {}) = text "return expression"
+pprStmtCat (BodyStmt {}) = text "body"
+pprStmtCat (BindStmt {}) = text "binding"
+pprStmtCat (LetStmt {}) = text "let"
+pprStmtCat (RecStmt {}) = text "rec"
+pprStmtCat (ParStmt {}) = text "parallel"
+pprStmtCat (ApplicativeStmt {}) = text "applicative"
+
pprAHsDoFlavour, pprHsDoFlavour :: HsDoFlavour -> SDoc
pprAHsDoFlavour flavour = article <+> pprHsDoFlavour flavour
where
@@ -2151,13 +2161,11 @@ type instance Anno (Match (GhcPass p) (LocatedA (HsExpr (GhcPass p)))) = SrcSpan
type instance Anno (Match (GhcPass p) (LocatedA (HsCmd (GhcPass p)))) = SrcSpanAnnA
type instance Anno (GRHS (GhcPass p) (LocatedA (HsExpr (GhcPass p)))) = SrcAnn NoEpAnns
type instance Anno (GRHS (GhcPass p) (LocatedA (HsCmd (GhcPass p)))) = SrcAnn NoEpAnns
-type instance Anno (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsExpr (GhcPass pr)))) = SrcSpanAnnA
-type instance Anno (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsCmd (GhcPass pr)))) = SrcSpanAnnA
+type instance Anno (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (body (GhcPass pr)))) = SrcSpanAnnA
type instance Anno (HsUntypedSplice (GhcPass p)) = SrcSpanAnnA
-type instance Anno [LocatedA (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsExpr (GhcPass pr))))] = SrcSpanAnnL
-type instance Anno [LocatedA (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsCmd (GhcPass pr))))] = SrcSpanAnnL
+type instance Anno [LocatedA (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (body (GhcPass pr))))] = SrcSpanAnnL
type instance Anno (FieldLabelStrings (GhcPass p)) = SrcAnn NoEpAnns
type instance Anno FieldLabelString = SrcSpanAnnN
=====================================
compiler/GHC/Rename/Expr.hs
=====================================
@@ -25,7 +25,7 @@ free variables.
module GHC.Rename.Expr (
rnLExpr, rnExpr, rnStmts, mkExpandedExpr,
- AnnoBody
+ AnnoBody, UnexpectedStatement(..)
) where
import GHC.Prelude
@@ -57,7 +57,6 @@ import GHC.Builtin.Names
import GHC.Types.FieldLabel
import GHC.Types.Fixity
-import GHC.Types.Hint (suggestExtension)
import GHC.Types.Id.Make
import GHC.Types.Name
import GHC.Types.Name.Set
@@ -486,13 +485,11 @@ rnExpr (RecordUpd { rupd_expr = expr, rupd_flds = rbinds })
}
Right flds -> -- 'OverloadedRecordUpdate' is in effect. Record dot update desugaring.
do { ; unlessXOptM LangExt.RebindableSyntax $
- addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $
- text "RebindableSyntax is required if OverloadedRecordUpdate is enabled."
+ addErr TcRnNoRebindableSyntaxRecordDot
; let punnedFields = [fld | (L _ fld) <- flds, hfbPun fld]
; punsEnabled <-xoptM LangExt.NamedFieldPuns
; unless (null punnedFields || punsEnabled) $
- addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $
- text "For this to work enable NamedFieldPuns."
+ addErr TcRnNoFieldPunsRecordDot
; (getField, fv_getField) <- lookupSyntaxName getFieldName
; (setField, fv_setField) <- lookupSyntaxName setFieldName
; (e, fv_e) <- rnLExpr expr
@@ -567,17 +564,11 @@ rnExpr e@(HsStatic _ expr) = do
-- absolutely prepared to cope with static forms, we check for
-- -XStaticPointers here as well.
unlessXOptM LangExt.StaticPointers $
- addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $
- hang (text "Illegal static expression:" <+> ppr e)
- 2 (text "Use StaticPointers to enable this extension")
+ addErr $ TcRnIllegalStaticExpression e
(expr',fvExpr) <- rnLExpr expr
stage <- getStage
case stage of
- Splice _ -> addErr $ mkTcRnUnknownMessage $
- mkPlainError noHints $ sep
- [ text "static forms cannot be used in splices:"
- , nest 2 $ ppr e
- ]
+ Splice _ -> addErr $ TcRnIllegalStaticFormInSplice e
_ -> return ()
mod <- getModule
let fvExpr' = filterNameSet (nameIsLocalOrFrom mod) fvExpr
@@ -1023,9 +1014,6 @@ See Note [Deterministic UniqFM] to learn more about nondeterminism.
type AnnoBody body
= ( Outputable (body GhcPs)
- , Anno (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA
- , Anno (StmtLR GhcRn GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA
- , Anno (StmtLR GhcRn GhcRn (LocatedA (body GhcRn))) ~ SrcSpanAnnA
)
-- | Rename some Stmts
@@ -1108,7 +1096,7 @@ rnStmtsWithFreeVars ctxt rnBody (lstmt@(L loc _) : lstmts) thing_inside
= do { ((stmts1, (stmts2, thing)), fvs)
<- setSrcSpanA loc $
do { checkStmt ctxt lstmt
- ; rnStmt ctxt rnBody lstmt $ \ bndrs1 ->
+ ; rnStmt ctxt rnBody lstmt $ \ bndrs1 ->
rnStmtsWithFreeVars ctxt rnBody lstmts $ \ bndrs2 ->
thing_inside (bndrs1 ++ bndrs2) }
; return (((stmts1 ++ stmts2), thing), fvs) }
@@ -1312,9 +1300,7 @@ rnParallelStmts ctxt return_op segs thing_inside
; return ((seg':segs', thing), fvs) }
cmpByOcc n1 n2 = nameOccName n1 `compare` nameOccName n2
- dupErr vs = addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $
- (text "Duplicate binding in parallel list comprehension for:"
- <+> quotes (ppr (NE.head vs)))
+ dupErr vs = addErr $ TcRnListComprehensionDuplicateBinding (NE.head vs)
lookupQualifiedDoStmtName :: HsStmtContext GhcRn -> Name -> RnM (SyntaxExpr GhcRn, FreeVars)
-- Like lookupStmtName, but respects QualifiedDo
@@ -1403,8 +1389,8 @@ type Segment stmts = (Defs,
-- wrapper that does both the left- and right-hand sides
-rnRecStmtsAndThen :: AnnoBody body =>
- HsStmtContext GhcRn
+rnRecStmtsAndThen :: AnnoBody body
+ => HsStmtContext GhcRn
-> (body GhcPs -> RnM (body GhcRn, FreeVars))
-> [LStmt GhcPs (LocatedA (body GhcPs))]
-- assumes that the FreeVars returned includes
@@ -1467,7 +1453,8 @@ rn_rec_stmt_lhs fix_env (L loc (BindStmt _ pat body))
return [(L loc (BindStmt noAnn pat' body), fv_pat)]
rn_rec_stmt_lhs _ (L _ (LetStmt _ binds@(HsIPBinds {})))
- = failWith (badIpBinds (text "an mdo expression") binds)
+ = failWith (badIpBinds (Left binds))
+
rn_rec_stmt_lhs fix_env (L loc (LetStmt _ (HsValBinds x binds)))
= do (_bound_names, binds') <- rnLocalValBindsLHS fix_env binds
@@ -1541,7 +1528,7 @@ rn_rec_stmt ctxt rnBody _ (L loc (BindStmt _ pat' (L lb body)), fv_pat)
L loc (BindStmt xbsrn pat' (L lb body')))] }
rn_rec_stmt _ _ _ (L _ (LetStmt _ binds@(HsIPBinds {})), _)
- = failWith (badIpBinds (text "an mdo expression") binds)
+ = failWith (badIpBinds (Right binds))
rn_rec_stmt _ _ all_bndrs (L loc (LetStmt _ (HsValBinds x binds')), _)
= do { (binds', du_binds) <- rnLocalValBindsRHS (mkNameSet all_bndrs) binds'
@@ -1566,8 +1553,8 @@ rn_rec_stmt _ _ _ (L _ (LetStmt _ (EmptyLocalBinds _)), _)
rn_rec_stmt _ _ _ stmt@(L _ (ApplicativeStmt {}), _)
= pprPanic "rn_rec_stmt: ApplicativeStmt" (ppr stmt)
-rn_rec_stmts :: AnnoBody body =>
- HsStmtContext GhcRn
+rn_rec_stmts :: AnnoBody body
+ => HsStmtContext GhcRn
-> (body GhcPs -> RnM (body GhcRn, FreeVars))
-> [Name]
-> [(LStmtLR GhcRn GhcPs (LocatedA (body GhcPs)), FreeVars)]
@@ -1577,8 +1564,7 @@ rn_rec_stmts ctxt rnBody bndrs stmts
; return (concat segs_s) }
---------------------------------------------
-segmentRecStmts :: AnnoBody body
- => SrcSpan -> HsStmtContext GhcRn
+segmentRecStmts :: SrcSpan -> HsStmtContext GhcRn
-> Stmt GhcRn (LocatedA (body GhcRn))
-> [Segment (LStmt GhcRn (LocatedA (body GhcRn)))]
-> (FreeVars, Bool)
@@ -2457,24 +2443,18 @@ isReturnApp monad_names (L loc e) mb_pure = case e of
checkEmptyStmts :: HsStmtContext GhcRn -> RnM ()
-- We've seen an empty sequence of Stmts... is that ok?
checkEmptyStmts ctxt
- = unless (okEmpty ctxt) (addErr (emptyErr ctxt))
-
-okEmpty :: HsStmtContext a -> Bool
-okEmpty (PatGuard {}) = True
-okEmpty _ = False
-
-emptyErr :: HsStmtContext GhcRn -> TcRnMessage
-emptyErr (ParStmtCtxt {}) = mkTcRnUnknownMessage $ mkPlainError noHints $
- text "Empty statement group in parallel comprehension"
-emptyErr (TransStmtCtxt {}) = mkTcRnUnknownMessage $ mkPlainError noHints $
- text "Empty statement group preceding 'group' or 'then'"
-emptyErr ctxt@(HsDoStmt _) = mkTcRnUnknownMessage $ mkPlainError [suggestExtension LangExt.NondecreasingIndentation] $
- text "Empty" <+> pprStmtContext ctxt
-emptyErr ctxt = mkTcRnUnknownMessage $ mkPlainError noHints $
- text "Empty" <+> pprStmtContext ctxt
+ = mapM_ (addErr . TcRnEmptyStmtsGroup) mb_err
+ where
+ mb_err = case ctxt of
+ PatGuard {} -> Nothing -- Pattern guards can be empty
+ ParStmtCtxt {} -> Just EmptyStmtsGroupInParallelComp
+ TransStmtCtxt {} -> Just EmptyStmtsGroupInTransformListComp
+ HsDoStmt flav -> Just $ EmptyStmtsGroupInDoNotation flav
+ ArrowExpr -> Just EmptyStmtsGroupInArrowNotation
----------------------
-checkLastStmt :: AnnoBody body => HsStmtContext GhcRn
+checkLastStmt :: AnnoBody body
+ => HsStmtContext GhcRn
-> LStmt GhcPs (LocatedA (body GhcPs))
-> RnM (LStmt GhcPs (LocatedA (body GhcPs)))
checkLastStmt ctxt lstmt@(L loc stmt)
@@ -2491,12 +2471,10 @@ checkLastStmt ctxt lstmt@(L loc stmt)
BodyStmt _ e _ _ -> return (L loc (mkLastStmt e))
LastStmt {} -> return lstmt -- "Deriving" clauses may generate a
-- LastStmt directly (unlike the parser)
- _ -> do { addErr $ mkTcRnUnknownMessage
- $ mkPlainError noHints $
- (hang last_error 2 (ppr stmt))
+ _ -> do { addErr $ TcRnLastStmtNotExpr ctxt
+ $ UnexpectedStatement stmt
; return lstmt }
- last_error = (text "The last statement in" <+> pprAStmtContext ctxt
- <+> text "must be an expression")
+
check_comp -- Expect LastStmt; this should be enforced by the parser!
= case stmt of
@@ -2507,36 +2485,25 @@ checkLastStmt ctxt lstmt@(L loc stmt)
= do { checkStmt ctxt lstmt; return lstmt }
-- Checking when a particular Stmt is ok
-checkStmt :: HsStmtContext GhcRn
+checkStmt :: AnnoBody body
+ => HsStmtContext GhcRn
-> LStmt GhcPs (LocatedA (body GhcPs))
-> RnM ()
checkStmt ctxt (L _ stmt)
= do { dflags <- getDynFlags
; case okStmt dflags ctxt stmt of
- IsValid -> return ()
- NotValid extra -> addErr $ mkTcRnUnknownMessage
- $ mkPlainError noHints (msg $$ extra) }
- where
- msg = sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement"
- , text "in" <+> pprAStmtContext ctxt ]
-
-pprStmtCat :: Stmt (GhcPass a) body -> SDoc
-pprStmtCat (TransStmt {}) = text "transform"
-pprStmtCat (LastStmt {}) = text "return expression"
-pprStmtCat (BodyStmt {}) = text "body"
-pprStmtCat (BindStmt {}) = text "binding"
-pprStmtCat (LetStmt {}) = text "let"
-pprStmtCat (RecStmt {}) = text "rec"
-pprStmtCat (ParStmt {}) = text "parallel"
-pprStmtCat (ApplicativeStmt {}) = panic "pprStmtCat: ApplicativeStmt"
+ IsValid -> return ()
+ NotValid ext -> addErr $
+ TcRnUnexpectedStatementInContext
+ ctxt (UnexpectedStatement stmt) ext }
------------
-emptyInvalid :: Validity -- Payload is the empty document
-emptyInvalid = NotValid Outputable.empty
+emptyInvalid :: Validity' (Maybe LangExt.Extension)
+emptyInvalid = NotValid Nothing -- Invalid, and no extension to suggest
okStmt, okDoStmt, okCompStmt, okParStmt
:: DynFlags -> HsStmtContext GhcRn
- -> Stmt GhcPs (LocatedA (body GhcPs)) -> Validity
+ -> Stmt GhcPs (LocatedA (body GhcPs)) -> Validity' (Maybe LangExt.Extension)
-- Return Nothing if OK, (Just extra) if not ok
-- The "extra" is an SDoc that is appended to a generic error message
@@ -2550,7 +2517,7 @@ okStmt dflags ctxt stmt
okDoFlavourStmt
:: DynFlags -> HsDoFlavour -> HsStmtContext GhcRn
- -> Stmt GhcPs (LocatedA (body GhcPs)) -> Validity
+ -> Stmt GhcPs (LocatedA (body GhcPs)) -> Validity' (Maybe LangExt.Extension)
okDoFlavourStmt dflags flavour ctxt stmt = case flavour of
DoExpr{} -> okDoStmt dflags ctxt stmt
MDoExpr{} -> okDoStmt dflags ctxt stmt
@@ -2559,7 +2526,7 @@ okDoFlavourStmt dflags flavour ctxt stmt = case flavour of
MonadComp -> okCompStmt dflags ctxt stmt
-------------
-okPatGuardStmt :: Stmt GhcPs (LocatedA (body GhcPs)) -> Validity
+okPatGuardStmt :: Stmt GhcPs (LocatedA (body GhcPs)) -> Validity' (Maybe LangExt.Extension)
okPatGuardStmt stmt
= case stmt of
BodyStmt {} -> IsValid
@@ -2579,7 +2546,7 @@ okDoStmt dflags ctxt stmt
RecStmt {}
| LangExt.RecursiveDo `xopt` dflags -> IsValid
| ArrowExpr <- ctxt -> IsValid -- Arrows allows 'rec'
- | otherwise -> NotValid (text "Use RecursiveDo")
+ | otherwise -> NotValid (Just LangExt.RecursiveDo)
BindStmt {} -> IsValid
LetStmt {} -> IsValid
BodyStmt {} -> IsValid
@@ -2593,10 +2560,10 @@ okCompStmt dflags _ stmt
BodyStmt {} -> IsValid
ParStmt {}
| LangExt.ParallelListComp `xopt` dflags -> IsValid
- | otherwise -> NotValid (text "Use ParallelListComp")
+ | otherwise -> NotValid (Just LangExt.ParallelListComp)
TransStmt {}
| LangExt.TransformListComp `xopt` dflags -> IsValid
- | otherwise -> NotValid (text "Use TransformListComp")
+ | otherwise -> NotValid (Just LangExt.TransformListComp)
RecStmt {} -> emptyInvalid
LastStmt {} -> emptyInvalid -- Should not happen (dealt with by checkLastStmt)
ApplicativeStmt {} -> emptyInvalid
@@ -2608,21 +2575,14 @@ checkTupleSection args
; checkErr (all tupArgPresent args || tuple_section) msg }
where
msg :: TcRnMessage
- msg = mkTcRnUnknownMessage $ mkPlainError noHints $
- text "Illegal tuple section: use TupleSections"
+ msg = TcRnIllegalTupleSection
---------
sectionErr :: HsExpr GhcPs -> TcRnMessage
-sectionErr expr
- = mkTcRnUnknownMessage $ mkPlainError noHints $
- hang (text "A section must be enclosed in parentheses")
- 2 (text "thus:" <+> (parens (ppr expr)))
-
-badIpBinds :: Outputable a => SDoc -> a -> TcRnMessage
-badIpBinds what binds
- = mkTcRnUnknownMessage $ mkPlainError noHints $
- hang (text "Implicit-parameter bindings illegal in" <+> what)
- 2 (ppr binds)
+sectionErr = TcRnSectionWithoutParentheses
+
+badIpBinds :: Either (HsLocalBindsLR GhcPs GhcPs) (HsLocalBindsLR GhcRn GhcPs) -> TcRnMessage
+badIpBinds = TcRnIllegalImplicitParameterBindings
---------
=====================================
compiler/GHC/Rename/Expr.hs-boot
=====================================
@@ -1,12 +1,6 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ConstraintKinds #-}
module GHC.Rename.Expr where
-#if MIN_VERSION_GLASGOW_HASKELL(9,3,0,0)
-import Data.Type.Equality (type (~))
-#endif
-
import GHC.Types.Name
import GHC.Hs
import GHC.Types.Name.Set ( FreeVars )
@@ -21,10 +15,8 @@ rnLExpr :: LHsExpr GhcPs
type AnnoBody body
= ( Outputable (body GhcPs)
- , Anno (StmtLR GhcPs GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA
- , Anno (StmtLR GhcRn GhcPs (LocatedA (body GhcPs))) ~ SrcSpanAnnA
- , Anno (StmtLR GhcRn GhcRn (LocatedA (body GhcRn))) ~ SrcSpanAnnA
)
+
rnStmts :: --forall thing body.
AnnoBody body => HsStmtContext GhcRn
-> (body GhcPs -> RnM (body GhcRn, FreeVars))
=====================================
compiler/GHC/Rename/Utils.hs
=====================================
@@ -1,5 +1,6 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE GADTs #-}
{-
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -1181,6 +1181,49 @@ instance Diagnostic TcRnMessage where
TcRnNotOpenFamily tc
-> mkSimpleDecorated $
text "Illegal instance for closed family" <+> quotes (ppr tc)
+ TcRnNoRebindableSyntaxRecordDot -> mkSimpleDecorated $
+ text "RebindableSyntax is required if OverloadedRecordUpdate is enabled."
+ TcRnNoFieldPunsRecordDot -> mkSimpleDecorated $
+ text "For this to work enable NamedFieldPuns"
+ TcRnIllegalStaticExpression e -> mkSimpleDecorated $
+ text "Illegal static expression:" <+> ppr e
+ TcRnIllegalStaticFormInSplice e -> mkSimpleDecorated $
+ sep [ text "static forms cannot be used in splices:"
+ , nest 2 $ ppr e
+ ]
+ TcRnListComprehensionDuplicateBinding n -> mkSimpleDecorated $
+ (text "Duplicate binding in parallel list comprehension for:"
+ <+> quotes (ppr n))
+ TcRnEmptyStmtsGroup cause -> mkSimpleDecorated $ case cause of
+ EmptyStmtsGroupInParallelComp ->
+ text "Empty statement group in parallel comprehension"
+ EmptyStmtsGroupInTransformListComp ->
+ text "Empty statement group preceding 'group' or 'then'"
+ EmptyStmtsGroupInDoNotation ctxt ->
+ text "Empty" <+> pprHsDoFlavour ctxt
+ EmptyStmtsGroupInArrowNotation ->
+ text "Empty 'do' block in an arrow command"
+ TcRnLastStmtNotExpr ctxt (UnexpectedStatement stmt) ->
+ mkSimpleDecorated $ hang last_error 2 (ppr stmt)
+ where
+ last_error =
+ text "The last statement in" <+> pprAStmtContext ctxt
+ <+> text "must be an expression"
+ TcRnUnexpectedStatementInContext ctxt (UnexpectedStatement stmt) _ -> mkSimpleDecorated $
+ sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement"
+ , text "in" <+> pprAStmtContext ctxt ]
+ TcRnIllegalTupleSection -> mkSimpleDecorated $
+ text "Illegal tuple section"
+ TcRnIllegalImplicitParameterBindings eBinds -> mkSimpleDecorated $
+ either msg msg eBinds
+ where
+ msg binds = hang
+ (text "Implicit-parameter bindings illegal in an mdo expression")
+ 2 (ppr binds)
+ TcRnSectionWithoutParentheses expr -> mkSimpleDecorated $
+ hang (text "A section must be enclosed in parentheses")
+ 2 (text "thus:" <+> (parens (ppr expr)))
+
diagnosticReason = \case
TcRnUnknownMessage m
@@ -1563,6 +1606,28 @@ instance Diagnostic TcRnMessage where
-> ErrorWithoutFlag
TcRnNotOpenFamily{}
-> ErrorWithoutFlag
+ TcRnNoRebindableSyntaxRecordDot{}
+ -> ErrorWithoutFlag
+ TcRnNoFieldPunsRecordDot{}
+ -> ErrorWithoutFlag
+ TcRnIllegalStaticExpression{}
+ -> ErrorWithoutFlag
+ TcRnIllegalStaticFormInSplice{}
+ -> ErrorWithoutFlag
+ TcRnListComprehensionDuplicateBinding{}
+ -> ErrorWithoutFlag
+ TcRnEmptyStmtsGroup{}
+ -> ErrorWithoutFlag
+ TcRnLastStmtNotExpr{}
+ -> ErrorWithoutFlag
+ TcRnUnexpectedStatementInContext{}
+ -> ErrorWithoutFlag
+ TcRnSectionWithoutParentheses{}
+ -> ErrorWithoutFlag
+ TcRnIllegalImplicitParameterBindings{}
+ -> ErrorWithoutFlag
+ TcRnIllegalTupleSection{}
+ -> ErrorWithoutFlag
diagnosticHints = \case
TcRnUnknownMessage m
@@ -1947,6 +2012,32 @@ instance Diagnostic TcRnMessage where
-> [suggestExtension LangExt.TypeFamilies]
TcRnNotOpenFamily{}
-> noHints
+ TcRnNoRebindableSyntaxRecordDot{}
+ -> noHints
+ TcRnNoFieldPunsRecordDot{}
+ -> noHints
+ TcRnIllegalStaticExpression{}
+ -> [suggestExtension LangExt.StaticPointers]
+ TcRnIllegalStaticFormInSplice{}
+ -> noHints
+ TcRnListComprehensionDuplicateBinding{}
+ -> noHints
+ TcRnEmptyStmtsGroup EmptyStmtsGroupInDoNotation{}
+ -> [suggestExtension LangExt.NondecreasingIndentation]
+ TcRnEmptyStmtsGroup{}
+ -> noHints
+ TcRnLastStmtNotExpr{}
+ -> noHints
+ TcRnUnexpectedStatementInContext _ _ mExt
+ | Nothing <- mExt -> noHints
+ | Just ext <- mExt -> [suggestExtension ext]
+ TcRnSectionWithoutParentheses{}
+ -> noHints
+ TcRnIllegalImplicitParameterBindings{}
+ -> noHints
+ TcRnIllegalTupleSection{}
+ -> [suggestExtension LangExt.TupleSections]
+
diagnosticCode = constructorCode
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -1,4 +1,5 @@
{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
@@ -85,6 +86,8 @@ module GHC.Tc.Errors.Types (
, RunSpliceFailReason(..)
, ThingBeingConverted(..)
, IllegalDecls(..)
+ , EmptyStatementGroupErrReason(..)
+ , UnexpectedStatement(..)
) where
import GHC.Prelude
@@ -2631,6 +2634,133 @@ data TcRnMessage where
testsuite/tests/indexed-types/should_fail/Overlap3
-}
TcRnNotOpenFamily :: TyCon -> TcRnMessage
+ {-| TcRnNoRebindableSyntaxRecordDot is an error triggered by an overloaded record update
+ without RebindableSyntax enabled.
+
+ Example(s):
+
+ Test cases: parser/should_fail/RecordDotSyntaxFail5
+ -}
+ TcRnNoRebindableSyntaxRecordDot :: TcRnMessage
+
+ {-| TcRnNoFieldPunsRecordDot is an error triggered by the use of record field puns
+ in an overloaded record update without enabling NamedFieldPuns.
+
+ Example(s):
+ print $ a{ foo.bar.baz.quux }
+
+ Test cases: parser/should_fail/RecordDotSyntaxFail12
+ -}
+ TcRnNoFieldPunsRecordDot :: TcRnMessage
+
+ {-| TcRnIllegalStaticExpression is an error thrown when user creates a static
+ pointer via TemplateHaskell without enabling the StaticPointers extension.
+
+ Example(s):
+
+ Test cases: th/T14204
+ -}
+ TcRnIllegalStaticExpression :: HsExpr GhcPs -> TcRnMessage
+
+ {-| TcRnIllegalStaticFormInSplice is an error when a user attempts to define
+ a static pointer in a Template Haskell splice.
+
+ Example(s):
+
+ Test cases: th/TH_StaticPointers02
+ -}
+ TcRnIllegalStaticFormInSplice :: HsExpr GhcPs -> TcRnMessage
+
+ {-| TcRnListComprehensionDuplicateBinding is an error triggered by duplicate
+ let-bindings in a list comprehension.
+
+ Example(s):
+ [ () | let a = 13 | let a = 17 ]
+
+ Test cases: typecheck/should_fail/tcfail092
+ -}
+ TcRnListComprehensionDuplicateBinding :: Name -> TcRnMessage
+
+ {-| TcRnEmptyStmtsGroup is an error triggered by an empty list of statements
+ in a statement block. For more information, see 'EmptyStatementGroupErrReason'
+
+ Example(s):
+
+ [() | then ()]
+
+ do
+
+ proc () -> do
+
+ Test cases: rename/should_fail/RnEmptyStatementGroup1
+ -}
+ TcRnEmptyStmtsGroup:: EmptyStatementGroupErrReason -> TcRnMessage
+
+ {-| TcRnLastStmtNotExpr is an error caused by the last statement
+ in a statement block not being an expression.
+
+ Example(s):
+
+ do x <- pure ()
+
+ do let x = 5
+
+ Test cases: rename/should_fail/T6060
+ parser/should_fail/T3811g
+ parser/should_fail/readFail028
+ -}
+ TcRnLastStmtNotExpr
+ :: HsStmtContext GhcRn
+ -> UnexpectedStatement
+ -> TcRnMessage
+
+ {-| TcRnUnexpectedStatementInContext is an error when a statement appears
+ in an unexpected context (e.g. an arrow statement appears in a list comprehension).
+
+ Example(s):
+
+ Test cases: parser/should_fail/readFail042
+ parser/should_fail/readFail038
+ parser/should_fail/readFail043
+ -}
+ TcRnUnexpectedStatementInContext
+ :: HsStmtContext GhcRn
+ -> UnexpectedStatement
+ -> Maybe LangExt.Extension
+ -> TcRnMessage
+
+ {-| TcRnIllegalTupleSection is an error triggered by usage of a tuple section
+ without enabling the TupleSections extension.
+
+ Example(s):
+ (5,)
+
+ Test cases: rename/should_fail/rnfail056
+ -}
+ TcRnIllegalTupleSection :: TcRnMessage
+
+ {-| TcRnIllegalImplicitParameterBindings is an error triggered by binding
+ an implicit parameter in an mdo block.
+
+ Example(s):
+ mdo { let { ?x = 5 }; () }
+
+ Test cases: rename/should_fail/RnImplicitBindInMdoNotation
+ -}
+ TcRnIllegalImplicitParameterBindings
+ :: Either (HsLocalBindsLR GhcPs GhcPs) (HsLocalBindsLR GhcRn GhcPs)
+ -> TcRnMessage
+
+ {-| TcRnSectionWithoutParentheses is an error triggered by attempting to
+ use an operator section without parentheses.
+
+ Example(s):
+ (`head` x, ())
+
+ Test cases: rename/should_fail/T2490
+ rename/should_fail/T5657
+ -}
+ TcRnSectionWithoutParentheses :: HsExpr GhcPs -> TcRnMessage
deriving Generic
@@ -3833,3 +3963,32 @@ data LookupTHInstNameErrReason
data UnrepresentableTypeDescr
= LinearInvisibleArgument
| CoercionsInTypes
+
+-- | The context for an "empty statement group" error.
+data EmptyStatementGroupErrReason
+ = EmptyStmtsGroupInParallelComp
+ -- ^ Empty statement group in a parallel list comprehension
+ | EmptyStmtsGroupInTransformListComp
+ -- ^ Empty statement group in a transform list comprehension
+ --
+ -- Example:
+ -- [() | then ()]
+ | EmptyStmtsGroupInDoNotation HsDoFlavour
+ -- ^ Empty statement group in do notation
+ --
+ -- Example:
+ -- do
+ | EmptyStmtsGroupInArrowNotation
+ -- ^ Empty statement group in arrow notation
+ --
+ -- Example:
+ -- proc () -> do
+
+ deriving (Generic)
+
+-- | An existential wrapper around @'StmtLR' GhcPs GhcPs body at .
+data UnexpectedStatement where
+ UnexpectedStatement
+ :: Outputable (StmtLR GhcPs GhcPs body)
+ => StmtLR GhcPs GhcPs body
+ -> UnexpectedStatement
=====================================
compiler/GHC/Types/Error/Codes.hs
=====================================
@@ -422,6 +422,16 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "TcRnIllegalTypeOperator" = 62547
GhcDiagnosticCode "TcRnGADTMonoLocalBinds" = 58008
GhcDiagnosticCode "TcRnIncorrectNameSpace" = 31891
+ GhcDiagnosticCode "TcRnNoRebindableSyntaxRecordDot" = 65945
+ GhcDiagnosticCode "TcRnNoFieldPunsRecordDot" = 57365
+ GhcDiagnosticCode "TcRnIllegalStaticExpression" = 23800
+ GhcDiagnosticCode "TcRnIllegalStaticFormInSplice" = 12219
+ GhcDiagnosticCode "TcRnListComprehensionDuplicateBinding" = 81232
+ GhcDiagnosticCode "TcRnLastStmtNotExpr" = 55814
+ GhcDiagnosticCode "TcRnUnexpectedStatementInContext" = 42026
+ GhcDiagnosticCode "TcRnSectionWithoutParentheses" = 95880
+ GhcDiagnosticCode "TcRnIllegalImplicitParameterBindings" = 50730
+ GhcDiagnosticCode "TcRnIllegalTupleSection" = 59155
GhcDiagnosticCode "TcRnUntickedPromotedThing" = 49957
GhcDiagnosticCode "TcRnIllegalBuiltinSyntax" = 39716
@@ -580,6 +590,12 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "DerivErrGenerics" = 30367
GhcDiagnosticCode "DerivErrEnumOrProduct" = 58291
+ -- TcRnEmptyStmtsGroupError/EmptyStatementGroupErrReason
+ GhcDiagnosticCode "EmptyStmtsGroupInParallelComp" = 41242
+ GhcDiagnosticCode "EmptyStmtsGroupInTransformListComp" = 92693
+ GhcDiagnosticCode "EmptyStmtsGroupInDoNotation" = 82311
+ GhcDiagnosticCode "EmptyStmtsGroupInArrowNotation" = 19442
+
-- To generate new random numbers:
-- https://www.random.org/integers/?num=10&min=1&max=99999&col=1&base=10&format=plain
--
@@ -671,6 +687,8 @@ type family ConRecursInto con where
-- Recur inside Mismatch to get the underlying reason
ConRecursInto "Mismatch" = 'Just MismatchMsg
+ -- Recur inside empty statements groups to get the underlying statements block
+ ConRecursInto "TcRnEmptyStmtsGroup" = 'Just EmptyStatementGroupErrReason
----------------------------------
-- Constructors of DsMessage
=====================================
testsuite/tests/ghci/prog011/prog011.stderr
=====================================
@@ -1,4 +1,4 @@
-prog011.hx:14:22: error:
+prog011.hx:14:22: [GHC-82311] error:
Empty 'do' block
Suggested fix: Perhaps you intended to use NondecreasingIndentation
=====================================
testsuite/tests/parser/should_fail/NondecreasingIndentationFail.stderr
=====================================
@@ -1,7 +1,8 @@
-NondecreasingIndentationFail.hs:7:28:
+NondecreasingIndentationFail.hs:7:28: [GHC-82311]
Empty 'do' block
Suggested fix: Perhaps you intended to use NondecreasingIndentation
-NondecreasingIndentationFail.hs:9:28:
+
+NondecreasingIndentationFail.hs:9:28: [GHC-82311]
Empty 'do' block
Suggested fix: Perhaps you intended to use NondecreasingIndentation
=====================================
testsuite/tests/parser/should_fail/RecordDotSyntaxFail12.stderr
=====================================
@@ -11,26 +11,26 @@ RecordDotSyntaxFail12.hs:124:65: error: [GHC-44287]
Illegal use of punning for field ‘bar’
Suggested fix: Perhaps you intended to use NamedFieldPuns
-RecordDotSyntaxFail12.hs:125:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:125:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:126:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:126:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:127:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:127:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:128:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:128:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:130:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:130:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:133:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:133:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:134:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:134:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
-RecordDotSyntaxFail12.hs:135:11: error:
- For this to work enable NamedFieldPuns.
+RecordDotSyntaxFail12.hs:135:11: error: [GHC-57365]
+ For this to work enable NamedFieldPuns
=====================================
testsuite/tests/parser/should_fail/RecordDotSyntaxFail5.stderr
=====================================
@@ -1,2 +1,2 @@
-RecordDotSyntaxFail5.hs:17:11:
+RecordDotSyntaxFail5.hs:17:11: [GHC-65945]
RebindableSyntax is required if OverloadedRecordUpdate is enabled.
=====================================
testsuite/tests/parser/should_fail/T3811g.stderr
=====================================
@@ -1,4 +1,4 @@
-T3811g.hs:6:8:
+T3811g.hs:6:8: [GHC-55814]
The last statement in a 'do' block must be an expression
_ <- return ()
=====================================
testsuite/tests/parser/should_fail/readFail028.stderr
=====================================
@@ -1,4 +1,4 @@
-readFail028.hs:4:11:
+readFail028.hs:4:11: [GHC-55814]
The last statement in a 'do' block must be an expression
x <- return ()
=====================================
testsuite/tests/parser/should_fail/readFail038.stderr
=====================================
@@ -1,4 +1,4 @@
-readFail038.hs:5:9:
+readFail038.hs:5:9: [GHC-42026]
Unexpected parallel statement in a list comprehension
- Use ParallelListComp
+ Suggested fix: Perhaps you intended to use ParallelListComp
=====================================
testsuite/tests/parser/should_fail/readFail042.stderr
=====================================
@@ -1,8 +1,8 @@
-readFail042.hs:9:9: error:
+readFail042.hs:9:9: [GHC-42026] error:
Unexpected transform statement in a list comprehension
- Use TransformListComp
+ Suggested fix: Perhaps you intended to use TransformListComp
-readFail042.hs:9:9: error:
+readFail042.hs:9:9: [GHC-42026] error:
Unexpected transform statement in a list comprehension
- Use TransformListComp
+ Suggested fix: Perhaps you intended to use TransformListComp
=====================================
testsuite/tests/parser/should_fail/readFail043.stderr
=====================================
@@ -1,12 +1,12 @@
-readFail043.hs:9:9: error:
+readFail043.hs:9:9: [GHC-42026] error:
Unexpected transform statement in a list comprehension
- Use TransformListComp
+ Suggested fix: Perhaps you intended to use TransformListComp
-readFail043.hs:9:9: error:
+readFail043.hs:9:9: [GHC-42026] error:
Unexpected transform statement in a list comprehension
- Use TransformListComp
+ Suggested fix: Perhaps you intended to use TransformListComp
-readFail043.hs:9:9: error:
+readFail043.hs:9:9: [GHC-42026] error:
Unexpected transform statement in a list comprehension
- Use TransformListComp
+ Suggested fix: Perhaps you intended to use TransformListComp
=====================================
testsuite/tests/rename/should_fail/RnEmptyStatementGroup1.hs
=====================================
@@ -0,0 +1,10 @@
+{-# LANGUAGE TransformListComp #-}
+{-# LANGUAGE Arrows #-}
+
+module ShouldFail where
+
+one = [() | then ()]
+
+two = do
+
+three = proc () -> do
=====================================
testsuite/tests/rename/should_fail/RnEmptyStatementGroup1.stderr
=====================================
@@ -0,0 +1,10 @@
+
+RnEmptyStatementGroup1.hs:6:13: error: [GHC-92693]
+ Empty statement group preceding 'group' or 'then'
+
+RnEmptyStatementGroup1.hs:8:7: error: [GHC-82311]
+ Empty 'do' block
+ Suggested fix: Perhaps you intended to use NondecreasingIndentation
+
+RnEmptyStatementGroup1.hs:10:20: error: [GHC-19442]
+ Empty 'do' block in an arrow command
=====================================
testsuite/tests/rename/should_fail/RnImplicitBindInMdoNotation.hs
=====================================
@@ -0,0 +1,8 @@
+{-# LANGUAGE RecursiveDo #-}
+{-# LANGUAGE ImplicitParams #-}
+
+module ShouldFail where
+
+x = mdo
+ let ?x = 5
+ ()
=====================================
testsuite/tests/rename/should_fail/RnImplicitBindInMdoNotation.stderr
=====================================
@@ -0,0 +1,3 @@
+
+RnImplicitBindInMdoNotation.hs:6:5: error: [GHC-50730]
+ Implicit-parameter bindings illegal in an mdo expression ?x = 5
=====================================
testsuite/tests/rename/should_fail/T20147.stderr
=====================================
@@ -1,4 +1,4 @@
-T20147.hs:6:28: error:
+T20147.hs:6:28: error: [GHC-82311]
Empty 'do' block
Suggested fix: Perhaps you intended to use NondecreasingIndentation
=====================================
testsuite/tests/rename/should_fail/T2490.stderr
=====================================
@@ -1,15 +1,15 @@
-T2490.hs:6:10:
+T2490.hs:6:10: [GHC-95880]
A section must be enclosed in parentheses thus: (`head` x)
-T2490.hs:7:10:
+T2490.hs:7:10: [GHC-95880]
A section must be enclosed in parentheses thus: (+ x)
-T2490.hs:8:14:
+T2490.hs:8:14: [GHC-95880]
A section must be enclosed in parentheses thus: (+ x)
-T2490.hs:9:14:
+T2490.hs:9:14: [GHC-95880]
A section must be enclosed in parentheses thus: (+ x)
-T2490.hs:10:14:
+T2490.hs:10:14: [GHC-95880]
A section must be enclosed in parentheses thus: (x +)
=====================================
testsuite/tests/rename/should_fail/T5657.stderr
=====================================
@@ -3,5 +3,5 @@ T5657.hs:3:8: error: [GHC-76037]
Not in scope: ‘LT..’
NB: no module named ‘LT’ is imported.
-T5657.hs:3:8: error:
+T5657.hs:3:8: error: [GHC-95880]
A section must be enclosed in parentheses thus: (LT.. GT)
=====================================
testsuite/tests/rename/should_fail/T6060.stderr
=====================================
@@ -1,4 +1,4 @@
-T6060.hs:5:10:
+T6060.hs:5:10: [GHC-55814]
The last statement in a 'do' block must be an expression
let bad = [True | x <- [] | y <- []]
=====================================
testsuite/tests/rename/should_fail/all.T
=====================================
@@ -177,3 +177,6 @@ test('T19843m', normal, compile_fail, [''])
test('T11167_ambig', normal, compile_fail, [''])
test('T18138', normal, compile_fail, [''])
test('T20147', normal, compile_fail, [''])
+
+test('RnEmptyStatementGroup1', normal, compile_fail, [''])
+test('RnImplicitBindInMdoNotation', normal, compile_fail, [''])
=====================================
testsuite/tests/rename/should_fail/rnfail056.stderr
=====================================
@@ -1,4 +1,8 @@
-rnfail056.hs:7:7: error: Illegal tuple section: use TupleSections
+rnfail056.hs:7:7: [GHC-59155] error:
+ Illegal tuple section
+ Suggested fix: Perhaps you intended to use TupleSections
-rnfail056.hs:9:7: error: Illegal tuple section: use TupleSections
+rnfail056.hs:9:7: [GHC-59155] error:
+ Illegal tuple section
+ Suggested fix: Perhaps you intended to use TupleSections
=====================================
testsuite/tests/th/T14204.stderr
=====================================
@@ -1,5 +1,5 @@
-T14204.hs:8:34: error:
+T14204.hs:8:34: [GHC-23800] error:
• Illegal static expression: static "wat"
- Use StaticPointers to enable this extension
• In the untyped splice: $(pure (StaticE (LitE (StringL "wat"))))
+ Suggested fix: Perhaps you intended to use StaticPointers
=====================================
testsuite/tests/th/TH_StaticPointers02.stderr
=====================================
@@ -1,5 +1,5 @@
-TH_StaticPointers02.hs:11:34: error:
+TH_StaticPointers02.hs:11:34: [GHC-12219] error:
• static forms cannot be used in splices: static 'a'
• In the untyped splice:
$(case staticKey (static 'a') of
=====================================
testsuite/tests/typecheck/should_fail/tcfail092.stderr
=====================================
@@ -1,3 +1,3 @@
-tcfail092.hs:7:27:
+tcfail092.hs:7:27: [GHC-81232]
Duplicate binding in parallel list comprehension for: ‘a’
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86ff1523d21f27f69351f8a2d053ba9d5d98aa89
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86ff1523d21f27f69351f8a2d053ba9d5d98aa89
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20221124/946a9101/attachment-0001.html>
More information about the ghc-commits
mailing list