summaryrefslogtreecommitdiff
path: root/compiler/GHC/Utils/Binary.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Utils/Binary.hs')
-rw-r--r--compiler/GHC/Utils/Binary.hs60
1 files changed, 44 insertions, 16 deletions
diff --git a/compiler/GHC/Utils/Binary.hs b/compiler/GHC/Utils/Binary.hs
index f224589ee0..26328d8d05 100644
--- a/compiler/GHC/Utils/Binary.hs
+++ b/compiler/GHC/Utils/Binary.hs
@@ -73,6 +73,9 @@ module GHC.Utils.Binary
UserData(..), getUserData, setUserData,
newReadState, newWriteState,
putDictionary, getDictionary, putFS,
+
+ -- * Newtype wrappers
+ BinSpan(..), BinSrcSpan(..), BinLocated(..)
) where
import GHC.Prelude
@@ -1285,18 +1288,23 @@ instance Binary ModuleName where
-- fs <- get bh
-- return (StringLiteral st fs Nothing)
-instance Binary a => Binary (Located a) where
- put_ bh (L l x) = do
- put_ bh l
+newtype BinLocated a = BinLocated { unBinLocated :: Located a }
+
+instance Binary a => Binary (BinLocated a) where
+ put_ bh (BinLocated (L l x)) = do
+ put_ bh $ BinSrcSpan l
put_ bh x
get bh = do
- l <- get bh
+ l <- unBinSrcSpan <$> get bh
x <- get bh
- return (L l x)
+ return $ BinLocated (L l x)
+
+newtype BinSpan = BinSpan { unBinSpan :: RealSrcSpan }
-instance Binary RealSrcSpan where
- put_ bh ss = do
+-- See Note [Source Location Wrappers]
+instance Binary BinSpan where
+ put_ bh (BinSpan ss) = do
put_ bh (srcSpanFile ss)
put_ bh (srcSpanStartLine ss)
put_ bh (srcSpanStartCol ss)
@@ -1309,8 +1317,8 @@ instance Binary RealSrcSpan where
sc <- get bh
el <- get bh
ec <- get bh
- return (mkRealSrcSpan (mkRealSrcLoc f sl sc)
- (mkRealSrcLoc f el ec))
+ return $ BinSpan (mkRealSrcSpan (mkRealSrcLoc f sl sc)
+ (mkRealSrcLoc f el ec))
instance Binary UnhelpfulSpanReason where
put_ bh r = case r of
@@ -1329,24 +1337,44 @@ instance Binary UnhelpfulSpanReason where
3 -> return UnhelpfulGenerated
_ -> UnhelpfulOther <$> get bh
-instance Binary SrcSpan where
- put_ bh (RealSrcSpan ss _sb) = do
+newtype BinSrcSpan = BinSrcSpan { unBinSrcSpan :: SrcSpan }
+
+-- See Note [Source Location Wrappers]
+instance Binary BinSrcSpan where
+ put_ bh (BinSrcSpan (RealSrcSpan ss _sb)) = do
putByte bh 0
-- BufSpan doesn't ever get serialised because the positions depend
-- on build location.
- put_ bh ss
+ put_ bh $ BinSpan ss
- put_ bh (UnhelpfulSpan s) = do
+ put_ bh (BinSrcSpan (UnhelpfulSpan s)) = do
putByte bh 1
put_ bh s
get bh = do
h <- getByte bh
case h of
- 0 -> do ss <- get bh
- return (RealSrcSpan ss Strict.Nothing)
+ 0 -> do BinSpan ss <- get bh
+ return $ BinSrcSpan (RealSrcSpan ss Strict.Nothing)
_ -> do s <- get bh
- return (UnhelpfulSpan s)
+ return $ BinSrcSpan (UnhelpfulSpan s)
+
+
+{-
+Note [Source Location Wrappers]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Source locations are banned from interface files, to
+prevent filepaths affecting interface hashes.
+
+Unfortunately, we can't remove all binary instances,
+as they're used to serialise .hie files, and we don't
+want to break binary compatibility.
+
+To this end, the Bin[Src]Span newtypes wrappers were
+introduced to prevent accidentally serialising a
+source location as part of a larger structure.
+-}
--------------------------------------------------------------------------------
-- Instances for the containers package