Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
a9827d13
by Simon Jakobi at 2026-09-11T18:53:32-04:00
-
c71d5e23
by Alan Zimmerman at 2026-09-11T18:54:11-04:00
-
edfc736b
by Simon Jakobi at 2026-09-12T15:25:34-04:00
-
95d56c33
by Alan Zimmerman at 2026-09-12T15:25:35-04:00
30 changed files:
- + changelog.d/27732
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Tc/Errors/Types.hs
- docs/users_guide/exts/type_data.rst
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/printer/Test20297.stdout
- + testsuite/tests/type-data/should_fail/T27732a.hs
- + testsuite/tests/type-data/should_fail/T27732a.stderr
- + testsuite/tests/type-data/should_fail/T27732b.hs
- + testsuite/tests/type-data/should_fail/T27732b.stderr
- + testsuite/tests/type-data/should_fail/T27732c.hs
- + testsuite/tests/type-data/should_fail/T27732c.stderr
- + testsuite/tests/type-data/should_fail/T27732d.hs
- + testsuite/tests/type-data/should_fail/T27732d.stderr
- + testsuite/tests/type-data/should_fail/T27732e.hs
- + testsuite/tests/type-data/should_fail/T27732e.stderr
- + testsuite/tests/type-data/should_fail/T27732f.hs
- + testsuite/tests/type-data/should_fail/T27732f.stderr
- testsuite/tests/type-data/should_fail/TDStrictnessGADT.stderr
- testsuite/tests/type-data/should_fail/TDStrictnessH98.stderr
- testsuite/tests/type-data/should_fail/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Utils.hs
Changes:
| 1 | +section: language
|
|
| 2 | +synopsis: Reject ``~``, ``UNPACK`` and multiplicity annotations on ``type data`` fields
|
|
| 3 | +description:
|
|
| 4 | + ``type data`` declarations (:extension:`TypeData`) now reject any
|
|
| 5 | + strictness, unpackedness or multiplicity annotation on constructor
|
|
| 6 | + fields. Previously only ``!`` was rejected.
|
|
| 7 | +mrs: !16563
|
|
| 8 | +issues: #27732 |
| ... | ... | @@ -320,7 +320,7 @@ data FastStringTable = FastStringTable |
| 320 | 320 | -- ^ Number of computed z-encodings for all buckets.
|
| 321 | 321 | --
|
| 322 | 322 | -- We mark this as 'NOUNPACK' as this 'FastMutInt' is retained by a thunk
|
| 323 | - -- in 'mkFastStringWith' and needs to be boxed any way.
|
|
| 323 | + -- in 'internSB' and needs to be boxed any way.
|
|
| 324 | 324 | -- If this is unpacked, then we box this single 'FastMutInt' once for each
|
| 325 | 325 | -- allocated FastString.
|
| 326 | 326 | (Array# (IORef FastStringTableSegment)) -- ^ concurrent segments
|
| ... | ... | @@ -474,9 +474,10 @@ The procedure goes like this: |
| 474 | 474 | * Otherwise, insert and return the string we created.
|
| 475 | 475 | -}
|
| 476 | 476 | |
| 477 | -mkFastStringWith
|
|
| 478 | - :: (Int -> FastMutInt-> IO FastString) -> ShortByteString -> IO FastString
|
|
| 479 | -mkFastStringWith mk_fs sbs = do
|
|
| 477 | +-- | Return the interned 'FastString' for the given bytes, creating and
|
|
| 478 | +-- inserting one on a table miss.
|
|
| 479 | +internSB :: ShortByteString -> IO FastString
|
|
| 480 | +internSB sbs = do
|
|
| 480 | 481 | FastStringTableSegment lock _ buckets# <- readIORef segmentRef
|
| 481 | 482 | let idx# = hashToIndex# buckets# hash#
|
| 482 | 483 | bucket <- IO $ readArray# buckets# idx#
|
| ... | ... | @@ -487,7 +488,7 @@ mkFastStringWith mk_fs sbs = do |
| 487 | 488 | -- only run partially and putMVar is not called after takeMVar.
|
| 488 | 489 | noDuplicate
|
| 489 | 490 | n <- get_uid
|
| 490 | - new_fs <- mk_fs n n_zencs
|
|
| 491 | + new_fs <- mkNewFastStringShortByteString sbs n n_zencs
|
|
| 491 | 492 | withMVar lock $ \_ -> insert new_fs
|
| 492 | 493 | where
|
| 493 | 494 | !(FastStringTable uid n_zencs segments#) = stringTable
|
| ... | ... | @@ -523,11 +524,11 @@ bucket_match fs sbs = go fs |
| 523 | 524 | |
| 524 | 525 | mkFastStringBytes :: Ptr Word8 -> Int -> FastString
|
| 525 | 526 | mkFastStringBytes !ptr !len =
|
| 526 | - -- NB: Might as well use unsafeDupablePerformIO, since mkFastStringWith is
|
|
| 527 | + -- NB: Might as well use unsafeDupablePerformIO, since internSB is
|
|
| 527 | 528 | -- idempotent.
|
| 528 | 529 | unsafeDupablePerformIO $ do
|
| 529 | 530 | sbs <- newSBSFromPtr ptr len
|
| 530 | - mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 531 | + internSB sbs
|
|
| 531 | 532 | |
| 532 | 533 | newSBSFromPtr :: Ptr a -> Int -> IO ShortByteString
|
| 533 | 534 | newSBSFromPtr (Ptr src#) (I# len#) =
|
| ... | ... | @@ -541,14 +542,13 @@ newSBSFromPtr (Ptr src#) (I# len#) = |
| 541 | 542 | mkFastStringByteString :: ByteString -> FastString
|
| 542 | 543 | mkFastStringByteString bs =
|
| 543 | 544 | let sbs = SBS.toShort bs in
|
| 544 | - inlinePerformIO $
|
|
| 545 | - mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 545 | + inlinePerformIO $ internSB sbs
|
|
| 546 | 546 | |
| 547 | 547 | -- | Create a 'FastString' from an existing 'ShortByteString' without
|
| 548 | 548 | -- copying.
|
| 549 | 549 | mkFastStringShortByteString :: ShortByteString -> FastString
|
| 550 | 550 | mkFastStringShortByteString sbs =
|
| 551 | - inlinePerformIO $ mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 551 | + inlinePerformIO $ internSB sbs
|
|
| 552 | 552 | |
| 553 | 553 | -- | Create a 'FastString' from an 'HText'
|
| 554 | 554 | mkFastStringShortText :: ShortText -> FastString
|
| ... | ... | @@ -560,7 +560,7 @@ mkFastString :: String -> FastString |
| 560 | 560 | mkFastString str =
|
| 561 | 561 | inlinePerformIO $ do
|
| 562 | 562 | let !sbs = utf8EncodeShortByteString str
|
| 563 | - mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
|
|
| 563 | + internSB sbs
|
|
| 564 | 564 | |
| 565 | 565 | -- The following rule is used to avoid polluting the non-reclaimable FastString
|
| 566 | 566 | -- table with transient strings when we only want their encoding.
|
| ... | ... | @@ -290,10 +290,12 @@ type instance XLet GhcPs = (EpToken "let", EpToken "in") |
| 290 | 290 | type instance XLet GhcRn = NoExtField
|
| 291 | 291 | type instance XLet GhcTc = NoExtField
|
| 292 | 292 | |
| 293 | -type instance XDo GhcPs = (AnnList, EpaLocation)
|
|
| 293 | +type instance XDo GhcPs = DoAnn
|
|
| 294 | 294 | type instance XDo GhcRn = NoExtField
|
| 295 | 295 | type instance XDo GhcTc = Type
|
| 296 | 296 | |
| 297 | +type DoAnn = (Either (EpToken "[", EpToken "]") AnnList, EpaLocation)
|
|
| 298 | + |
|
| 297 | 299 | type instance XExplicitList GhcPs = (EpToken "[", EpToken "]")
|
| 298 | 300 | type instance XExplicitList GhcRn = NoExtField
|
| 299 | 301 | type instance XExplicitList GhcTc = Type
|
| ... | ... | @@ -1467,7 +1469,7 @@ type instance XCmdLet GhcPs = (EpToken "let", EpToken "in") |
| 1467 | 1469 | type instance XCmdLet GhcRn = NoExtField
|
| 1468 | 1470 | type instance XCmdLet GhcTc = NoExtField
|
| 1469 | 1471 | |
| 1470 | -type instance XCmdDo GhcPs = (AnnList, EpaLocation)
|
|
| 1472 | +type instance XCmdDo GhcPs = DoAnn
|
|
| 1471 | 1473 | type instance XCmdDo GhcRn = NoExtField
|
| 1472 | 1474 | type instance XCmdDo GhcTc = Type
|
| 1473 | 1475 |
| ... | ... | @@ -335,11 +335,10 @@ mkHsIntegral :: IntegralLit GhcPs -> HsOverLit GhcPs |
| 335 | 335 | mkHsFractional :: FractionalLit GhcPs -> HsOverLit GhcPs
|
| 336 | 336 | mkHsIsString :: SourceText -> HText -> HsOverLit GhcPs
|
| 337 | 337 | mkHsDo :: HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> HsExpr GhcPs
|
| 338 | -mkHsDoAnns :: HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> (AnnList, EpaLocation) -> HsExpr GhcPs
|
|
| 338 | +mkHsDoAnns :: HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> DoAnn -> HsExpr GhcPs
|
|
| 339 | 339 | mkHsComp :: HsDoFlavour -> [ExprLStmt GhcPs] -> LHsExpr GhcPs
|
| 340 | 340 | -> HsExpr GhcPs
|
| 341 | -mkHsCompAnns :: HsDoFlavour -> [ExprLStmt GhcPs] -> LHsExpr GhcPs
|
|
| 342 | - -> (AnnList, EpaLocation)
|
|
| 341 | +mkHsCompAnns :: HsDoFlavour -> [ExprLStmt GhcPs] -> LHsExpr GhcPs -> DoAnn
|
|
| 343 | 342 | -> HsExpr GhcPs
|
| 344 | 343 | |
| 345 | 344 | mkNPat :: LocatedAn NoEpAnns (HsOverLit GhcPs) -> Maybe (SyntaxExpr GhcPs) -> EpToken "-"
|
| ... | ... | @@ -3152,19 +3152,15 @@ aexp :: { ECP } |
| 3152 | 3152 | return $ ECP $
|
| 3153 | 3153 | $2 >>= \ $2 ->
|
| 3154 | 3154 | mkHsDoPV (comb2 $1 $2)
|
| 3155 | - (stmtlistAnns $2)
|
|
| 3155 | + (Right $ stmtlistAnns $2, glR $1)
|
|
| 3156 | 3156 | (fmap mkModuleNameFS (getDO $1))
|
| 3157 | - (stmtlistStmts $2)
|
|
| 3158 | - (glR $1)
|
|
| 3159 | - (glR $2) }
|
|
| 3157 | + (stmtlistStmts $2) }
|
|
| 3160 | 3158 | | MDO stmtlist {% hintQualifiedDo $1 >> runPV $2 >>= \ $2 ->
|
| 3161 | 3159 | fmap ecpFromExp $
|
| 3162 | 3160 | amsA' (L (comb2 $1 $2)
|
| 3163 | - (mkMDo (stmtlistAnns $2)
|
|
| 3164 | - (MDoExpr $ fmap mkModuleNameFS (getMDO $1))
|
|
| 3165 | - (stmtlistStmts $2)
|
|
| 3166 | - (glR $1)
|
|
| 3167 | - (glR $2))) }
|
|
| 3161 | + (mkHsDoAnns (MDoExpr $ fmap mkModuleNameFS (getMDO $1))
|
|
| 3162 | + (stmtlistStmts $2)
|
|
| 3163 | + (Right $ stmtlistAnns $2, glR $1))) }
|
|
| 3168 | 3164 | | 'proc' aexp '->' exp
|
| 3169 | 3165 | {% (checkPattern <=< runPV) (unECP $2) >>= \ p ->
|
| 3170 | 3166 | runPV (unECP $4) >>= \ $4@cmd ->
|
| ... | ... | @@ -3440,7 +3436,7 @@ list :: { forall b. DisambECP b => SrcSpan -> (EpaLocation, EpaLocation) -> PV ( |
| 3440 | 3436 | { \loc (ao,ac) ->
|
| 3441 | 3437 | checkMonadComp >>= \ ctxt ->
|
| 3442 | 3438 | unECP $1 >>= \ $1 -> do { t <- addTrailingVbarA $1 (epTok $2)
|
| 3443 | - ; amsA' (L loc $ mkHsCompAnns ctxt (unLoc $3) t (AnnList Nothing (ListSquare (EpTok ao) (EpTok ac)) [], noAnn))
|
|
| 3439 | + ; amsA' (L loc $ mkHsCompAnns ctxt (unLoc $3) t (Left $ (EpTok ao, EpTok ac), noAnn))
|
|
| 3444 | 3440 | >>= ecpFromExp' } }
|
| 3445 | 3441 | |
| 3446 | 3442 | lexps :: { forall b. DisambECP b => PV [LocatedA b] }
|
| ... | ... | @@ -3658,11 +3654,13 @@ apat : aexp {% (checkPattern <=< runPV) (unECP $1) } |
| 3658 | 3654 | -----------------------------------------------------------------------------
|
| 3659 | 3655 | -- Statement sequences
|
| 3660 | 3656 | |
| 3661 | -stmtlist :: { forall b. DisambECP b => PV (LocatedA ((EpToken "{", [EpToken ";"], EpToken "}"), Located [LocatedA (Stmt GhcPs (LocatedA b))])) }
|
|
| 3657 | +stmtlist :: { forall b. DisambECP b => PV (LocatedA (AnnList, Located [LocatedA (Stmt GhcPs (LocatedA b))])) }
|
|
| 3662 | 3658 | : '{' stmts '}' { $2 >>= \ $2 ->
|
| 3663 | - amsA' (sLL $1 $> ((epTok $1, fromOL $ fst $ unLoc $2, epTok $3), sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3659 | + amsA' (sLL $1 $> (AnnList (Just (spanAsAnchor $ stmtsLoc $2)) (ListBraces (epTok $1) (epTok $3)) (fromOL $ fst $ unLoc $2)
|
|
| 3660 | + , sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3664 | 3661 | | vocurly stmts close { $2 >>= \ $2 ->
|
| 3665 | - amsA' (L (stmtsLoc $2) ((noEpTok, fromOL $ fst $ unLoc $2, noEpTok), sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3662 | + amsA' (L (stmtsLoc $2) (AnnList (Just (spanAsAnchor $ stmtsLoc $2)) ListNone (fromOL $ fst $ unLoc $2)
|
|
| 3663 | + , sL1 $2 $ reverse $ snd $ unLoc $2))}
|
|
| 3666 | 3664 | |
| 3667 | 3665 | -- do { ;; s ; s ; ; s ;; }
|
| 3668 | 3666 | -- The last Stmt should be an expression, but that's hard to enforce
|
| ... | ... | @@ -3704,7 +3702,7 @@ e_stmt :: { LStmt GhcPs (LHsExpr GhcPs) } |
| 3704 | 3702 | stmt :: { forall b. DisambECP b => PV (LStmt GhcPs (LocatedA b)) }
|
| 3705 | 3703 | : qual { $1 }
|
| 3706 | 3704 | | 'rec' stmtlist { $2 >>= \ $2 ->
|
| 3707 | - amsA' (sLL $1 $> $ mkRecStmt (hsDoAnn (epTok $1) (stmtlistAnns $2) $2)
|
|
| 3705 | + amsA' (sLL $1 $> $ mkRecStmt (stmtlistAnns $2, epTok $1)
|
|
| 3708 | 3706 | (stmtlistStmts $2)) }
|
| 3709 | 3707 | |
| 3710 | 3708 | qual :: { forall b. DisambECP b => PV (LStmt GhcPs (LocatedA b)) }
|
| ... | ... | @@ -4724,10 +4722,6 @@ commentsPA la@(L l a) = do |
| 4724 | 4722 | !cs <- getPriorCommentsFor (getLocA la)
|
| 4725 | 4723 | return (L (addCommentsToEpAnn l cs) a)
|
| 4726 | 4724 | |
| 4727 | -hsDoAnn :: EpToken "rec" -> (EpToken "{", [EpToken ";"], EpToken "}") -> LocatedAn t b -> (AnnList, EpToken "rec")
|
|
| 4728 | -hsDoAnn rec (ob, semis, cb) (L ll _)
|
|
| 4729 | - = (AnnList (Just $ spanAsAnchor (locA ll)) (ListBraces ob cb) semis, rec)
|
|
| 4730 | - |
|
| 4731 | 4725 | listAsAnchorM :: [LocatedAn t a] -> Maybe EpaLocation
|
| 4732 | 4726 | listAsAnchorM [] = Nothing
|
| 4733 | 4727 | listAsAnchorM (L l _:_) =
|
| ... | ... | @@ -4757,8 +4751,7 @@ stmtlistStmts :: LocatedA (a, Located [LocatedA (Stmt GhcPs (LocatedA b))]) |
| 4757 | 4751 | stmtlistStmts (L la (_,L l stmts))
|
| 4758 | 4752 | = L ((noAnnSrcSpan l) {comments = comments la}) stmts
|
| 4759 | 4753 | |
| 4760 | -stmtlistAnns :: LocatedA ((EpToken "{", [EpToken ";"], EpToken "}"), a)
|
|
| 4761 | - -> (EpToken "{", [EpToken ";"], EpToken "}")
|
|
| 4754 | +stmtlistAnns :: LocatedA (AnnList, a) -> AnnList
|
|
| 4762 | 4755 | stmtlistAnns (L _ (an,_)) = an
|
| 4763 | 4756 | |
| 4764 | 4757 | -- -------------------------------------
|
| ... | ... | @@ -519,8 +519,7 @@ data AnnList |
| 519 | 519 | } deriving (Data,Eq)
|
| 520 | 520 | |
| 521 | 521 | data AnnListBrackets
|
| 522 | - = ListBraces (EpToken "{") (EpToken "}")
|
|
| 523 | - | ListSquare (EpToken "[") (EpToken "]")
|
|
| 522 | + = ListBraces (EpToken "{") (EpToken "}")
|
|
| 524 | 523 | | ListNone
|
| 525 | 524 | deriving (Data,Eq)
|
| 526 | 525 | |
| ... | ... | @@ -1093,7 +1092,6 @@ instance Outputable AnnList where |
| 1093 | 1092 | |
| 1094 | 1093 | instance Outputable AnnListBrackets where
|
| 1095 | 1094 | ppr (ListBraces o c) = text "ListBraces" <+> ppr o <+> ppr c
|
| 1096 | - ppr (ListSquare o c) = text "ListSquare" <+> ppr o <+> ppr c
|
|
| 1097 | 1095 | ppr ListNone = text "ListNone"
|
| 1098 | 1096 | |
| 1099 | 1097 | instance Outputable AnnCType where
|
| ... | ... | @@ -12,7 +12,7 @@ module GHC.Parser.PostProcess ( |
| 12 | 12 | mkRdrGetField, mkRdrProjection, Fbind, -- RecordDot
|
| 13 | 13 | mkHsOpApp,
|
| 14 | 14 | mkHsIntegral, mkHsFractional, mkHsIsString,
|
| 15 | - mkHsDo, mkMDo, mkSpliceDecl,
|
|
| 15 | + mkHsDo, mkSpliceDecl,
|
|
| 16 | 16 | mkRoleAnnotDecl,
|
| 17 | 17 | mkClassDecl,
|
| 18 | 18 | mkTyData, mkDataFamInst,
|
| ... | ... | @@ -435,10 +435,6 @@ mkRoleAnnotDecl loc tycon roles anns |
| 435 | 435 | addFatalError $ mkPlainErrorMsgEnvelope loc_role $
|
| 436 | 436 | (PsErrIllegalRoleName role nearby)
|
| 437 | 437 | |
| 438 | -mkMDo :: (EpToken "{", [EpToken ";"], EpToken "}") -> HsDoFlavour -> LocatedA [ExprLStmt GhcPs] -> EpaLocation -> EpaLocation -> HsExpr GhcPs
|
|
| 439 | -mkMDo (ob, semis, cb) ctxt stmts tok loc
|
|
| 440 | - = mkHsDoAnns ctxt stmts (AnnList (Just loc) (ListBraces ob cb) semis, tok)
|
|
| 441 | - |
|
| 442 | 438 | -- | Converts a list of 'LHsTyVarBndr's annotated with their 'Specificity' to
|
| 443 | 439 | -- binders without annotations. Only accepts specified variables, and errors if
|
| 444 | 440 | -- any of the provided binders has an 'InferredSpec' annotation.
|
| ... | ... | @@ -1804,12 +1800,7 @@ class (b ~ (Body b) GhcPs, AnnoBody b) => DisambECP b where |
| 1804 | 1800 | -> PV (LocatedA b)
|
| 1805 | 1801 | -- | Disambiguate "do { ... }" (do notation)
|
| 1806 | 1802 | mkHsDoPV ::
|
| 1807 | - SrcSpan ->
|
|
| 1808 | - (EpToken "{", [EpToken ";"], EpToken "}") ->
|
|
| 1809 | - Maybe ModuleName ->
|
|
| 1810 | - LocatedA [LStmt GhcPs (LocatedA b)] ->
|
|
| 1811 | - EpaLocation -> -- Token
|
|
| 1812 | - EpaLocation -> -- Anchor
|
|
| 1803 | + SrcSpan -> DoAnn -> Maybe ModuleName -> LocatedA [LStmt GhcPs (LocatedA b)] ->
|
|
| 1813 | 1804 | PV (LocatedA b)
|
| 1814 | 1805 | -- | Disambiguate "( ... )" (parentheses)
|
| 1815 | 1806 | mkHsParPV :: SrcSpan -> EpToken "(" -> LocatedA b -> EpToken ")" -> PV (LocatedA b)
|
| ... | ... | @@ -1959,10 +1950,10 @@ instance DisambECP (HsCmd GhcPs) where |
| 1959 | 1950 | checkDoAndIfThenElse PsErrSemiColonsInCondCmd c semi1 a semi2 b
|
| 1960 | 1951 | !cs <- getCommentsFor l
|
| 1961 | 1952 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (mkHsCmdIf c a b anns)
|
| 1962 | - mkHsDoPV l (ob,semis,cb) Nothing stmts tok_loc anc = do
|
|
| 1953 | + mkHsDoPV l ann Nothing stmts = do
|
|
| 1963 | 1954 | !cs <- getCommentsFor l
|
| 1964 | - return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsCmdDo (AnnList (Just anc) (ListBraces ob cb) semis, tok_loc) stmts)
|
|
| 1965 | - mkHsDoPV l _ (Just m) _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrQualifiedDoInCmd m
|
|
| 1955 | + return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsCmdDo ann stmts)
|
|
| 1956 | + mkHsDoPV l _ (Just m) _ = addFatalError $ mkPlainErrorMsgEnvelope l $ PsErrQualifiedDoInCmd m
|
|
| 1966 | 1957 | mkHsParPV l lpar c rpar = do
|
| 1967 | 1958 | !cs <- getCommentsFor l
|
| 1968 | 1959 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsCmdPar (lpar, rpar) c)
|
| ... | ... | @@ -2058,9 +2049,9 @@ instance DisambECP (HsExpr GhcPs) where |
| 2058 | 2049 | checkDoAndIfThenElse PsErrSemiColonsInCondExpr c semi1 a semi2 b
|
| 2059 | 2050 | !cs <- getCommentsFor l
|
| 2060 | 2051 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (mkHsIf c a b anns)
|
| 2061 | - mkHsDoPV l (ob,semis,cb) mod stmts loc_tok anc = do
|
|
| 2052 | + mkHsDoPV l ann mod stmts = do
|
|
| 2062 | 2053 | !cs <- getCommentsFor l
|
| 2063 | - return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsDo (AnnList (Just anc) (ListBraces ob cb) semis, loc_tok) (DoExpr mod) stmts)
|
|
| 2054 | + return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsDo ann (DoExpr mod) stmts)
|
|
| 2064 | 2055 | mkHsParPV l lpar e rpar = do
|
| 2065 | 2056 | !cs <- getCommentsFor l
|
| 2066 | 2057 | return $ L (EpAnn (spanAsAnchor l) noAnn cs) (HsPar (lpar, rpar) e)
|
| ... | ... | @@ -2156,7 +2147,7 @@ instance DisambECP (PatBuilder GhcPs) where |
| 2156 | 2147 | !cs <- getCommentsFor (locA l)
|
| 2157 | 2148 | return $ L (addCommentsToEpAnn l cs) (PatBuilderAppType p at (mkHsTyPat t))
|
| 2158 | 2149 | mkHsIfPV l _ _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrIfThenElseInPat
|
| 2159 | - mkHsDoPV l _ _ _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat
|
|
| 2150 | + mkHsDoPV l _ _ _ = addFatalError $ mkPlainErrorMsgEnvelope l PsErrDoNotationInPat
|
|
| 2160 | 2151 | mkHsParPV l lpar p rpar = return $ L (noAnnSrcSpan l) (PatBuilderPar lpar p rpar)
|
| 2161 | 2152 | mkHsVarPV v@(getLoc -> l) = return $ L (l2l l) (PatBuilderVar v)
|
| 2162 | 2153 | mkHsLitPV lit@(L l a) = do
|
| ... | ... | @@ -71,7 +71,6 @@ import GHC.Data.Graph.Directed ( SCC, flattenSCC, Node(..) |
| 71 | 71 | , stronglyConnCompFromEdgedVerticesUniq )
|
| 72 | 72 | import GHC.Data.OrdList
|
| 73 | 73 | import qualified GHC.LanguageExtensions as LangExt
|
| 74 | -import GHC.Core.DataCon ( isSrcStrict )
|
|
| 75 | 74 | |
| 76 | 75 | import Control.Monad
|
| 77 | 76 | import Data.Bifunctor ( first )
|
| ... | ... | @@ -2116,8 +2115,8 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond |
| 2116 | 2115 | = do {
|
| 2117 | 2116 | ; when (has_labelled_fields condecl) $
|
| 2118 | 2117 | failWith $ TcRnTypeDataForbids TypeDataForbidsLabelledFields
|
| 2119 | - ; when (has_strictness_flags condecl) $
|
|
| 2120 | - failWith $ TcRnTypeDataForbids TypeDataForbidsStrictnessAnnotations
|
|
| 2118 | + ; when (has_field_annotations condecl) $
|
|
| 2119 | + failWith $ TcRnTypeDataForbids TypeDataForbidsFieldAnnotations
|
|
| 2121 | 2120 | }
|
| 2122 | 2121 | |
| 2123 | 2122 | has_labelled_fields (ConDeclGADT { con_g_args = RecConGADT _ _ }) = True
|
| ... | ... | @@ -2125,13 +2124,19 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond |
| 2125 | 2124 | = not (null (unLoc flds))
|
| 2126 | 2125 | has_labelled_fields _ = False
|
| 2127 | 2126 | |
| 2128 | - has_strictness_flags condecl
|
|
| 2129 | - = any isSrcStrict (con_arg_bangs condecl)
|
|
| 2127 | + has_field_annotations condecl
|
|
| 2128 | + = not (all unannotated (con_arg_fields condecl))
|
|
| 2129 | + where
|
|
| 2130 | + unannotated (CDF { cdf_bang = NoSrcStrict
|
|
| 2131 | + , cdf_unpack = NoSrcUnpack
|
|
| 2132 | + , cdf_multiplicity = HsModifiedFunArr _ [] (HsStandardArr _) })
|
|
| 2133 | + = True
|
|
| 2134 | + unannotated _ = False
|
|
| 2130 | 2135 | |
| 2131 | - con_arg_bangs (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = map cdf_bang args
|
|
| 2132 | - con_arg_bangs (ConDeclH98 { con_args = PrefixCon _ args }) = map cdf_bang args
|
|
| 2133 | - con_arg_bangs (ConDeclH98 { con_args = InfixCon _ arg1 arg2 }) = [cdf_bang arg1, cdf_bang arg2]
|
|
| 2134 | - con_arg_bangs _ = []
|
|
| 2136 | + con_arg_fields (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args
|
|
| 2137 | + con_arg_fields (ConDeclH98 { con_args = PrefixCon _ args }) = args
|
|
| 2138 | + con_arg_fields (ConDeclH98 { con_args = InfixCon _ arg1 arg2 }) = [arg1, arg2]
|
|
| 2139 | + con_arg_fields _ = []
|
|
| 2135 | 2140 | |
| 2136 | 2141 | {-
|
| 2137 | 2142 | Note [Type data declarations]
|
| ... | ... | @@ -2166,8 +2171,9 @@ preceded by `type`, with the following restrictions: |
| 2166 | 2171 | (R2) There are no labelled fields. Perhaps these could be supported
|
| 2167 | 2172 | using type families, but they are omitted for now.
|
| 2168 | 2173 | |
| 2169 | -(R3) There are no strictness flags, because they don't make sense at
|
|
| 2170 | - the type level.
|
|
| 2174 | +(R3) There are no strictness, unpackedness or multiplicity annotations
|
|
| 2175 | + (!, ~, {-# UNPACK #-}, {-# NOUNPACK #-}, %m ->, ⊸), because they
|
|
| 2176 | + don't make sense at the type level.
|
|
| 2171 | 2177 | |
| 2172 | 2178 | (R4) The types of the constructors contain no constraints.
|
| 2173 | 2179 |
| ... | ... | @@ -2866,6 +2866,12 @@ data TcRnMessage where |
| 2866 | 2866 | type-data/should_fail/TDRecordsH98
|
| 2867 | 2867 | type-data/should_fail/TDStrictnessGADT
|
| 2868 | 2868 | type-data/should_fail/TDStrictnessH98
|
| 2869 | + type-data/should_fail/T27732a
|
|
| 2870 | + type-data/should_fail/T27732b
|
|
| 2871 | + type-data/should_fail/T27732c
|
|
| 2872 | + type-data/should_fail/T27732d
|
|
| 2873 | + type-data/should_fail/T27732e
|
|
| 2874 | + type-data/should_fail/T27732f
|
|
| 2869 | 2875 | -}
|
| 2870 | 2876 | TcRnTypeDataForbids :: !TypeDataForbids -> TcRnMessage
|
| 2871 | 2877 | |
| ... | ... | @@ -4541,15 +4547,15 @@ data ZonkerMessage where |
| 4541 | 4547 | data TypeDataForbids
|
| 4542 | 4548 | = TypeDataForbidsDatatypeContexts
|
| 4543 | 4549 | | TypeDataForbidsLabelledFields
|
| 4544 | - | TypeDataForbidsStrictnessAnnotations
|
|
| 4550 | + | TypeDataForbidsFieldAnnotations
|
|
| 4545 | 4551 | | TypeDataForbidsDerivingClauses
|
| 4546 | 4552 | deriving Generic
|
| 4547 | 4553 | |
| 4548 | 4554 | instance Outputable TypeDataForbids where
|
| 4549 | - ppr TypeDataForbidsDatatypeContexts = text "Data type contexts"
|
|
| 4550 | - ppr TypeDataForbidsLabelledFields = text "Labelled fields"
|
|
| 4551 | - ppr TypeDataForbidsStrictnessAnnotations = text "Strictness flags"
|
|
| 4552 | - ppr TypeDataForbidsDerivingClauses = text "Deriving clauses"
|
|
| 4555 | + ppr TypeDataForbidsDatatypeContexts = text "Data type contexts"
|
|
| 4556 | + ppr TypeDataForbidsLabelledFields = text "Labelled fields"
|
|
| 4557 | + ppr TypeDataForbidsFieldAnnotations = text "Strictness, unpackedness or multiplicity annotations"
|
|
| 4558 | + ppr TypeDataForbidsDerivingClauses = text "Deriving clauses"
|
|
| 4553 | 4559 | |
| 4554 | 4560 | -- | Specifies which back ends can handle a requested foreign import or export
|
| 4555 | 4561 | type ExpectedBackends = [Backend]
|
| ... | ... | @@ -33,7 +33,8 @@ either an ordinary algebraic data type or a GADT, prefixed with the keyword |
| 33 | 33 | ``type``, except that it may not contain
|
| 34 | 34 | a datatype context (even with :extension:`DatatypeContexts`),
|
| 35 | 35 | labelled fields,
|
| 36 | -strictness flags, or
|
|
| 36 | +:ref:`strictness <strict-haskell>`, :ref:`unpackedness <unpack-pragma>` or
|
|
| 37 | +:ref:`multiplicity <linear-types>` annotations, or
|
|
| 37 | 38 | a ``deriving`` clause.
|
| 38 | 39 | |
| 39 | 40 | The only constraints permitted in the types of constructors are
|
| ... | ... | @@ -289,13 +289,12 @@ |
| 289 | 289 | { DumpParsedAstComments.hs:14:7-8 }))]))
|
| 290 | 290 | (HsDo
|
| 291 | 291 | ((,)
|
| 292 | - (AnnList
|
|
| 293 | - (Just
|
|
| 294 | - (EpaSpan { DumpParsedAstComments.hs:16:3 }))
|
|
| 295 | - (ListBraces
|
|
| 296 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 297 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 298 | - [])
|
|
| 292 | + (Right
|
|
| 293 | + (AnnList
|
|
| 294 | + (Just
|
|
| 295 | + (EpaSpan { DumpParsedAstComments.hs:16:3 }))
|
|
| 296 | + (ListNone)
|
|
| 297 | + []))
|
|
| 299 | 298 | (EpaSpan { DumpParsedAstComments.hs:14:7-8 }))
|
| 300 | 299 | (DoExpr
|
| 301 | 300 | (Nothing))
|
| ... | ... | @@ -331,13 +331,12 @@ |
| 331 | 331 | []))
|
| 332 | 332 | (HsDo
|
| 333 | 333 | ((,)
|
| 334 | - (AnnList
|
|
| 335 | - (Just
|
|
| 336 | - (EpaSpan { DumpSemis.hs:(11,3)-(12,3) }))
|
|
| 337 | - (ListBraces
|
|
| 338 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 339 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 340 | - [])
|
|
| 334 | + (Right
|
|
| 335 | + (AnnList
|
|
| 336 | + (Just
|
|
| 337 | + (EpaSpan { DumpSemis.hs:(11,3)-(12,3) }))
|
|
| 338 | + (ListNone)
|
|
| 339 | + []))
|
|
| 341 | 340 | (EpaSpan { DumpSemis.hs:10:7-8 }))
|
| 342 | 341 | (DoExpr
|
| 343 | 342 | (Nothing))
|
| ... | ... | @@ -363,20 +362,21 @@ |
| 363 | 362 | []))
|
| 364 | 363 | (HsDo
|
| 365 | 364 | ((,)
|
| 366 | - (AnnList
|
|
| 367 | - (Just
|
|
| 368 | - (EpaSpan { DumpSemis.hs:11:6-15 }))
|
|
| 369 | - (ListBraces
|
|
| 370 | - (EpTok (EpaSpan { DumpSemis.hs:11:6 }))
|
|
| 371 | - (EpTok (EpaSpan { DumpSemis.hs:11:15 })))
|
|
| 372 | - [(EpTok
|
|
| 373 | - (EpaSpan { DumpSemis.hs:11:8 }))
|
|
| 374 | - ,(EpTok
|
|
| 375 | - (EpaSpan { DumpSemis.hs:11:9 }))
|
|
| 376 | - ,(EpTok
|
|
| 377 | - (EpaSpan { DumpSemis.hs:11:10 }))
|
|
| 378 | - ,(EpTok
|
|
| 379 | - (EpaSpan { DumpSemis.hs:11:11 }))])
|
|
| 365 | + (Right
|
|
| 366 | + (AnnList
|
|
| 367 | + (Just
|
|
| 368 | + (EpaSpan { DumpSemis.hs:11:8-13 }))
|
|
| 369 | + (ListBraces
|
|
| 370 | + (EpTok (EpaSpan { DumpSemis.hs:11:6 }))
|
|
| 371 | + (EpTok (EpaSpan { DumpSemis.hs:11:15 })))
|
|
| 372 | + [(EpTok
|
|
| 373 | + (EpaSpan { DumpSemis.hs:11:8 }))
|
|
| 374 | + ,(EpTok
|
|
| 375 | + (EpaSpan { DumpSemis.hs:11:9 }))
|
|
| 376 | + ,(EpTok
|
|
| 377 | + (EpaSpan { DumpSemis.hs:11:10 }))
|
|
| 378 | + ,(EpTok
|
|
| 379 | + (EpaSpan { DumpSemis.hs:11:11 }))]))
|
|
| 380 | 380 | (EpaSpan { DumpSemis.hs:11:3-4 }))
|
| 381 | 381 | (DoExpr
|
| 382 | 382 | (Nothing))
|
| ... | ... | @@ -625,16 +625,17 @@ |
| 625 | 625 | []))
|
| 626 | 626 | (HsDo
|
| 627 | 627 | ((,)
|
| 628 | - (AnnList
|
|
| 629 | - (Just
|
|
| 630 | - (EpaSpan { DumpSemis.hs:(16,3)-(19,3) }))
|
|
| 631 | - (ListBraces
|
|
| 632 | - (EpTok (EpaSpan { DumpSemis.hs:16:3 }))
|
|
| 633 | - (EpTok (EpaSpan { DumpSemis.hs:19:3 })))
|
|
| 634 | - [(EpTok
|
|
| 635 | - (EpaSpan { DumpSemis.hs:16:5 }))
|
|
| 636 | - ,(EpTok
|
|
| 637 | - (EpaSpan { DumpSemis.hs:16:8 }))])
|
|
| 628 | + (Right
|
|
| 629 | + (AnnList
|
|
| 630 | + (Just
|
|
| 631 | + (EpaSpan { DumpSemis.hs:(16,5)-(18,5) }))
|
|
| 632 | + (ListBraces
|
|
| 633 | + (EpTok (EpaSpan { DumpSemis.hs:16:3 }))
|
|
| 634 | + (EpTok (EpaSpan { DumpSemis.hs:19:3 })))
|
|
| 635 | + [(EpTok
|
|
| 636 | + (EpaSpan { DumpSemis.hs:16:5 }))
|
|
| 637 | + ,(EpTok
|
|
| 638 | + (EpaSpan { DumpSemis.hs:16:8 }))]))
|
|
| 638 | 639 | (EpaSpan { DumpSemis.hs:15:7-8 }))
|
| 639 | 640 | (DoExpr
|
| 640 | 641 | (Nothing))
|
| ... | ... | @@ -877,16 +878,17 @@ |
| 877 | 878 | []))
|
| 878 | 879 | (HsDo
|
| 879 | 880 | ((,)
|
| 880 | - (AnnList
|
|
| 881 | - (Just
|
|
| 882 | - (EpaSpan { DumpSemis.hs:22:10-30 }))
|
|
| 883 | - (ListBraces
|
|
| 884 | - (EpTok (EpaSpan { DumpSemis.hs:22:10 }))
|
|
| 885 | - (EpTok (EpaSpan { DumpSemis.hs:22:30 })))
|
|
| 886 | - [(EpTok
|
|
| 887 | - (EpaSpan { DumpSemis.hs:22:12 }))
|
|
| 888 | - ,(EpTok
|
|
| 889 | - (EpaSpan { DumpSemis.hs:22:13 }))])
|
|
| 881 | + (Right
|
|
| 882 | + (AnnList
|
|
| 883 | + (Just
|
|
| 884 | + (EpaSpan { DumpSemis.hs:22:12-28 }))
|
|
| 885 | + (ListBraces
|
|
| 886 | + (EpTok (EpaSpan { DumpSemis.hs:22:10 }))
|
|
| 887 | + (EpTok (EpaSpan { DumpSemis.hs:22:30 })))
|
|
| 888 | + [(EpTok
|
|
| 889 | + (EpaSpan { DumpSemis.hs:22:12 }))
|
|
| 890 | + ,(EpTok
|
|
| 891 | + (EpaSpan { DumpSemis.hs:22:13 }))]))
|
|
| 890 | 892 | (EpaSpan { DumpSemis.hs:22:7-8 }))
|
| 891 | 893 | (DoExpr
|
| 892 | 894 | (Nothing))
|
| ... | ... | @@ -394,13 +394,12 @@ |
| 394 | 394 | []))
|
| 395 | 395 | (HsDo
|
| 396 | 396 | ((,)
|
| 397 | - (AnnList
|
|
| 398 | - (Just
|
|
| 399 | - (EpaSpan { Test20297.hs:11:22-26 }))
|
|
| 400 | - (ListBraces
|
|
| 401 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 402 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 403 | - [])
|
|
| 397 | + (Right
|
|
| 398 | + (AnnList
|
|
| 399 | + (Just
|
|
| 400 | + (EpaSpan { Test20297.hs:11:22-26 }))
|
|
| 401 | + (ListNone)
|
|
| 402 | + []))
|
|
| 404 | 403 | (EpaSpan { Test20297.hs:11:19-20 }))
|
| 405 | 404 | (DoExpr
|
| 406 | 405 | (Nothing))
|
| ... | ... | @@ -820,13 +819,12 @@ |
| 820 | 819 | []))
|
| 821 | 820 | (HsDo
|
| 822 | 821 | ((,)
|
| 823 | - (AnnList
|
|
| 824 | - (Just
|
|
| 825 | - (EpaSpan { Test20297.ppr.hs:9:20-24 }))
|
|
| 826 | - (ListBraces
|
|
| 827 | - (EpTok (EpaSpan { <no location info> }))
|
|
| 828 | - (EpTok (EpaSpan { <no location info> })))
|
|
| 829 | - [])
|
|
| 822 | + (Right
|
|
| 823 | + (AnnList
|
|
| 824 | + (Just
|
|
| 825 | + (EpaSpan { Test20297.ppr.hs:9:20-24 }))
|
|
| 826 | + (ListNone)
|
|
| 827 | + []))
|
|
| 830 | 828 | (EpaSpan { Test20297.ppr.hs:9:17-18 }))
|
| 831 | 829 | (DoExpr
|
| 832 | 830 | (Nothing))
|
| 1 | +{-# LANGUAGE TypeData, LazyFieldAnnotations #-}
|
|
| 2 | +module T27732a where
|
|
| 3 | + |
|
| 4 | +type data T a = Cons ~a |
| 1 | +T27732a.hs:4:17: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 3 | + |
| 1 | +{-# LANGUAGE TypeData, LazyFieldAnnotations #-}
|
|
| 2 | +module T27732b where
|
|
| 3 | + |
|
| 4 | +type data T a where
|
|
| 5 | + Cons :: ~a -> T a |
| 1 | +T27732b.hs:5:6: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 3 | + |
| 1 | +{-# LANGUAGE TypeData #-}
|
|
| 2 | +module T27732c where
|
|
| 3 | + |
|
| 4 | +type data T a = Cons {-# UNPACK #-} a |
| 1 | +T27732c.hs:4:17: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 3 | + |
| 1 | +{-# LANGUAGE TypeData #-}
|
|
| 2 | +module T27732d where
|
|
| 3 | + |
|
| 4 | +type data T a = Cons {-# NOUNPACK #-} a |
| 1 | +T27732d.hs:4:17: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 3 | + |
| 1 | +{-# LANGUAGE TypeData, LinearTypes #-}
|
|
| 2 | +module T27732e where
|
|
| 3 | + |
|
| 4 | +type data T where
|
|
| 5 | + MkT :: Int %1 -> T |
| 1 | +T27732e.hs:5:3: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 3 | + |
| 1 | +{-# LANGUAGE TypeData, LinearTypes, UnicodeSyntax #-}
|
|
| 2 | +module T27732f where
|
|
| 3 | + |
|
| 4 | +type data T where
|
|
| 5 | + MkT :: Int ⊸ T |
| 1 | +T27732f.hs:5:3: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 3 | + |
| 1 | +TDStrictnessGADT.hs:5:6: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 1 | 3 | |
| 2 | -TDStrictnessGADT.hs:5:6: [GHC-67297]
|
|
| 3 | - Strictness flags are not allowed in type data declarations. |
| 1 | +TDStrictnessH98.hs:4:17: error: [GHC-67297]
|
|
| 2 | + Strictness, unpackedness or multiplicity annotations are not allowed in type data declarations.
|
|
| 1 | 3 | |
| 2 | -TDStrictnessH98.hs:4:17: [GHC-67297]
|
|
| 3 | - Strictness flags are not allowed in type data declarations. |
| ... | ... | @@ -13,3 +13,9 @@ test('TDStrictnessGADT', normal, compile_fail, ['']) |
| 13 | 13 | test('TDStrictnessH98', normal, compile_fail, [''])
|
| 14 | 14 | test('TDTagToEnum', normal, compile_fail, [''])
|
| 15 | 15 | test('T22332b', normal, compile_fail, [''])
|
| 16 | +test('T27732a', normal, compile_fail, [''])
|
|
| 17 | +test('T27732b', normal, compile_fail, [''])
|
|
| 18 | +test('T27732c', normal, compile_fail, [''])
|
|
| 19 | +test('T27732d', normal, compile_fail, [''])
|
|
| 20 | +test('T27732e', normal, compile_fail, [''])
|
|
| 21 | +test('T27732f', normal, compile_fail, ['']) |
| ... | ... | @@ -140,9 +140,9 @@ defaultEPState = EPState |
| 140 | 140 | |
| 141 | 141 | -- | The R part of RWS. The environment. Updated via 'local' as we
|
| 142 | 142 | -- enter a new AST element, having a different anchor point.
|
| 143 | -data EPOptions m a = EPOptions
|
|
| 144 | - { epTokenPrint :: String -> m a
|
|
| 145 | - , epWhitespacePrint :: String -> m a
|
|
| 143 | +data EPOptions m w = EPOptions
|
|
| 144 | + { epTokenPrint :: String -> m w
|
|
| 145 | + , epWhitespacePrint :: String -> m w
|
|
| 146 | 146 | }
|
| 147 | 147 | |
| 148 | 148 | -- | Helper to create a 'EPOptions'
|
| ... | ... | @@ -163,8 +163,7 @@ stringOptions = epOptions return return |
| 163 | 163 | deltaOptions :: EPOptions Identity ()
|
| 164 | 164 | deltaOptions = epOptions (\_ -> return ()) (\_ -> return ())
|
| 165 | 165 | |
| 166 | -data EPWriter a = EPWriter
|
|
| 167 | - { output :: !a }
|
|
| 166 | +data EPWriter w = EPWriter { output :: !w }
|
|
| 168 | 167 | |
| 169 | 168 | instance Monoid w => Semigroup (EPWriter w) where
|
| 170 | 169 | (EPWriter a) <> (EPWriter b) = EPWriter (a <> b)
|
| ... | ... | @@ -239,7 +238,220 @@ setAnchorEpaL (EpAnn _ an _) anc ts cs = EpAnn anc (setTrailing (an {al_anchor = |
| 239 | 238 | -- | Key entry point. Switches to an independent AST element with its
|
| 240 | 239 | -- own annotation, calculating new offsets, etc
|
| 241 | 240 | markAnnotated :: (Monad m, Monoid w, ExactPrint a) => a -> EP w m a
|
| 242 | -markAnnotated a = enterAnn (getAnnotationEntry a) a
|
|
| 241 | +markAnnotated a = enterAnn (getAnnotationEntry a) a -- See Note [Exact print main loop]
|
|
| 242 | + |
|
| 243 | +{-
|
|
| 244 | +Note [Exact print main loop]
|
|
| 245 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 246 | + |
|
| 247 | +Exact printing is the process of taking the ParsedSource, or some
|
|
| 248 | +subtree from it, and rendering it to a string, which accurately
|
|
| 249 | +reflects the original source that was parsed, except detail of
|
|
| 250 | +whitespace (such as spaces vs tabs) is discarded.
|
|
| 251 | + |
|
| 252 | +The ParsedSource or fragment from it must implement the ExactPrint
|
|
| 253 | +class, and this file does that, as well as supporting machinery to
|
|
| 254 | +drive the process. The ExactPrint class is described later in this
|
|
| 255 | +note.
|
|
| 256 | + |
|
| 257 | +The entry point for exact printing is the exactPrint function, defined
|
|
| 258 | +as
|
|
| 259 | + |
|
| 260 | + exactPrint :: ExactPrint ast => ast -> String
|
|
| 261 | + exactPrint ast = snd $ runIdentity (runEP stringOptions (markAnnotated ast))
|
|
| 262 | + |
|
| 263 | + type EP w m a = RWST (EPOptions m w) (EPWriter w) EPState m a
|
|
| 264 | + |
|
| 265 | + runEP :: (Monad m) => EPOptions m w -> EP w m a -> m (a, w)
|
|
| 266 | + runEP epReader action = do
|
|
| 267 | + (ast, w) <- evalRWST action epReader defaultEPState
|
|
| 268 | + return (ast, output w)
|
|
| 269 | + |
|
| 270 | + data EPWriter w = EPWriter { output :: !w }
|
|
| 271 | + |
|
| 272 | + data EPOptions m w = EPOptions
|
|
| 273 | + { epTokenPrint :: String -> m w
|
|
| 274 | + , epWhitespacePrint :: String -> m w
|
|
| 275 | + }
|
|
| 276 | + |
|
| 277 | +This offers some flexibility in how the output is produced, in that
|
|
| 278 | +the EpWriter and EPOptions work together, defining an output type and
|
|
| 279 | +a function to render whitespace and non-whitepace.
|
|
| 280 | + |
|
| 281 | +In normal operation (via exactPrint) these are simply returning the
|
|
| 282 | +string unchanged and accumulating a larger string. But it has also been
|
|
| 283 | +used to render an HTML version of the source as it prints.
|
|
| 284 | + |
|
| 285 | +The main reason exact print exists is to make it easier for tool
|
|
| 286 | +writers to manipulate the ParsedSource, and render this back to the
|
|
| 287 | +original source, except for the changed parts. One manipulation is to
|
|
| 288 | +simply take say a FunBind with its signature from one place in the
|
|
| 289 | +code to another. When doing this, the original parsed locations are no
|
|
| 290 | +longer useful when rendering the source back to a string. To enable
|
|
| 291 | +this, we have another entry point, for converting all absolute
|
|
| 292 | +locations to relative ones, using DeltaPos, which captures the line
|
|
| 293 | +and col offset relative to the prior output.
|
|
| 294 | + |
|
| 295 | +The function to do this is
|
|
| 296 | + |
|
| 297 | + makeDeltaAst :: ExactPrint ast => ast -> ast
|
|
| 298 | + makeDeltaAst ast = fst $ runIdentity (runEP deltaOptions (markAnnotated ast))
|
|
| 299 | + |
|
| 300 | +The implementation is practically identical for exactPrint and
|
|
| 301 | +makeDeltaAst, they simply return the second or first part of the same
|
|
| 302 | +calculation.
|
|
| 303 | + |
|
| 304 | +This simplifies the implementation of the required ExactPrint
|
|
| 305 | +implmentations, in that we only need one per ast item, which encodes
|
|
| 306 | +how to print it, and this print process does bookkeeping to keep track
|
|
| 307 | +of what spacing it used when doing the print, so it can return the
|
|
| 308 | +updated item, with the original absolute SrcSpan's converted to
|
|
| 309 | +DeltaPos values instead.
|
|
| 310 | + |
|
| 311 | +This information is captured in the XRec/Anno instances used in GHC
|
|
| 312 | +Hs, which are mostly LocatedA a, defined as
|
|
| 313 | + |
|
| 314 | + GenLocated (EpAnn [TrailingAnn]) a
|
|
| 315 | + |
|
| 316 | + data EpAnn ann
|
|
| 317 | + = EpAnn { entry :: !EpaLocation
|
|
| 318 | + , anns :: !ann
|
|
| 319 | + , comments :: !EpAnnComments
|
|
| 320 | + }
|
|
| 321 | + |
|
| 322 | + data EpaLocation = EpaSpan !SrcSpan
|
|
| 323 | + | EpaDelta !SrcSpan !DeltaPos [LEpaComment]
|
|
| 324 | + |
|
| 325 | +When parsed, the entry EpaLocation captures an EpaSpan with the parsed
|
|
| 326 | +absolute location. After makeDeltaAst, this instead uses EpaDelta,
|
|
| 327 | +including the original SrcSpan, the relative spaceing as a DeltaPos,
|
|
| 328 | +and any comments that may come before the item, e.g. comments before a
|
|
| 329 | +semicolon.
|
|
| 330 | + |
|
| 331 | +Both exactPrint and makeDeltaAst call markAnnotated on the item to be
|
|
| 332 | +printed, inside the monad machinery.
|
|
| 333 | + |
|
| 334 | + markAnnotated :: (Monad m, Monoid w, ExactPrint a) => a -> EP w m a
|
|
| 335 | + markAnnotated a = enterAnn (getAnnotationEntry a) a
|
|
| 336 | + |
|
| 337 | +This makes use of the ExactPrint instance for the ParsedSource and
|
|
| 338 | +for every other part of the ParsedSource as a tree.
|
|
| 339 | + |
|
| 340 | + class (Typeable a) => ExactPrint a where
|
|
| 341 | + getAnnotationEntry :: a -> Entry
|
|
| 342 | + exact :: (Monad m, Monoid w) => a -> EP w m a
|
|
| 343 | + setAnnotationAnchor :: a -> EpaLocation -> [TrailingAnn] -> EpAnnComments -> a
|
|
| 344 | + |
|
| 345 | +- getAnnotationEntry : returns the Entry information, normally derived
|
|
| 346 | + directly from the EpAnn in the LocatedA enclosing the item.
|
|
| 347 | + Entry contains
|
|
| 348 | + - The location of the first non-comment part of the item to be printed.
|
|
| 349 | + - Any [TrailingAnn] (semis, commas, etc) to follow the item.
|
|
| 350 | + - Any comments associated with the item, but not with enclosed items.
|
|
| 351 | + These comments may also precede or follow the entry location
|
|
| 352 | + - Some technical flags, relating to flushing remaining comments at the
|
|
| 353 | + last (topmost) item, and if the anchor can be updated (see below).
|
|
| 354 | + |
|
| 355 | +- exact : Do the actual printing of the item, having been put in the right
|
|
| 356 | + place in terms of print location by the main loop, based on a call to
|
|
| 357 | + getAnnotationEntry for it. This printing normally comprises making nested
|
|
| 358 | + markAnnotated calls on the nested items in the current one, e.g.
|
|
| 359 | + |
|
| 360 | + exact (HsApp an e1 e2) = do
|
|
| 361 | + e1' <- markAnnotated e1
|
|
| 362 | + e2' <- markAnnotated e2
|
|
| 363 | + return (HsApp an e1' e2')
|
|
| 364 | + |
|
| 365 | +- setAnnotationAnchor : the main loop printing does two things:
|
|
| 366 | + - produce output, reflecting the items being printed
|
|
| 367 | + - convert all the locations in the item (each an EpaLocation) from its
|
|
| 368 | + EpaSpan version to an EpaDelta one, which is independent of absolute
|
|
| 369 | + location, being the spacing from the previous print output to this
|
|
| 370 | + entry point
|
|
| 371 | + To allow these updated locations to be captured, the item implements
|
|
| 372 | + the setAnnotationAnchor method, which updates the fields of the Entry
|
|
| 373 | + returned by getAnnotationEntry
|
|
| 374 | + |
|
| 375 | +You will recall
|
|
| 376 | + |
|
| 377 | + markAnnotated a = enterAnn (getAnnotationEntry a) a
|
|
| 378 | + enterAnn :: (Monad m, Monoid w, ExactPrint a) => Entry -> a -> EP w m a
|
|
| 379 | + |
|
| 380 | +enterAnn is the part that is repeatedly called via markAnnotated, to
|
|
| 381 | +manage the bookkeeping around printing and calculating the updated
|
|
| 382 | +delta positions.
|
|
| 383 | + |
|
| 384 | +It manages the printing state, adding the new comments from the Entry,
|
|
| 385 | +positioning the print head to the entry point, takes account of whether
|
|
| 386 | +it is an absolute span or a delta, and prints any comments that must come
|
|
| 387 | +before this location.
|
|
| 388 | + |
|
| 389 | +At this print location, it calls the `exact` method on the item. This
|
|
| 390 | +is the only place `exact` can be called. Within `exact` implementations
|
|
| 391 | +the `markAnnotated` function should be used instead, to ensure the state
|
|
| 392 | +is managed properly for printing.
|
|
| 393 | + |
|
| 394 | +Once the item is printed via its `exact` method, which normally
|
|
| 395 | +recurses via `markAnnotated` into any nested items inside it, the
|
|
| 396 | +`enterAnn` function prints any [TrailingAnn] from the entry and any
|
|
| 397 | +trailing comments. It then wraps up by calling
|
|
| 398 | +`setAnnotationAnchor`with the updated (now delta-based) values for the
|
|
| 399 | +Entry
|
|
| 400 | + |
|
| 401 | +Printing Complicated Items
|
|
| 402 | +~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 403 | +Sometimes we need to print a sub-item which does not map cleanly onto the
|
|
| 404 | +ExactPrint class, usually because there are parts spread through the item
|
|
| 405 | +that need to be managed together while printing.
|
|
| 406 | + |
|
| 407 | +An example is in
|
|
| 408 | +https://gitlab.haskell.org/ghc/ghc/-/merge_requests/16321, where
|
|
| 409 | +ConDeclGADT needs to print its inner_bindings, but the these in turn
|
|
| 410 | +may have parens, e.g.
|
|
| 411 | + |
|
| 412 | + data V a where
|
|
| 413 | + MkV4 :: forall a. ((forall b. (Show a => a -> (b -> V a))))
|
|
| 414 | + |
|
| 415 | +Here there are inner bindings for the first forall, the multiple
|
|
| 416 | +parens around the second forall, and the second forall, wrapping the
|
|
| 417 | +inner content within this.
|
|
| 418 | + |
|
| 419 | +But the inner content `Show a => a -> (b -> V a)` had to be printed "inside"
|
|
| 420 | +the inner_bindings, to correctly close the nested parens.
|
|
| 421 | + |
|
| 422 | +The approach in !16321 modified `enterAnn`, to pass in alternate versions
|
|
| 423 | +of the `exact` implementation. This works, but it makes an already
|
|
| 424 | +complicated function even more complicated.
|
|
| 425 | + |
|
| 426 | +An ExactPrint-idiomatic approach is to create a helper data structure
|
|
| 427 | +to represent this nested organisation, and provide ExactPrint
|
|
| 428 | +instances for that.
|
|
| 429 | + |
|
| 430 | +This is done in
|
|
| 431 | +https://gitlab.haskell.org/ghc/ghc/-/merge_requests/16644, using
|
|
| 432 | + |
|
| 433 | + data InnerBindings
|
|
| 434 | + = InnerMore (LHsGadtTelescope GhcPs) InnerBindings
|
|
| 435 | + | InnerDone (Maybe (LHsContext GhcPs), HsConDeclGADTDetails GhcPs, LHsType GhcPs)
|
|
| 436 | + |
|
| 437 | +The key part of the ExactPrint instance for this is
|
|
| 438 | + |
|
| 439 | + exact (InnerMore (L l (HsGadtPar (lp, rp))) xs) = do
|
|
| 440 | + lp' <- markEpToken lp
|
|
| 441 | + xs' <- markAnnotated xs
|
|
| 442 | + rp' <- markEpToken rp
|
|
| 443 | + return (InnerMore (L l (HsGadtPar (lp',rp'))) xs')
|
|
| 444 | + |
|
| 445 | +This first prints the opening paren, prints the balance of the cons list, then
|
|
| 446 | +prints the closing paren.
|
|
| 447 | + |
|
| 448 | +Conversions to and from this structure populate the initial values from
|
|
| 449 | +the ConDeclGADT, and retrieve the updated delta-based values after
|
|
| 450 | +printing.
|
|
| 451 | + |
|
| 452 | +Another use of this technique involves HsModuleImpDecls.
|
|
| 453 | + |
|
| 454 | +-}
|
|
| 243 | 455 | |
| 244 | 456 | -- | For HsModule, because we do not have a proper SrcSpan, we must
|
| 245 | 457 | -- indicate to flush trailing comments when done.
|
| ... | ... | @@ -377,6 +589,7 @@ cua NoCanUpdateAnchor _ = return [] |
| 377 | 589 | -- This is combination of the ghc=exactprint Delta.withAST and
|
| 378 | 590 | -- Print.exactPC functions and effectively does the delta processing
|
| 379 | 591 | -- immediately followed by the print processing. JIT ghc-exactprint.
|
| 592 | +-- See Note [Exact print main loop]
|
|
| 380 | 593 | enterAnn :: (Monad m, Monoid w, ExactPrint a) => Entry -> a -> EP w m a
|
| 381 | 594 | enterAnn NoEntryVal a = do
|
| 382 | 595 | p <- getPosP
|
| ... | ... | @@ -767,9 +980,6 @@ markLensBracketsO' a l = |
| 767 | 980 | ListBraces o c -> do
|
| 768 | 981 | o' <- markEpToken o
|
| 769 | 982 | return (set l (ListBraces o' c) a)
|
| 770 | - ListSquare o c -> do
|
|
| 771 | - o' <- markEpToken o
|
|
| 772 | - return (set l (ListSquare o' c) a)
|
|
| 773 | 983 | ListNone -> return (set l ListNone a)
|
| 774 | 984 | |
| 775 | 985 | markLensBracketsC :: (Monad m, Monoid w)
|
| ... | ... | @@ -783,9 +993,6 @@ markLensBracketsC' a l = |
| 783 | 993 | ListBraces o c -> do
|
| 784 | 994 | c' <- markEpToken c
|
| 785 | 995 | return (set l (ListBraces o c') a)
|
| 786 | - ListSquare o c -> do
|
|
| 787 | - c' <- markEpToken c
|
|
| 788 | - return (set l (ListSquare o c') a)
|
|
| 789 | 996 | ListNone -> return (set l ListNone a)
|
| 790 | 997 | |
| 791 | 998 | -- -------------------------------------
|
| ... | ... | @@ -1255,6 +1462,19 @@ markKwT (AddDarrowAnn tok) = AddDarrowAnn <$> markEpUniToken tok |
| 1255 | 1462 | |
| 1256 | 1463 | -- ---------------------------------------------------------------------
|
| 1257 | 1464 | |
| 1465 | +markAnnListD :: (Monad m, Monoid w)
|
|
| 1466 | + => Either (EpToken "[", EpToken "]") AnnList
|
|
| 1467 | + -> EP w m a
|
|
| 1468 | + -> EP w m (Either (EpToken "[", EpToken "]") AnnList, a)
|
|
| 1469 | +markAnnListD (Left (o,c)) action = do
|
|
| 1470 | + o' <- markEpToken o
|
|
| 1471 | + r <- action
|
|
| 1472 | + c' <- markEpToken c
|
|
| 1473 | + return (Left (o',c'), r)
|
|
| 1474 | +markAnnListD (Right ann) action = do
|
|
| 1475 | + (ann',r) <- markAnnList' ann action
|
|
| 1476 | + return (Right ann',r)
|
|
| 1477 | + |
|
| 1258 | 1478 | markAnnList :: (Monad m, Monoid w)
|
| 1259 | 1479 | => EpAnn AnnList -> EP w m a -> EP w m (EpAnn AnnList, a)
|
| 1260 | 1480 | markAnnList ann action = do
|
| ... | ... | @@ -2902,10 +3122,10 @@ instance ExactPrint (HsExpr GhcPs) where |
| 2902 | 3122 | e' <- markAnnotated e
|
| 2903 | 3123 | return (HsLet (tkLet',tkIn') binds' e')
|
| 2904 | 3124 | |
| 2905 | - exact (HsDo (an,l) do_or_list_comp stmts) = do
|
|
| 3125 | + exact (HsDo an do_or_list_comp stmts) = do
|
|
| 2906 | 3126 | debugM $ "HsDo"
|
| 2907 | - (an',l',stmts') <- exactDo (an,l) do_or_list_comp stmts
|
|
| 2908 | - return (HsDo (an',l') do_or_list_comp stmts')
|
|
| 3127 | + (an',stmts') <- exactDo an do_or_list_comp stmts
|
|
| 3128 | + return (HsDo an' do_or_list_comp stmts')
|
|
| 2909 | 3129 | |
| 2910 | 3130 | exact (ExplicitList (o,c) es) = do
|
| 2911 | 3131 | debugM $ "ExplicitList start"
|
| ... | ... | @@ -3077,8 +3297,8 @@ instance ExactPrint (HsExpr GhcPs) where |
| 3077 | 3297 | -- ---------------------------------------------------------------------
|
| 3078 | 3298 | |
| 3079 | 3299 | exactDo :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))
|
| 3080 | - => (AnnList, EpaLocation) -> HsDoFlavour -> LocatedAn an a
|
|
| 3081 | - -> EP w m (AnnList, EpaLocation, LocatedAn an a)
|
|
| 3300 | + => DoAnn -> HsDoFlavour -> LocatedAn an a
|
|
| 3301 | + -> EP w m (DoAnn, LocatedAn an a)
|
|
| 3082 | 3302 | exactDo (an,l) (DoExpr m) stmts = exactMdo l m "do" >>=
|
| 3083 | 3303 | \l0 -> markMaybeDodgyStmts (an,l0) stmts
|
| 3084 | 3304 | exactDo (an,l) GhciStmtCtxt stmts = printStringAtAA l "do" >>=
|
| ... | ... | @@ -3097,15 +3317,23 @@ exactMdo l (Just module_name) kw = printStringAtAA l n |
| 3097 | 3317 | n = (moduleNameString module_name) ++ "." ++ kw
|
| 3098 | 3318 | |
| 3099 | 3319 | markMaybeDodgyStmts :: (Monad m, Monoid w, ExactPrint (LocatedAn an a))
|
| 3100 | - => (AnnList, EpaLocation) -> LocatedAn an a -> EP w m (AnnList, EpaLocation, LocatedAn an a)
|
|
| 3320 | + => DoAnn -> LocatedAn an a -> EP w m (DoAnn, LocatedAn an a)
|
|
| 3101 | 3321 | markMaybeDodgyStmts (an,l) stmts =
|
| 3102 | 3322 | if notDodgy stmts
|
| 3103 | 3323 | then do
|
| 3104 | - (an0,stmts') <- markAnnListA' an $ \a -> do
|
|
| 3105 | - r <- markAnnotatedWithLayout stmts
|
|
| 3106 | - return (a, r)
|
|
| 3107 | - return (an0, l, stmts')
|
|
| 3108 | - else return (an, l, stmts)
|
|
| 3324 | + (an0,stmts') <- case an of
|
|
| 3325 | + Left (o,c) -> do
|
|
| 3326 | + o' <- markEpToken o
|
|
| 3327 | + r <- markAnnotated stmts
|
|
| 3328 | + c' <- markEpToken c
|
|
| 3329 | + return (Left (o',c'), r)
|
|
| 3330 | + Right an' -> do
|
|
| 3331 | + (an'',r') <- markAnnListA' an' $ \a -> do
|
|
| 3332 | + r <- markAnnotatedWithLayout stmts
|
|
| 3333 | + return (a, r)
|
|
| 3334 | + return (Right an'',r')
|
|
| 3335 | + return ((an0, l), stmts')
|
|
| 3336 | + else return ((an, l), stmts)
|
|
| 3109 | 3337 | |
| 3110 | 3338 | notDodgy :: GenLocated (EpAnn ann) a -> Bool
|
| 3111 | 3339 | notDodgy (L (EpAnn anc _ _) _) = notDodgyE anc
|
| ... | ... | @@ -3388,9 +3616,7 @@ instance ExactPrint (HsCmd GhcPs) where |
| 3388 | 3616 | exact (HsCmdDo (an0,loc) es) = do
|
| 3389 | 3617 | debugM $ "HsCmdDo"
|
| 3390 | 3618 | loc' <- printStringAtAA loc "do"
|
| 3391 | - (an1,es') <- markAnnList' an0 $ do
|
|
| 3392 | - ee <- markAnnotated es
|
|
| 3393 | - return ee
|
|
| 3619 | + (an1,es') <- markAnnListD an0 $ do markAnnotated es
|
|
| 3394 | 3620 | return (HsCmdDo (an1,loc') es')
|
| 3395 | 3621 | |
| 3396 | 3622 | -- ---------------------------------------------------------------------
|
| ... | ... | @@ -343,7 +343,6 @@ insertTopLevelCppComments (HsModule (XModulePs an lo mdeprec mbDoc) mmn mexports |
| 343 | 343 | |
| 344 | 344 | annListBracketsLocs :: AnnListBrackets -> (EpaLocation,EpaLocation)
|
| 345 | 345 | annListBracketsLocs (ListBraces o c) = (getEpTokenLoc o, getEpTokenLoc c)
|
| 346 | -annListBracketsLocs (ListSquare o c) = (getEpTokenLoc o, getEpTokenLoc c)
|
|
| 347 | 346 | annListBracketsLocs ListNone = (noAnn, noAnn)
|
| 348 | 347 | |
| 349 | 348 | data SplitWhere = Before | After
|