| ... |
... |
@@ -139,6 +139,7 @@ import Foreign.C |
|
139
|
139
|
import System.IO
|
|
140
|
140
|
import Data.Data
|
|
141
|
141
|
import Data.IORef
|
|
|
142
|
+import qualified Data.List.NonEmpty as NE
|
|
142
|
143
|
import Data.Semigroup as Semi
|
|
143
|
144
|
|
|
144
|
145
|
import Foreign
|
| ... |
... |
@@ -232,6 +233,7 @@ instance IsString FastString where |
|
232
|
233
|
|
|
233
|
234
|
instance Semi.Semigroup FastString where
|
|
234
|
235
|
(<>) = appendFS
|
|
|
236
|
+ sconcat = concatFS . NE.toList
|
|
235
|
237
|
|
|
236
|
238
|
instance Monoid FastString where
|
|
237
|
239
|
mempty = nilFS
|
| ... |
... |
@@ -619,6 +621,42 @@ unpackFS fs = utf8DecodeShortByteString $ fs_sbs fs |
|
619
|
621
|
zEncodeFS :: FastString -> FastZString
|
|
620
|
622
|
zEncodeFS fs = fs_zenc fs
|
|
621
|
623
|
|
|
|
624
|
+-- Sometimes an `appendFS` operand is temporarily constructed, and we
|
|
|
625
|
+-- should avoid retaining the unused `FastString` operand in the
|
|
|
626
|
+-- table. The RULES below mitigate the issue by concatenating the
|
|
|
627
|
+-- `ShortByteString`s instead when an operand is `fsLit` or
|
|
|
628
|
+-- `mkFastString`, which cover most such `appendFS` use cases. See
|
|
|
629
|
+-- #27205.
|
|
|
630
|
+
|
|
|
631
|
+{-# RULES
|
|
|
632
|
+"appendFS/fsLit y" forall x y.
|
|
|
633
|
+ appendFS x (fsLit y) =
|
|
|
634
|
+ mkFastStringShortByteString $
|
|
|
635
|
+ fs_sbs x Semi.<> utf8EncodeShortByteString y
|
|
|
636
|
+ #-}
|
|
|
637
|
+
|
|
|
638
|
+{-# RULES
|
|
|
639
|
+"appendFS/fsLit x" forall x y.
|
|
|
640
|
+ appendFS (fsLit x) y =
|
|
|
641
|
+ mkFastStringShortByteString $
|
|
|
642
|
+ utf8EncodeShortByteString x Semi.<> fs_sbs y
|
|
|
643
|
+ #-}
|
|
|
644
|
+
|
|
|
645
|
+{-# RULES
|
|
|
646
|
+"appendFS/mkFastString y" forall x y.
|
|
|
647
|
+ appendFS x (mkFastString y) =
|
|
|
648
|
+ mkFastStringShortByteString $
|
|
|
649
|
+ fs_sbs x Semi.<> utf8EncodeShortByteString y
|
|
|
650
|
+ #-}
|
|
|
651
|
+
|
|
|
652
|
+{-# RULES
|
|
|
653
|
+"appendFS/mkFastString x" forall x y.
|
|
|
654
|
+ appendFS (mkFastString x) y =
|
|
|
655
|
+ mkFastStringShortByteString $
|
|
|
656
|
+ utf8EncodeShortByteString x Semi.<> fs_sbs y
|
|
|
657
|
+ #-}
|
|
|
658
|
+
|
|
|
659
|
+{-# INLINE[1] appendFS #-}
|
|
622
|
660
|
appendFS :: FastString -> FastString -> FastString
|
|
623
|
661
|
appendFS fs1 fs2 = mkFastStringShortByteString
|
|
624
|
662
|
$ (Semi.<>) (fs_sbs fs1) (fs_sbs fs2)
|