Fix Trac #959: a long-standing bug in instantiating otherwise-unbound type variables
[ghc-hetmet.git] / compiler / iface / BinIface.hs
index 2661326..b04e6e1 100644 (file)
@@ -38,6 +38,7 @@ import FastMutInt
 import Unique
 import Outputable
 import FastString
+import Constants
 
 import Data.List
 import Data.Word
@@ -58,12 +59,13 @@ readBinIface :: CheckHiWay -> TraceBinIFaceReading -> FilePath
              -> TcRnIf a b ModIface
 readBinIface checkHiWay traceBinIFaceReading hi_path = do
   update_nc <- mkNameCacheUpdater
-  liftIO $ readBinIface_ checkHiWay traceBinIFaceReading hi_path update_nc
+  dflags <- getDOpts
+  liftIO $ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path update_nc
 
-readBinIface_ :: CheckHiWay -> TraceBinIFaceReading -> FilePath
+readBinIface_ :: DynFlags -> CheckHiWay -> TraceBinIFaceReading -> FilePath
               -> NameCacheUpdater (Array Int Name)
               -> IO ModIface
-readBinIface_ checkHiWay traceBinIFaceReading hi_path update_nc = do
+readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path update_nc = do
   let printer :: SDoc -> IO ()
       printer = case traceBinIFaceReading of
                 TraceBinIFaceReading -> \sd -> printSDoc sd defaultDumpStyle
@@ -91,12 +93,17 @@ readBinIface_ checkHiWay traceBinIFaceReading hi_path update_nc = do
   errorOnMismatch "magic number mismatch: old/corrupt interface file?"
       binaryInterfaceMagic magic
 
-        -- Get the dictionary pointer.  We won't attempt to actually
-        -- read the dictionary until we've done the version checks below,
-        -- just in case this isn't a valid interface.  In retrospect the
-        -- version should have come before the dictionary pointer, but this
-        -- is the way it was done originally, and we can't change it now.
-  dict_p <- Binary.get bh       -- Get the dictionary ptr
+        -- Note [dummy iface field]
+        -- read a dummy 32/64 bit value.  This field used to hold the
+        -- dictionary pointer in old interface file formats, but now
+        -- the dictionary pointer is after the version (where it
+        -- should be).  Also, the serialisation of value of type "Bin
+        -- a" used to depend on the word size of the machine, now they
+        -- are always 32 bits.
+        --
+  if wORD_SIZE == 4
+     then do _ <- Binary.get bh :: IO Word32; return ()
+     else do _ <- Binary.get bh :: IO Word64; return ()
 
         -- Check the interface file version and ways.
   check_ver  <- get bh
@@ -105,7 +112,7 @@ readBinIface_ checkHiWay traceBinIFaceReading hi_path update_nc = do
   errorOnMismatch "mismatched interface file versions" our_ver check_ver
 
   check_way <- get bh
-  way_descr <- getWayDescr
+  let way_descr = getWayDescr dflags
   wantedGot "Way" way_descr check_way
   when (checkHiWay == CheckHiWay) $
        errorOnMismatch "mismatched interface file ways" way_descr check_way
@@ -113,6 +120,7 @@ readBinIface_ checkHiWay traceBinIFaceReading hi_path update_nc = do
         -- Read the dictionary
         -- The next word in the file is a pointer to where the dictionary is
         -- (probably at the end of the file)
+  dict_p <- Binary.get bh
   data_p <- tellBin bh          -- Remember where we are now
   seekBin bh dict_p
   dict <- getDictionary bh
@@ -138,15 +146,22 @@ writeBinIface dflags hi_path mod_iface = do
   bh <- openBinMem initBinMemSize
   put_ bh binaryInterfaceMagic
 
-       -- Remember where the dictionary pointer will go
-  dict_p_p <- tellBin bh
-  put_ bh dict_p_p     -- Placeholder for ptr to dictionary
+       -- dummy 32/64-bit field before the version/way for
+       -- compatibility with older interface file formats.
+       -- See Note [dummy iface field] above.
+  if wORD_SIZE == 4
+     then Binary.put_ bh (0 :: Word32)
+     else Binary.put_ bh (0 :: Word64)
 
         -- The version and way descriptor go next
   put_ bh (show opt_HiVersion)
-  way_descr <- getWayDescr
+  let way_descr = getWayDescr dflags
   put_  bh way_descr
 
+       -- Remember where the dictionary pointer will go
+  dict_p_p <- tellBin bh
+  put_ bh dict_p_p     -- Placeholder for ptr to dictionary
+
         -- Remember where the symbol table pointer will go
   symtab_p_p <- tellBin bh
   put_ bh symtab_p_p
@@ -272,13 +287,13 @@ putName BinSymbolTable{
   = do
     symtab_map <- readIORef symtab_map_ref
     case lookupUFM symtab_map name of
-      Just (off,_) -> put_ bh off
+      Just (off,_) -> put_ bh (fromIntegral off :: Word32)
       Nothing -> do
          off <- readFastMutInt symtab_next
          writeFastMutInt symtab_next (off+1)
          writeIORef symtab_map_ref
              $! addToUFM symtab_map name (off,name)
-         put_ bh off          
+         put_ bh (fromIntegral off :: Word32)
 
 
 data BinSymbolTable = BinSymbolTable {
@@ -295,10 +310,10 @@ putFastString BinDictionary { bin_dict_next = j_r,
     out <- readIORef out_r
     let uniq = getUnique f
     case lookupUFM out uniq of
-        Just (j, _)  -> put_ bh j
+        Just (j, _)  -> put_ bh (fromIntegral j :: Word32)
         Nothing -> do
            j <- readFastMutInt j_r
-           put_ bh j
+           put_ bh (fromIntegral j :: Word32)
            writeFastMutInt j_r (j + 1)
            writeIORef out_r $! addToUFM out uniq (j, f)
 
@@ -448,10 +463,11 @@ instance Binary ModIface where
                 mi_fix_fn    = mkIfaceFixCache fixities,
                 mi_hash_fn   = mkIfaceHashCache decls })
 
-getWayDescr :: IO String
-getWayDescr = do
-  tag <- readIORef v_Build_tag
-  if cGhcUnregisterised == "YES" then return ('u':tag) else return tag
+getWayDescr :: DynFlags -> String
+getWayDescr dflags
+  | cGhcUnregisterised == "YES" = 'u':tag
+  | otherwise                   = tag
+  where tag = buildTag dflags
        -- if this is an unregisterised build, make sure our interfaces
        -- can't be used by a registerised build.
 
@@ -867,6 +883,7 @@ instance Binary IfaceType where
     put_ bh (IfaceTyConApp IfaceUnliftedTypeKindTc []) = putByte bh 14
     put_ bh (IfaceTyConApp IfaceUbxTupleKindTc [])     = putByte bh 15
     put_ bh (IfaceTyConApp IfaceArgTypeKindTc [])      = putByte bh 16
+    put_ bh (IfaceTyConApp (IfaceAnyTc k) [])         = do { putByte bh 17; put_ bh k }
 
        -- Generic cases
 
@@ -902,6 +919,7 @@ instance Binary IfaceType where
               14 -> return (IfaceTyConApp IfaceUnliftedTypeKindTc [])
               15 -> return (IfaceTyConApp IfaceUbxTupleKindTc [])
               16 -> return (IfaceTyConApp IfaceArgTypeKindTc [])
+              17 -> do { k <- get bh; return (IfaceTyConApp (IfaceAnyTc k) []) }
 
              18 -> do { tc <- get bh; tys <- get bh; return (IfaceTyConApp (IfaceTc tc) tys) }
              _  -> do { tc <- get bh; tys <- get bh; return (IfaceTyConApp tc tys) }
@@ -921,6 +939,7 @@ instance Binary IfaceTyCon where
    put_ bh IfaceArgTypeKindTc      = putByte bh 10
    put_ bh (IfaceTupTc bx ar) = do { putByte bh 11; put_ bh bx; put_ bh ar }
    put_ bh (IfaceTc ext)      = do { putByte bh 12; put_ bh ext }
+   put_ bh (IfaceAnyTc k)     = do { putByte bh 13; put_ bh k }
 
    get bh = do
        h <- getByte bh
@@ -936,7 +955,8 @@ instance Binary IfaceTyCon where
           9 -> return IfaceUbxTupleKindTc
           10 -> return IfaceArgTypeKindTc
          11 -> do { bx <- get bh; ar <- get bh; return (IfaceTupTc bx ar) }
-         _ -> do { ext <- get bh; return (IfaceTc ext) }
+         12 -> do { ext <- get bh; return (IfaceTc ext) }
+         _  -> do { k <- get bh; return (IfaceAnyTc k) }
 
 instance Binary IfacePredType where
     put_ bh (IfaceClassP aa ab) = do