[Git][ghc/ghc][wip/int-index/no-multiline] Refactor: merge HsMultilineString into HsString (#26860)
Vladislav Zavialov pushed to branch wip/int-index/no-multiline at Glasgow Haskell Compiler / GHC Commits: 1d461f72 by Vladislav Zavialov at 2026-01-30T23:09:44+03:00 Refactor: merge HsMultilineString into HsString (#26860) Before this patch, HsLit defined two separate constructors to represent single-line and multi-line strings: data HsLit x ... | HsString (XHsString x) FastString | HsMultilineString (XHsMultilineString x) FastString I found this to be an unnecessary complication and an obstacle to unifying HsLit with HsTyLit. Now we use HsString for both kinds of literals. In addition (and unrelatedly to the main payload of this patch), drop the unused pmPprHsLit helper. - - - - - 11 changed files: - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/String.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Lit.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Lit.hs ===================================== @@ -45,7 +45,6 @@ import Language.Haskell.Syntax.Lit type instance XHsChar (GhcPass _) = SourceText type instance XHsCharPrim (GhcPass _) = SourceText type instance XHsString (GhcPass _) = SourceText -type instance XHsMultilineString (GhcPass _) = SourceText type instance XHsStringPrim (GhcPass _) = SourceText type instance XHsInt (GhcPass _) = NoExtField type instance XHsIntPrim (GhcPass _) = SourceText @@ -147,7 +146,6 @@ hsLitNeedsParens p = go go (HsChar {}) = False go (HsCharPrim {}) = False go (HsString {}) = False - go (HsMultilineString {}) = False go (HsStringPrim {}) = False go (HsInt _ x) = p > topPrec && il_neg x go (HsFloatPrim {}) = False @@ -177,7 +175,6 @@ convertLit :: XXLit (GhcPass p)~DataConCantHappen => HsLit (GhcPass p) -> HsLit convertLit (HsChar a x) = HsChar a x convertLit (HsCharPrim a x) = HsCharPrim a x convertLit (HsString a x) = HsString a x -convertLit (HsMultilineString a x) = HsMultilineString a x convertLit (HsStringPrim a x) = HsStringPrim a x convertLit (HsInt a x) = HsInt a x convertLit (HsIntPrim a x) = HsIntPrim a x @@ -212,8 +209,7 @@ Equivalently it's True if instance IsPass p => Outputable (HsLit (GhcPass p)) where ppr (HsChar st c) = pprWithSourceText st (pprHsChar c) ppr (HsCharPrim st c) = pprWithSourceText st (pprPrimChar c) - ppr (HsString st s) = pprWithSourceText st (pprHsString s) - ppr (HsMultilineString st s) = + ppr (HsString st s) = case st of NoSourceText -> pprHsString s SourceText src -> vcat $ map text $ split '\n' (unpackFS src) @@ -248,36 +244,6 @@ instance Outputable OverLitVal where ppr (HsFractional f) = ppr f ppr (HsIsString st s) = pprWithSourceText st (pprHsString s) --- | pmPprHsLit pretty prints literals and is used when pretty printing pattern --- match warnings. All are printed the same (i.e., without hashes if they are --- primitive and not wrapped in constructors if they are boxed). This happens --- mainly for too reasons: --- * We do not want to expose their internal representation --- * The warnings become too messy -pmPprHsLit :: forall p. IsPass p => HsLit (GhcPass p) -> SDoc -pmPprHsLit (HsChar _ c) = pprHsChar c -pmPprHsLit (HsCharPrim _ c) = pprHsChar c -pmPprHsLit (HsString st s) = pprWithSourceText st (pprHsString s) -pmPprHsLit (HsMultilineString st s) = pprWithSourceText st (pprHsString s) -pmPprHsLit (HsStringPrim _ s) = pprHsBytes s -pmPprHsLit (HsInt _ i) = integer (il_value i) -pmPprHsLit (HsIntPrim _ i) = integer i -pmPprHsLit (HsWordPrim _ w) = integer w -pmPprHsLit (HsInt8Prim _ i) = integer i -pmPprHsLit (HsInt16Prim _ i) = integer i -pmPprHsLit (HsInt32Prim _ i) = integer i -pmPprHsLit (HsInt64Prim _ i) = integer i -pmPprHsLit (HsWord8Prim _ w) = integer w -pmPprHsLit (HsWord16Prim _ w) = integer w -pmPprHsLit (HsWord32Prim _ w) = integer w -pmPprHsLit (HsWord64Prim _ w) = integer w -pmPprHsLit (HsFloatPrim _ f) = ppr f -pmPprHsLit (HsDoublePrim _ d) = ppr d -pmPprHsLit (XLit x) = case ghcPass @p of - GhcTc -> case x of - (HsInteger _ i _) -> integer i - (HsRat f _) -> ppr f - negateOverLitVal :: OverLitVal -> OverLitVal negateOverLitVal (HsIntegral i) = HsIntegral (negateIntegralLit i) negateOverLitVal (HsFractional f) = HsFractional (negateFractionalLit f) ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -75,7 +75,6 @@ hsLitType :: forall p. IsPass p => HsLit (GhcPass p) -> Type hsLitType (HsChar _ _) = charTy hsLitType (HsCharPrim _ _) = charPrimTy hsLitType (HsString _ _) = stringTy -hsLitType (HsMultilineString _ _) = stringTy hsLitType (HsStringPrim _ _) = addrPrimTy hsLitType (HsInt _ _) = intTy hsLitType (HsIntPrim _ _) = intPrimTy ===================================== compiler/GHC/HsToCore/Match/Literal.hs ===================================== @@ -117,7 +117,6 @@ dsLit l = do HsDoublePrim _ fl -> return (Lit (LitDouble (rationalFromFractionalLit fl))) HsChar _ c -> return (mkCharExpr c) HsString _ str -> mkStringExprFS str - HsMultilineString _ str -> mkStringExprFS str HsInt _ i -> return (mkIntExpr platform (il_value i)) XLit x -> case ghcPass @p of GhcTc -> case x of @@ -463,7 +462,6 @@ getSimpleIntegralLit (XLit (HsInteger _ i ty)) = Just (i, ty) getSimpleIntegralLit HsChar{} = Nothing getSimpleIntegralLit HsCharPrim{} = Nothing getSimpleIntegralLit HsString{} = Nothing -getSimpleIntegralLit HsMultilineString{} = Nothing getSimpleIntegralLit HsStringPrim{} = Nothing getSimpleIntegralLit (XLit (HsRat{})) = Nothing getSimpleIntegralLit HsFloatPrim{} = Nothing ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -3077,7 +3077,6 @@ repLiteral lit HsChar _ _ -> Just charLName HsCharPrim _ _ -> Just charPrimLName HsString _ _ -> Just stringLName - HsMultilineString _ _ -> Just stringLName _ -> Nothing mk_integer :: Integer -> MetaM (HsLit GhcTc) ===================================== compiler/GHC/Parser.y ===================================== @@ -4130,7 +4130,7 @@ literal :: { Located (HsLit GhcPs) } : CHAR { sL1 $1 $ HsChar (getCHARs $1) $ getCHAR $1 } | STRING { sL1 $1 $ HsString (getSTRINGs $1) $ getSTRING $1 } - | STRING_MULTI { sL1 $1 $ HsMultilineString (getSTRINGMULTIs $1) + | STRING_MULTI { sL1 $1 $ HsString (getSTRINGMULTIs $1) $ getSTRINGMULTI $1 } | PRIMINTEGER { sL1 $1 $ HsIntPrim (getPRIMINTEGERs $1) $ getPRIMINTEGER $1 } ===================================== compiler/GHC/Parser/String.hs ===================================== @@ -392,9 +392,9 @@ proposal: https://github.com/ghc-proposals/ghc-proposals/pull/569 Multiline string literals are syntax sugar for normal string literals, with an extra post processing step. This all happens in the Lexer; that -is, HsMultilineString will contain the post-processed string. This matches -the same behavior as HsString, which contains the normalized string -(see Note [Literal source text]). +is, the multi-line HsString will contain the post-processed string. +This matches the behavior of the single-line HsString, which contains +the normalized string too (see Note [Literal source text]). The canonical steps for post processing a multiline string are: 1. Collapse string gaps ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -352,18 +352,13 @@ rnExpr (HsOverLabel src v) hs_ty_arg = mkEmptyWildCardBndrs $ wrapGenSpan $ HsTyLit noExtField (HsStrTy NoSourceText v) -rnExpr (HsLit x lit) | Just (src, s) <- stringLike lit +rnExpr (HsLit x lit) | HsString src s <- lit = do { opt_OverloadedStrings <- xoptM LangExt.OverloadedStrings ; if opt_OverloadedStrings then rnExpr (HsOverLit x (mkHsIsString src s)) else do { ; rnLit lit ; return (HsLit x (convertLit lit), emptyFVs) } } - where - stringLike = \case - HsString src s -> Just (src, s) - HsMultilineString src s -> Just (src, s) - _ -> Nothing rnExpr (HsLit x lit) = do { rnLit lit ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -4786,7 +4786,6 @@ promotionErr name err tyLitFromLit :: HsLit GhcRn -> Maybe (HsTyLit GhcRn) tyLitFromLit (HsString x str) = Just (HsStrTy x str) -tyLitFromLit (HsMultilineString x str) = Just (HsStrTy x str) tyLitFromLit (HsChar x char) = Just (HsCharTy x char) tyLitFromLit _ = Nothing ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -604,7 +604,6 @@ type family XXParStmtBlock x x' type family XHsChar x type family XHsCharPrim x type family XHsString x -type family XHsMultilineString x type family XHsStringPrim x type family XHsInt x type family XHsIntPrim x ===================================== compiler/Language/Haskell/Syntax/Lit.hs ===================================== @@ -47,8 +47,6 @@ data HsLit x -- ^ Unboxed character | HsString (XHsString x) {- SourceText -} FastString -- ^ String - | HsMultilineString (XHsMultilineString x) {- SourceText -} FastString - -- ^ String | HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString -- ^ Packed bytes | HsInt (XHsInt x) IntegralLit ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4794,7 +4794,6 @@ hsLit2String lit = HsChar src v -> toSourceTextWithSuffix src v "" HsCharPrim src p -> toSourceTextWithSuffix src p "" HsString src v -> toSourceTextWithSuffix src v "" - HsMultilineString src v -> toSourceTextWithSuffix src v "" HsStringPrim src v -> toSourceTextWithSuffix src v "" HsInt _ (IL src _ v) -> toSourceTextWithSuffix src v "" HsIntPrim src v -> toSourceTextWithSuffix src v "" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d461f728d4e65726725f02e4dab8549... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d461f728d4e65726725f02e4dab8549... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Vladislav Zavialov (@int-index)