From 17fcce4ca5bf1418d8f335e869d328e1913d3f95 Mon Sep 17 00:00:00 2001 From: Zubin Duggal Date: Tue, 16 May 2023 14:34:19 +0530 Subject: compiler: Remove instance Binary Char It is generally not a good idea to serialise strings as [Char] into interface files, as upon deserialisation each of these would be turned into a highly memory inefficient structure mostly composed of cons cells and pointers. If you really want to serialise a Char, use the SerialisableChar newtype. --- compiler/GHC/Utils/Binary.hs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'compiler/GHC/Utils/Binary.hs') diff --git a/compiler/GHC/Utils/Binary.hs b/compiler/GHC/Utils/Binary.hs index 7534d65918..6ee06274d3 100644 --- a/compiler/GHC/Utils/Binary.hs +++ b/compiler/GHC/Utils/Binary.hs @@ -1,5 +1,7 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -81,7 +83,7 @@ module GHC.Utils.Binary FSTable, initFSTable, getDictFastString, putDictFastString, -- * Newtype wrappers - BinSpan(..), BinSrcSpan(..), BinLocated(..) + BinSpan(..), BinSrcSpan(..), BinLocated(..), SerialisableChar(..) ) where import GHC.Prelude @@ -125,6 +127,8 @@ import qualified Data.IntMap as IntMap import GHC.ForeignPtr ( unsafeWithForeignPtr ) #endif +import GHC.TypeError + type BinArray = ForeignPtr Word8 #if !MIN_VERSION_base(4,15,0) @@ -675,9 +679,20 @@ instance Binary Bool where put_ bh b = putByte bh (fromIntegral (fromEnum b)) get bh = do x <- getWord8 bh; return $! (toEnum (fromIntegral x)) -instance Binary Char where - put_ bh c = put_ bh (fromIntegral (ord c) :: Word32) - get bh = do x <- get bh; return $! (chr (fromIntegral (x :: Word32))) +instance (TypeError (Text "No instance for Binary Char" + :$$: Text "We don't want to serialise Strings into interface files" + :$$: Text "Use a compact representation like " :<>: ShowType FastString :<>: Text " instead" + :$$: Text "If you really want to serialise you can use " :<>: ShowType SerialisableChar) + ) + => Binary Char where + put_ = undefined + get = undefined + +newtype SerialisableChar = SerialisableChar { getSerialisedChar :: Char } + +instance Binary SerialisableChar where + put_ bh (SerialisableChar c) = put_ bh (fromIntegral (ord c) :: Word32) + get bh = do x <- get bh; return $! (SerialisableChar $ chr (fromIntegral (x :: Word32))) instance Binary Int where put_ bh i = put_ bh (fromIntegral i :: Int64) -- cgit v1.2.1