summaryrefslogtreecommitdiff
path: root/compiler/iface
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/iface')
-rw-r--r--compiler/iface/BinIface.hs251
-rw-r--r--compiler/iface/IfaceEnv.lhs160
-rw-r--r--compiler/iface/IfaceSyn.lhs159
-rw-r--r--compiler/iface/IfaceType.lhs141
-rw-r--r--compiler/iface/LoadIface.lhs103
-rw-r--r--compiler/iface/MkIface.lhs558
-rw-r--r--compiler/iface/TcIface.lhs78
7 files changed, 763 insertions, 687 deletions
diff --git a/compiler/iface/BinIface.hs b/compiler/iface/BinIface.hs
index 3e9895a5bf..3e79a3947c 100644
--- a/compiler/iface/BinIface.hs
+++ b/compiler/iface/BinIface.hs
@@ -9,20 +9,39 @@ module BinIface ( writeBinIface, readBinIface, v_IgnoreHiWay ) where
#include "HsVersions.h"
+import TcRnMonad ( TcRnIf, ioToIOEnv )
+import IfaceEnv
import HscTypes
import BasicTypes
import NewDemand
import IfaceSyn
+import Module ( ModuleName, mkModule, modulePackageId, moduleName )
+import Name
+import OccName ( OccName )
import VarEnv
import InstEnv ( OverlapFlag(..) )
import Class ( DefMeth(..) )
+import DynFlags ( DynFlags )
+import UniqFM ( UniqFM, eltsUFM )
+import UniqSupply ( uniqFromSupply, splitUniqSupply )
import CostCentre
import StaticFlags ( opt_HiVersion, v_Build_tag )
+import Type ( Kind,
+ isLiftedTypeKind, isUnliftedTypeKind, isOpenTypeKind,
+ isArgTypeKind, isUbxTupleKind, liftedTypeKind,
+ unliftedTypeKind, openTypeKind, argTypeKind,
+ ubxTupleKind, mkArrowKind, splitFunTy_maybe )
+import PackageConfig ( PackageId )
import Panic
import Binary
+import SrcLoc ( noSrcLoc )
import Util
+import ErrUtils ( debugTraceMsg )
import Config ( cGhcUnregisterised )
+import FastMutInt ( readFastMutInt )
+import Data.Word ( Word32 )
+import Data.Array ( Array, array, elems, listArray, (!) )
import DATA_IOREF
import EXCEPTION ( throwDyn )
import Monad ( when )
@@ -31,19 +50,164 @@ import Outputable
#include "HsVersions.h"
-- ---------------------------------------------------------------------------
-writeBinIface :: FilePath -> ModIface -> IO ()
-writeBinIface hi_path mod_iface
- = putBinFileWithDict hi_path mod_iface
-
-readBinIface :: FilePath -> IO ModIface
-readBinIface hi_path = getBinFileWithDict hi_path
-
-
--- %*********************************************************
--- %* *
--- All the Binary instances
--- %* *
--- %*********************************************************
+-- Reading and writing binary interface files
+
+readBinIface :: FilePath -> TcRnIf a b ModIface
+readBinIface hi_path = do
+ nc <- getNameCache
+ (new_nc, iface) <- ioToIOEnv $ readBinIface_ hi_path nc
+ setNameCache new_nc
+ return iface
+
+readBinIface_ :: FilePath -> NameCache -> IO (NameCache, ModIface)
+readBinIface_ hi_path nc = do
+ bh <- Binary.readBinMem hi_path
+
+ -- Read the magic number to check that this really is a GHC .hi file
+ -- (This magic number does not change when we change
+ -- GHC interface file format)
+ magic <- get bh
+ when (magic /= binaryInterfaceMagic) $
+ throwDyn (ProgramError (
+ "magic number mismatch: old/corrupt interface file?"))
+
+ -- 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 -- Get the dictionary ptr
+ data_p <- tellBin bh -- Remember where we are now
+ seekBin bh dict_p
+ dict <- getDictionary bh
+ seekBin bh data_p -- Back to where we were before
+
+ -- Initialise the user-data field of bh
+ ud <- newReadState dict
+ bh <- return (setUserData bh ud)
+
+ symtab_p <- Binary.get bh -- Get the symtab ptr
+ data_p <- tellBin bh -- Remember where we are now
+ seekBin bh symtab_p
+ (nc', symtab) <- getSymbolTable bh nc
+ seekBin bh data_p -- Back to where we were before
+ let ud = getUserData bh
+ bh <- return $! setUserData bh ud{ud_symtab = symtab}
+ iface <- get bh
+ return (nc', iface)
+
+
+writeBinIface :: DynFlags -> FilePath -> ModIface -> IO ()
+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
+
+ -- Remember where the symbol table pointer will go
+ symtab_p_p <- tellBin bh
+ put_ bh symtab_p_p
+
+ -- Make some intial state
+ ud <- newWriteState
+
+ -- Put the main thing,
+ bh <- return $ setUserData bh ud
+ put_ bh mod_iface
+
+ -- Write the symtab pointer at the fornt of the file
+ symtab_p <- tellBin bh -- This is where the symtab will start
+ putAt bh symtab_p_p symtab_p -- Fill in the placeholder
+ seekBin bh symtab_p -- Seek back to the end of the file
+
+ -- Write the symbol table itself
+ symtab_next <- readFastMutInt (ud_symtab_next ud)
+ symtab_map <- readIORef (ud_symtab_map ud)
+ putSymbolTable bh symtab_next symtab_map
+ debugTraceMsg dflags 3 (text "writeBinIface:" <+> int symtab_next
+ <+> text "Names")
+
+ -- NB. write the dictionary after the symbol table, because
+ -- writing the symbol table may create more dictionary entries.
+
+ -- Write the dictionary pointer at the fornt of the file
+ dict_p <- tellBin bh -- This is where the dictionary will start
+ putAt bh dict_p_p dict_p -- Fill in the placeholder
+ seekBin bh dict_p -- Seek back to the end of the file
+
+ -- Write the dictionary itself
+ dict_next <- readFastMutInt (ud_dict_next ud)
+ dict_map <- readIORef (ud_dict_map ud)
+ putDictionary bh dict_next dict_map
+ debugTraceMsg dflags 3 (text "writeBinIface:" <+> int dict_next
+ <+> text "dict entries")
+
+ -- And send the result to the file
+ writeBinMem bh hi_path
+
+initBinMemSize = (1024*1024) :: Int
+
+-- The *host* architecture version:
+#include "MachDeps.h"
+
+#if WORD_SIZE_IN_BITS == 32
+binaryInterfaceMagic = 0x1face :: Word32
+#elif WORD_SIZE_IN_BITS == 64
+binaryInterfaceMagic = 0x1face64 :: Word32
+#endif
+
+-- -----------------------------------------------------------------------------
+-- The symbol table
+
+putSymbolTable :: BinHandle -> Int -> UniqFM (Int,Name) -> IO ()
+putSymbolTable bh next_off symtab = do
+ put_ bh next_off
+ let names = elems (array (0,next_off-1) (eltsUFM symtab))
+ mapM_ (\n -> serialiseName bh n symtab) names
+
+getSymbolTable :: BinHandle -> NameCache -> IO (NameCache, Array Int Name)
+getSymbolTable bh namecache = do
+ sz <- get bh
+ od_names <- sequence (replicate sz (get bh))
+ let
+ arr = listArray (0,sz-1) names
+ (namecache', names) =
+ mapAccumR (fromOnDiskName arr) namecache od_names
+ --
+ return (namecache', arr)
+
+type OnDiskName = (PackageId, ModuleName, OccName)
+
+fromOnDiskName
+ :: Array Int Name
+ -> NameCache
+ -> OnDiskName
+ -> (NameCache, Name)
+fromOnDiskName arr nc (pid, mod_name, occ) =
+ let
+ mod = mkModule pid mod_name
+ cache = nsNames nc
+ in
+ case lookupOrigNameCache cache mod occ of
+ Just name -> (nc, name)
+ Nothing ->
+ let
+ us = nsUniqs nc
+ uniq = uniqFromSupply us
+ name = mkExternalName uniq mod occ noSrcLoc
+ new_cache = extendNameCache cache mod occ name
+ in
+ case splitUniqSupply us of { (us',_) ->
+ ( nc{ nsUniqs = us', nsNames = new_cache }, name )
+ }
+
+serialiseName :: BinHandle -> Name -> UniqFM (Int,Name) -> IO ()
+serialiseName bh name symtab = do
+ let mod = nameModule name
+ put_ bh (modulePackageId mod, moduleName mod, nameOccName name)
+
+-- -----------------------------------------------------------------------------
+-- All the binary instances
-- BasicTypes
{-! for IPName derive: Binary !-}
@@ -504,36 +668,6 @@ instance Binary CostCentre where
-- IfaceTypes and friends
-------------------------------------------------------------------------
-instance Binary IfaceExtName where
- put_ bh (ExtPkg mod occ) = do
- putByte bh 0
- put_ bh mod
- put_ bh occ
- put_ bh (HomePkg mod occ vers) = do
- putByte bh 1
- put_ bh mod
- put_ bh occ
- put_ bh vers
- put_ bh (LocalTop occ) = do
- putByte bh 2
- put_ bh occ
- put_ bh (LocalTopSub occ _) = do -- Write LocalTopSub just like LocalTop
- putByte bh 2
- put_ bh occ
-
- get bh = do
- h <- getByte bh
- case h of
- 0 -> do mod <- get bh
- occ <- get bh
- return (ExtPkg mod occ)
- 1 -> do mod <- get bh
- occ <- get bh
- vers <- get bh
- return (HomePkg mod occ vers)
- _ -> do occ <- get bh
- return (LocalTop occ)
-
instance Binary IfaceBndr where
put_ bh (IfaceIdBndr aa) = do
putByte bh 0
@@ -884,17 +1018,23 @@ instance Binary IfaceNote where
-- IfaceDecl and friends
-------------------------------------------------------------------------
+-- A bit of magic going on here: there's no need to store the OccName
+-- for a decl on the disk, since we can infer the namespace from the
+-- context; however it is useful to have the OccName in the IfaceDecl
+-- to avoid re-building it in various places. So we build the OccName
+-- when de-serialising.
+
instance Binary IfaceDecl where
put_ bh (IfaceId name ty idinfo) = do
putByte bh 0
- put_ bh name
+ put_ bh (occNameFS name)
put_ bh ty
put_ bh idinfo
put_ bh (IfaceForeign ae af) =
error "Binary.put_(IfaceDecl): IfaceForeign"
put_ bh (IfaceData a1 a2 a3 a4 a5 a6 a7 a8) = do
putByte bh 2
- put_ bh a1
+ put_ bh (occNameFS a1)
put_ bh a2
put_ bh a3
put_ bh a4
@@ -904,14 +1044,14 @@ instance Binary IfaceDecl where
put_ bh a8
put_ bh (IfaceSyn aq ar as at) = do
putByte bh 3
- put_ bh aq
+ put_ bh (occNameFS aq)
put_ bh ar
put_ bh as
put_ bh at
put_ bh (IfaceClass a1 a2 a3 a4 a5 a6 a7) = do
putByte bh 4
put_ bh a1
- put_ bh a2
+ put_ bh (occNameFS a2)
put_ bh a3
put_ bh a4
put_ bh a5
@@ -923,7 +1063,8 @@ instance Binary IfaceDecl where
0 -> do name <- get bh
ty <- get bh
idinfo <- get bh
- return (IfaceId name ty idinfo)
+ occ <- return $! mkOccNameFS varName name
+ return (IfaceId occ ty idinfo)
1 -> error "Binary.get(TyClDecl): ForeignType"
2 -> do
a1 <- get bh
@@ -934,13 +1075,15 @@ instance Binary IfaceDecl where
a6 <- get bh
a7 <- get bh
a8 <- get bh
- return (IfaceData a1 a2 a3 a4 a5 a6 a7 a8)
+ occ <- return $! mkOccNameFS tcName a1
+ return (IfaceData occ a2 a3 a4 a5 a6 a7 a8)
3 -> do
aq <- get bh
ar <- get bh
as <- get bh
at <- get bh
- return (IfaceSyn aq ar as at)
+ occ <- return $! mkOccNameFS tcName aq
+ return (IfaceSyn occ ar as at)
_ -> do
a1 <- get bh
a2 <- get bh
@@ -949,7 +1092,8 @@ instance Binary IfaceDecl where
a5 <- get bh
a6 <- get bh
a7 <- get bh
- return (IfaceClass a1 a2 a3 a4 a5 a6 a7)
+ occ <- return $! mkOccNameFS clsName a2
+ return (IfaceClass a1 occ a3 a4 a5 a6 a7)
instance Binary IfaceInst where
put_ bh (IfaceInst cls tys dfun flag orph) = do
@@ -1028,14 +1172,15 @@ instance Binary IfaceConDecl where
instance Binary IfaceClassOp where
put_ bh (IfaceClassOp n def ty) = do
- put_ bh n
+ put_ bh (occNameFS n)
put_ bh def
put_ bh ty
get bh = do
n <- get bh
def <- get bh
ty <- get bh
- return (IfaceClassOp n def ty)
+ occ <- return $! mkOccNameFS varName n
+ return (IfaceClassOp occ def ty)
instance Binary IfaceRule where
put_ bh (IfaceRule a1 a2 a3 a4 a5 a6 a7) = do
diff --git a/compiler/iface/IfaceEnv.lhs b/compiler/iface/IfaceEnv.lhs
index 61759658d3..fe0b0cdb22 100644
--- a/compiler/iface/IfaceEnv.lhs
+++ b/compiler/iface/IfaceEnv.lhs
@@ -3,31 +3,31 @@
\begin{code}
module IfaceEnv (
newGlobalBinder, newIPName, newImplicitBinder,
- lookupIfaceTop, lookupIfaceExt,
- lookupOrig, lookupIfaceTc,
+ lookupIfaceTop,
+ lookupOrig, lookupOrigNameCache, extendNameCache,
newIfaceName, newIfaceNames,
extendIfaceIdEnv, extendIfaceTyVarEnv,
tcIfaceLclId, tcIfaceTyVar,
- lookupAvail, ifaceExportNames,
+ ifaceExportNames,
-- Name-cache stuff
allocateGlobalBinder, initNameCache,
+ getNameCache, setNameCache
) where
#include "HsVersions.h"
import TcRnMonad
-import IfaceType ( IfaceExtName(..), IfaceTyCon(..), ifaceTyConName )
import TysWiredIn ( tupleTyCon, tupleCon )
import HscTypes ( NameCache(..), HscEnv(..), GenAvailInfo(..),
- IfaceExport, OrigNameCache )
+ IfaceExport, OrigNameCache, AvailInfo )
+import Type ( mkOpenTvSubst, substTy )
import TyCon ( TyCon, tyConName )
import DataCon ( dataConWorkId, dataConName )
import Var ( TyVar, Id, varName )
-import Name ( Name, nameUnique, nameModule,
- nameOccName, nameSrcLoc,
- getOccName, nameParent_maybe,
+import Name ( Name, nameUnique, nameModule,
+ nameOccName, nameSrcLoc, getOccName,
isWiredInName, mkIPName,
mkExternalName, mkInternalName )
import NameSet ( NameSet, emptyNameSet, addListToNameSet )
@@ -54,7 +54,7 @@ import Outputable
%*********************************************************
\begin{code}
-newGlobalBinder :: Module -> OccName -> Maybe Name -> SrcLoc -> TcRnIf a b Name
+newGlobalBinder :: Module -> OccName -> SrcLoc -> TcRnIf a b Name
-- Used for source code and interface files, to make the
-- Name for a thing, given its Module and OccName
--
@@ -62,25 +62,25 @@ newGlobalBinder :: Module -> OccName -> Maybe Name -> SrcLoc -> TcRnIf a b Name
-- because we may have seen an occurrence before, but now is the
-- moment when we know its Module and SrcLoc in their full glory
-newGlobalBinder mod occ mb_parent loc
+newGlobalBinder mod occ loc
= do { mod `seq` occ `seq` return () -- See notes with lookupOrig_help
- -- ; traceIf (text "newGlobalBinder" <+> ppr mod <+> ppr occ <+> ppr loc)
+ ; traceIf (text "newGlobalBinder" <+> ppr mod <+> ppr occ <+> ppr loc)
; name_supply <- getNameCache
; let (name_supply', name) = allocateGlobalBinder
name_supply mod occ
- mb_parent loc
+ loc
; setNameCache name_supply'
; return name }
allocateGlobalBinder
:: NameCache
- -> Module -> OccName -> Maybe Name -> SrcLoc
+ -> Module -> OccName -> SrcLoc
-> (NameCache, Name)
-allocateGlobalBinder name_supply mod occ mb_parent loc
+allocateGlobalBinder name_supply mod occ loc
= case lookupOrigNameCache (nsNames name_supply) mod occ of
-- A hit in the cache! We are at the binding site of the name.
- -- This is the moment when we know the defining parent and SrcLoc
- -- of the Name, so we set these fields in the Name we return.
+ -- This is the moment when we know the SrcLoc
+ -- of the Name, so we set this field in the Name we return.
--
-- Then (bogus) multiple bindings of the same Name
-- get different SrcLocs can can be reported as such.
@@ -98,8 +98,8 @@ allocateGlobalBinder name_supply mod occ mb_parent loc
| otherwise -> (new_name_supply, name')
where
uniq = nameUnique name
- name' = mkExternalName uniq mod occ mb_parent loc
- new_cache = extend_name_cache (nsNames name_supply) mod occ name'
+ name' = mkExternalName uniq mod occ loc
+ new_cache = extendNameCache (nsNames name_supply) mod occ name'
new_name_supply = name_supply {nsNames = new_cache}
-- Miss in the cache!
@@ -108,8 +108,8 @@ allocateGlobalBinder name_supply mod occ mb_parent loc
where
(us', us1) = splitUniqSupply (nsUniqs name_supply)
uniq = uniqFromSupply us1
- name = mkExternalName uniq mod occ mb_parent loc
- new_cache = extend_name_cache (nsNames name_supply) mod occ name
+ name = mkExternalName uniq mod occ loc
+ new_cache = extendNameCache (nsNames name_supply) mod occ name
new_name_supply = name_supply {nsUniqs = us', nsNames = new_cache}
@@ -119,67 +119,34 @@ newImplicitBinder :: Name -- Base name
-- Called in BuildTyCl to allocate the implicit binders of type/class decls
-- For source type/class decls, this is the first occurrence
-- For iface ones, the LoadIface has alrady allocated a suitable name in the cache
---
--- An *implicit* name has the base-name as parent
newImplicitBinder base_name mk_sys_occ
= newGlobalBinder (nameModule base_name)
(mk_sys_occ (nameOccName base_name))
- (Just parent_name)
(nameSrcLoc base_name)
- where
- parent_name = case nameParent_maybe base_name of
- Just parent_name -> parent_name
- Nothing -> base_name
-ifaceExportNames :: [IfaceExport] -> TcRnIf gbl lcl NameSet
-ifaceExportNames exports
- = foldlM do_one emptyNameSet exports
- where
- do_one acc (mod, exports) = foldlM (do_avail mod) acc exports
- do_avail mod acc avail = do { ns <- lookupAvail mod avail
- ; return (addListToNameSet acc ns) }
-
-lookupAvail :: Module -> GenAvailInfo OccName -> TcRnIf a b [Name]
--- Find all the names arising from an import
--- Make sure the parent info is correct, even though we may not
--- yet have read the interface for this module
-lookupAvail mod (Avail n) = do { n' <- lookupOrig mod n;
- ; return [n'] }
-lookupAvail mod (AvailTC p_occ occs)
- = do { p_name <- lookupOrig mod p_occ
- ; let lookup_sub occ | occ == p_occ = return p_name
- | otherwise = lookup_orig mod occ (Just p_name)
- ; mappM lookup_sub occs }
+ifaceExportNames :: [IfaceExport] -> TcRnIf gbl lcl [AvailInfo]
+ifaceExportNames exports = do
+ mod_avails <- mapM (\(mod,avails) -> mapM (lookupAvail mod) avails) exports
+ return (concat mod_avails)
+
+-- Convert OccNames in GenAvailInfo to Names.
+lookupAvail :: Module -> GenAvailInfo OccName -> TcRnIf a b AvailInfo
+lookupAvail mod (Avail n) = do
+ n' <- lookupOrig mod n
+ return (Avail n')
+lookupAvail mod (AvailTC p_occ occs) = do
+ p_name <- lookupOrig mod p_occ
+ let lookup_sub occ | occ == p_occ = return p_name
+ | otherwise = lookupOrig mod occ
+ subs <- mappM lookup_sub occs
+ return (AvailTC p_name subs)
-- Remember that 'occs' is all the exported things, including
-- the parent. It's possible to export just class ops without
- -- the class, via C( op ). If the class was exported too we'd
- -- have C( C, op )
-
- -- The use of lookupOrigSub here (rather than lookupOrig)
- -- ensures that the subordinate names record their parent;
- -- and that in turn ensures that the GlobalRdrEnv
- -- has the correct parent for all the names in its range.
- -- For imported things, we may only suck in the interface later, if ever.
- -- Reason for all this:
- -- Suppose module M exports type A.T, and constructor A.MkT
- -- Then, we know that A.MkT is a subordinate name of A.T,
- -- even though we aren't at the binding site of A.T
- -- And it's important, because we may simply re-export A.T
- -- without ever sucking in the declaration itself.
-
-
-lookupOrig :: Module -> OccName -> TcRnIf a b Name
--- Even if we get a miss in the original-name cache, we
--- make a new External Name.
--- We fake up
--- SrcLoc to noSrcLoc
--- Parent no Nothing
--- They'll be overwritten, in due course, by LoadIface.loadDecl.
-lookupOrig mod occ = lookup_orig mod occ Nothing
-
-lookup_orig :: Module -> OccName -> Maybe Name -> TcRnIf a b Name
--- Used when we know the parent of the thing we are looking up
-lookup_orig mod occ mb_parent
+ -- the class, which shows up as C( op ) here. If the class was
+ -- exported too we'd have C( C, op )
+
+lookupOrig :: Module -> OccName -> TcRnIf a b Name
+lookupOrig mod occ
= do { -- First ensure that mod and occ are evaluated
-- If not, chaos can ensue:
-- we read the name-cache
@@ -187,21 +154,22 @@ lookup_orig mod occ mb_parent
-- which does some stuff that modifies the name cache
-- This did happen, with tycon_mod in TcIface.tcIfaceAlt (DataAlt..)
mod `seq` occ `seq` return ()
+ ; traceIf (text "lookup_orig" <+> ppr mod <+> ppr occ)
- ; name_supply <- getNameCache
- ; case lookupOrigNameCache (nsNames name_supply) mod occ of {
- Just name -> returnM name ;
- Nothing -> do
-
- { let { (us', us1) = splitUniqSupply (nsUniqs name_supply)
- ; uniq = uniqFromSupply us1
- ; name = mkExternalName uniq mod occ mb_parent noSrcLoc
- ; new_cache = extend_name_cache (nsNames name_supply) mod occ name
- ; new_name_supply = name_supply {nsUniqs = us', nsNames = new_cache}
- }
- ; setNameCache new_name_supply
- ; return name }
- }}
+ ; name_cache <- getNameCache
+ ; case lookupOrigNameCache (nsNames name_cache) mod occ of {
+ Just name -> returnM name;
+ Nothing ->
+ let
+ us = nsUniqs name_cache
+ uniq = uniqFromSupply us
+ name = mkExternalName uniq mod occ noSrcLoc
+ new_cache = extendNameCache (nsNames name_cache) mod occ name
+ in
+ case splitUniqSupply us of { (us',_) -> do
+ setNameCache name_cache{ nsUniqs = us', nsNames = new_cache }
+ return name
+ }}}
newIPName :: IPName OccName -> TcRnIf m n (IPName Name)
newIPName occ_name_ip
@@ -246,10 +214,10 @@ lookupOrigNameCache nc mod occ -- The normal case
extendOrigNameCache :: OrigNameCache -> Name -> OrigNameCache
extendOrigNameCache nc name
- = extend_name_cache nc (nameModule name) (nameOccName name) name
+ = extendNameCache nc (nameModule name) (nameOccName name) name
-extend_name_cache :: OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
-extend_name_cache nc mod occ name
+extendNameCache :: OrigNameCache -> Module -> OccName -> Name -> OrigNameCache
+extendNameCache nc mod occ name
= extendModuleEnv_C combine nc mod (unitOccEnv occ name)
where
combine occ_env _ = extendOccEnv occ_env occ name
@@ -324,16 +292,6 @@ extendIfaceTyVarEnv tyvars thing_inside
%************************************************************************
\begin{code}
-lookupIfaceTc :: IfaceTyCon -> IfL Name
-lookupIfaceTc (IfaceTc ext) = lookupIfaceExt ext
-lookupIfaceTc other_tc = return (ifaceTyConName other_tc)
-
-lookupIfaceExt :: IfaceExtName -> IfL Name
-lookupIfaceExt (ExtPkg mod occ) = lookupOrig mod occ
-lookupIfaceExt (HomePkg mod occ _) = lookupHomePackage mod occ
-lookupIfaceExt (LocalTop occ) = lookupIfaceTop occ
-lookupIfaceExt (LocalTopSub occ _) = lookupIfaceTop occ
-
lookupIfaceTop :: OccName -> IfL Name
-- Look up a top-level name from the current Iface module
lookupIfaceTop occ
diff --git a/compiler/iface/IfaceSyn.lhs b/compiler/iface/IfaceSyn.lhs
index 8ac4eecc87..a8426081a8 100644
--- a/compiler/iface/IfaceSyn.lhs
+++ b/compiler/iface/IfaceSyn.lhs
@@ -20,14 +20,14 @@ module IfaceSyn (
IfaceInfoItem(..), IfaceRule(..), IfaceInst(..), IfaceFamInst(..),
-- Misc
- visibleIfConDecls,
+ ifaceDeclSubBndrs, visibleIfConDecls,
-- Equality
- IfaceEq(..), (&&&), bool, eqListBy, eqMaybeBy,
+ GenIfaceEq(..), IfaceEq, (&&&), bool, eqListBy, eqMaybeBy,
eqIfDecl, eqIfInst, eqIfRule, checkBootDecl,
-- Pretty printing
- pprIfaceExpr, pprIfaceDecl, pprIfaceDeclHead
+ pprIfaceExpr, pprIfaceDeclHead
) where
#include "HsVersions.h"
@@ -37,16 +37,23 @@ import IfaceType
import NewDemand ( StrictSig, pprIfaceStrictSig )
import Class ( FunDep, DefMeth, pprFundeps )
-import OccName ( OccName, parenSymOcc, occNameFS,
- OccSet, unionOccSets, unitOccSet, occSetElts )
+import OccName
import UniqFM ( UniqFM, emptyUFM, addToUFM, lookupUFM )
+import Unique ( mkBuiltinUnique )
+import NameSet
+import Name ( Name, NamedThing(..), isExternalName,
+ mkInternalName )
import CostCentre ( CostCentre, pprCostCentreCore )
import Literal ( Literal )
import ForeignCall ( ForeignCall )
-import BasicTypes ( Arity, Activation(..), StrictnessMark, OverlapFlag,
- RecFlag(..), Boxity(..), tupleParens )
+import SrcLoc ( noSrcLoc )
+import BasicTypes
import Outputable
import FastString
+import Maybes ( catMaybes )
+
+import Data.List ( nub )
+import Data.Maybe ( isJust )
infixl 3 &&&
infix 4 `eqIfExt`, `eqIfIdInfo`, `eqIfType`
@@ -101,7 +108,8 @@ data IfaceDecl
ifRec :: RecFlag -- Is newtype/datatype associated with the class recursive?
}
- | IfaceForeign { ifName :: OccName, -- Needs expanding when we move beyond .NET
+ | IfaceForeign { ifName :: OccName, -- Needs expanding when we move
+ -- beyond .NET
ifExtName :: Maybe FastString }
data IfaceClassOp = IfaceClassOp OccName DefMeth IfaceType
@@ -125,7 +133,7 @@ visibleIfConDecls (IfNewTyCon c) = [c]
data IfaceConDecl
= IfCon {
- ifConOcc :: OccName, -- Constructor name
+ ifConOcc :: OccName, -- Constructor name
ifConInfix :: Bool, -- True <=> declared infix
ifConUnivTvs :: [IfaceTvBndr], -- Universal tyvars
ifConExTvs :: [IfaceTvBndr], -- Existential tyvars
@@ -137,9 +145,9 @@ data IfaceConDecl
-- or 1-1 corresp with arg tys
data IfaceInst
- = IfaceInst { ifInstCls :: IfaceExtName, -- See comments with
+ = IfaceInst { ifInstCls :: Name, -- See comments with
ifInstTys :: [Maybe IfaceTyCon], -- the defn of Instance
- ifDFun :: OccName, -- The dfun
+ ifDFun :: Name, -- The dfun
ifOFlag :: OverlapFlag, -- Overlap flag
ifInstOrph :: Maybe OccName } -- See is_orph in defn of Instance
-- There's always a separate IfaceDecl for the DFun, which gives
@@ -150,7 +158,7 @@ data IfaceInst
-- and if the head does not change it won't be used if it wasn't before
data IfaceFamInst
- = IfaceFamInst { ifFamInstFam :: IfaceExtName -- Family tycon
+ = IfaceFamInst { ifFamInstFam :: Name -- Family tycon
, ifFamInstTys :: [Maybe IfaceTyCon] -- Rough match types
, ifFamInstTyCon :: IfaceTyCon -- Instance decl
}
@@ -160,7 +168,7 @@ data IfaceRule
ifRuleName :: RuleName,
ifActivation :: Activation,
ifRuleBndrs :: [IfaceBndr], -- Tyvars and term vars
- ifRuleHead :: IfaceExtName, -- Head of lhs
+ ifRuleHead :: Name, -- Head of lhs
ifRuleArgs :: [IfaceExpr], -- Args of LHS
ifRuleRhs :: IfaceExpr,
ifRuleOrph :: Maybe OccName -- Just like IfaceInst
@@ -186,7 +194,7 @@ data IfaceInfoItem
| HsInline Activation
| HsUnfold IfaceExpr
| HsNoCafRefs
- | HsWorker IfaceExtName Arity -- Worker, if any see IdInfo.WorkerInfo
+ | HsWorker Name Arity -- Worker, if any see IdInfo.WorkerInfo
-- for why we want arity here.
-- NB: we need IfaceExtName (not just OccName) because the worker
-- can simplify to a function in another module.
@@ -196,7 +204,7 @@ data IfaceInfoItem
--------------------------------
data IfaceExpr
= IfaceLcl FastString
- | IfaceExt IfaceExtName
+ | IfaceExt Name
| IfaceType IfaceType
| IfaceTuple Boxity [IfaceExpr] -- Saturated; type arguments omitted
| IfaceLam IfaceBndr IfaceExpr
@@ -218,25 +226,80 @@ type IfaceAlt = (IfaceConAlt, [FastString], IfaceExpr)
-- thus saving bulk in interface files
data IfaceConAlt = IfaceDefault
- | IfaceDataAlt OccName
+ | IfaceDataAlt Name
| IfaceTupleAlt Boxity
| IfaceLitAlt Literal
data IfaceBinding
= IfaceNonRec IfaceIdBndr IfaceExpr
| IfaceRec [(IfaceIdBndr, IfaceExpr)]
-\end{code}
-
-
-%************************************************************************
-%* *
-\subsection[HsCore-print]{Printing Core unfoldings}
-%* *
-%************************************************************************
------------------------------ Printing IfaceDecl ------------------------------------
+-- -----------------------------------------------------------------------------
+-- Utils on IfaceSyn
+
+ifaceDeclSubBndrs :: IfaceDecl -> [OccName]
+-- *Excludes* the 'main' name, but *includes* the implicitly-bound names
+-- Deeply revolting, because it has to predict what gets bound,
+-- especially the question of whether there's a wrapper for a datacon
+
+ifaceDeclSubBndrs (IfaceClass {ifCtxt = sc_ctxt, ifName = cls_occ,
+ ifSigs = sigs, ifATs = ats })
+ = co_occs ++
+ [tc_occ, dc_occ, dcww_occ] ++
+ [op | IfaceClassOp op _ _ <- sigs] ++
+ [ifName at | at <- ats ] ++
+ [mkSuperDictSelOcc n cls_occ | n <- [1..n_ctxt]]
+ where
+ n_ctxt = length sc_ctxt
+ n_sigs = length sigs
+ tc_occ = mkClassTyConOcc cls_occ
+ dc_occ = mkClassDataConOcc cls_occ
+ co_occs | is_newtype = [mkNewTyCoOcc tc_occ]
+ | otherwise = []
+ dcww_occ -- | is_newtype = mkDataConWrapperOcc dc_occ -- Newtypes have wrapper but no worker
+ | otherwise = mkDataConWorkerOcc dc_occ -- Otherwise worker but no wrapper
+ is_newtype = n_sigs + n_ctxt == 1 -- Sigh
+
+ifaceDeclSubBndrs IfaceData {ifCons = IfAbstractTyCon}
+ = []
+-- Newtype
+ifaceDeclSubBndrs (IfaceData {ifName = tc_occ,
+ ifCons = IfNewTyCon (
+ IfCon { ifConOcc = con_occ,
+ ifConFields = fields
+ }),
+ ifFamInst = famInst})
+ = fields ++ [con_occ, mkDataConWorkerOcc con_occ, mkNewTyCoOcc tc_occ]
+ ++ famInstCo famInst tc_occ
+
+ifaceDeclSubBndrs (IfaceData {ifName = tc_occ,
+ ifCons = IfDataTyCon cons,
+ ifFamInst = famInst})
+ = nub (concatMap ifConFields cons) -- Eliminate duplicate fields
+ ++ concatMap dc_occs cons
+ ++ famInstCo famInst tc_occ
+ where
+ dc_occs con_decl
+ | has_wrapper = [con_occ, work_occ, wrap_occ]
+ | otherwise = [con_occ, work_occ]
+ where
+ con_occ = ifConOcc con_decl
+ strs = ifConStricts con_decl
+ wrap_occ = mkDataConWrapperOcc con_occ
+ work_occ = mkDataConWorkerOcc con_occ
+ has_wrapper = any isMarkedStrict strs -- See MkId.mkDataConIds (sigh)
+ || not (null . ifConEqSpec $ con_decl)
+ || isJust famInst
+ -- ToDo: may miss strictness in existential dicts
+
+ifaceDeclSubBndrs _other = []
+
+-- coercion for data/newtype family instances
+famInstCo Nothing baseOcc = []
+famInstCo (Just _) baseOcc = [mkInstTyCoOcc baseOcc]
+
+----------------------------- Printing IfaceDecl ------------------------------
-\begin{code}
instance Outputable IfaceDecl where
ppr = pprIfaceDecl
@@ -319,9 +382,10 @@ pprIfaceConDecl tc
eq_ctxt = [(IfaceEqPred (IfaceTyVar (occNameFS tv)) ty)
| (tv,ty) <- eq_spec]
con_tau = foldr1 IfaceFunTy (arg_tys ++ [tc_app])
- tc_app = IfaceTyConApp (IfaceTc (LocalTop tc))
+ tc_app = IfaceTyConApp (IfaceTc tc_name)
[IfaceTyVar tv | (tv,_) <- univ_tvs]
- -- Gruesome, but just for debug print
+ tc_name = mkInternalName (mkBuiltinUnique 1) tc noSrcLoc
+ -- Really Gruesome, but just for debug print
instance Outputable IfaceRule where
ppr (IfaceRule { ifRuleName = name, ifActivation = act, ifRuleBndrs = bndrs,
@@ -457,23 +521,25 @@ ppr_hs_info (HsWorker w a) = ptext SLIT("Worker:") <+> ppr w <+> int a
%* *
%************************************************************************
-Equality over IfaceSyn returns an IfaceEq, not a Bool. The new constructor is
-EqBut, which gives the set of *locally-defined* things whose version must be equal
-for the whole thing to be equal. So the key function is eqIfExt, which compares
-IfaceExtNames.
+Equality over IfaceSyn returns an IfaceEq, not a Bool. The new
+constructor is EqBut, which gives the set of things whose version must
+be equal for the whole thing to be equal. So the key function is
+eqIfExt, which compares Names.
Of course, equality is also done modulo alpha conversion.
\begin{code}
-data IfaceEq
+data GenIfaceEq a
= Equal -- Definitely exactly the same
| NotEqual -- Definitely different
- | EqBut OccSet -- The same provided these local things have not changed
+ | EqBut a -- The same provided these Names have not changed
+
+type IfaceEq = GenIfaceEq NameSet
instance Outputable IfaceEq where
ppr Equal = ptext SLIT("Equal")
ppr NotEqual = ptext SLIT("NotEqual")
- ppr (EqBut occset) = ptext SLIT("EqBut") <+> ppr (occSetElts occset)
+ ppr (EqBut occset) = ptext SLIT("EqBut") <+> ppr (nameSetToList occset)
bool :: Bool -> IfaceEq
bool True = Equal
@@ -491,23 +557,18 @@ zapEq other = other
(&&&) :: IfaceEq -> IfaceEq -> IfaceEq
Equal &&& x = x
NotEqual &&& x = NotEqual
-EqBut occs &&& Equal = EqBut occs
-EqBut occs &&& NotEqual = NotEqual
-EqBut occs1 &&& EqBut occs2 = EqBut (occs1 `unionOccSets` occs2)
+EqBut nms &&& Equal = EqBut nms
+EqBut nms &&& NotEqual = NotEqual
+EqBut nms1 &&& EqBut nms2 = EqBut (nms1 `unionNameSets` nms2)
----------------------
-eqIfExt :: IfaceExtName -> IfaceExtName -> IfaceEq
-- This function is the core of the EqBut stuff
-eqIfExt (ExtPkg mod1 occ1) (ExtPkg mod2 occ2) = bool (mod1==mod2 && occ1==occ2)
-eqIfExt (HomePkg mod1 occ1 v1) (HomePkg mod2 occ2 v2) = bool (mod1==mod2 && occ1==occ2 && v1==v2)
-eqIfExt (LocalTop occ1) (LocalTop occ2) | occ1 == occ2 = EqBut (unitOccSet occ1)
-eqIfExt (LocalTopSub occ1 p1) (LocalTop occ2) | occ1 == occ2 = EqBut (unitOccSet p1)
-eqIfExt (LocalTopSub occ1 p1) (LocalTopSub occ2 _) | occ1 == occ2 = EqBut (unitOccSet p1)
-eqIfExt n1 n2 = NotEqual
-\end{code}
+-- ASSUMPTION: The left-hand argument is the NEW CODE, and hence
+-- any Names in the left-hand arg have the correct parent in them.
+eqIfExt :: Name -> Name -> IfaceEq
+eqIfExt name1 name2
+ | name1 == name2 = EqBut (unitNameSet name1)
+ | otherwise = NotEqual
-
-\begin{code}
---------------------
checkBootDecl :: IfaceDecl -- The boot decl
-> IfaceDecl -- The real decl
diff --git a/compiler/iface/IfaceType.lhs b/compiler/iface/IfaceType.lhs
index ee37891aa7..64d88927f6 100644
--- a/compiler/iface/IfaceType.lhs
+++ b/compiler/iface/IfaceType.lhs
@@ -8,9 +8,7 @@
module IfaceType (
IfaceType(..), IfaceKind, IfacePredType(..), IfaceTyCon(..),
IfaceContext, IfaceBndr(..), IfaceTvBndr, IfaceIdBndr, IfaceCoercion,
-
- IfaceExtName(..), mkIfaceExtName, isLocalIfaceExtName,
- ifaceTyConName, ifaceTyConOccName,
+ ifaceTyConName,
-- Conversion from Type -> IfaceType
toIfaceType, toIfacePred, toIfaceContext,
@@ -42,50 +40,6 @@ import Outputable
import FastString
\end{code}
-
-%************************************************************************
-%* *
- IfaceExtName
-%* *
-%************************************************************************
-
-\begin{code}
-data IfaceExtName
- = ExtPkg Module OccName
- -- From an external package; no version # Also used for
- -- wired-in things regardless of whether they are home-pkg or
- -- not
-
- | HomePkg ModuleName OccName Version
- -- From another module in home package; has version #; in all
- -- other respects, HomePkg and ExtPkg are the same. Since this
- -- is a home package name, we use ModuleName rather than Module
-
- | LocalTop OccName -- Top-level from the same module as
- -- the enclosing IfaceDecl
-
- | LocalTopSub -- Same as LocalTop, but for a class method or constr
- OccName -- Class-meth/constr name
- OccName -- Parent class/datatype name
- -- LocalTopSub is written into iface files as LocalTop; the parent
- -- info is only used when computing version information in MkIface
-
-isLocalIfaceExtName :: IfaceExtName -> Bool
-isLocalIfaceExtName (LocalTop _) = True
-isLocalIfaceExtName (LocalTopSub _ _) = True
-isLocalIfaceExtName other = False
-
-mkIfaceExtName name = ExtPkg (nameModule name) (nameOccName name)
- -- Local helper for wired-in names
-
-ifaceExtOcc :: IfaceExtName -> OccName
-ifaceExtOcc (ExtPkg _ occ) = occ
-ifaceExtOcc (HomePkg _ occ _) = occ
-ifaceExtOcc (LocalTop occ) = occ
-ifaceExtOcc (LocalTopSub occ _) = occ
-\end{code}
-
-
%************************************************************************
%* *
Local (nested) binders
@@ -115,7 +69,7 @@ data IfaceType
| IfaceFunTy IfaceType IfaceType
data IfacePredType -- NewTypes are handled as ordinary TyConApps
- = IfaceClassP IfaceExtName [IfaceType]
+ = IfaceClassP Name [IfaceType]
| IfaceIParam (IPName OccName) IfaceType
| IfaceEqPred IfaceType IfaceType
@@ -124,14 +78,14 @@ type IfaceContext = [IfacePredType]
-- NB: If you add a data constructor, remember to add a case to
-- IfaceSyn.eqIfTc!
data IfaceTyCon -- Abbreviations for common tycons with known names
- = IfaceTc IfaceExtName -- The common case
+ = IfaceTc Name -- The common case
| IfaceIntTc | IfaceBoolTc | IfaceCharTc
| IfaceListTc | IfacePArrTc
| IfaceTupTc Boxity Arity
| IfaceLiftedTypeKindTc | IfaceOpenTypeKindTc | IfaceUnliftedTypeKindTc
| IfaceUbxTupleKindTc | IfaceArgTypeKindTc
-ifaceTyConName :: IfaceTyCon -> Name -- Works for all except IfaceTc
+ifaceTyConName :: IfaceTyCon -> Name
ifaceTyConName IfaceIntTc = intTyConName
ifaceTyConName IfaceBoolTc = boolTyConName
ifaceTyConName IfaceCharTc = charTyConName
@@ -143,11 +97,7 @@ ifaceTyConName IfaceOpenTypeKindTc = openTypeKindTyConName
ifaceTyConName IfaceUnliftedTypeKindTc = unliftedTypeKindTyConName
ifaceTyConName IfaceUbxTupleKindTc = ubxTupleKindTyConName
ifaceTyConName IfaceArgTypeKindTc = argTypeKindTyConName
-ifaceTyConName (IfaceTc ext) = pprPanic "ifaceTyConName" (ppr ext)
-
-ifaceTyConOccName :: IfaceTyCon -> OccName -- Works for all!
-ifaceTyConOccName (IfaceTc ext) = ifaceExtOcc ext
-ifaceTyConOccName tycon = nameOccName . ifaceTyConName $ tycon
+ifaceTyConName (IfaceTc ext) = ext
\end{code}
@@ -209,16 +159,6 @@ maybeParen ctxt_prec inner_prec pretty
----------------------------- Printing binders ------------------------------------
\begin{code}
--- These instances are used only when printing for the user, either when
--- debugging, or in GHCi when printing the results of a :info command
-instance Outputable IfaceExtName where
- ppr (ExtPkg mod occ) = ppr mod <> dot <> ppr occ
- ppr (HomePkg mod occ vers) = ppr mod <> dot <> ppr occ <> braces (ppr vers)
- ppr (LocalTop occ) = ppr occ -- Do we want to distinguish these
- ppr (LocalTopSub occ _) = ppr occ -- from an ordinary occurrence?
--- No need to worry about printing unqualified becuase that was handled
--- in the transiation to IfaceSyn
-
instance Outputable IfaceBndr where
ppr (IfaceIdBndr bndr) = pprIfaceIdBndr bndr
ppr (IfaceTvBndr bndr) = char '@' <+> pprIfaceTvBndr bndr
@@ -301,7 +241,7 @@ ppr_tc_app ctxt_prec tc tys
ppr_tc :: IfaceTyCon -> SDoc
-- Wrap infix type constructors in parens
-ppr_tc tc@(IfaceTc ext_nm) = parenSymOcc (ifaceExtOcc ext_nm) (ppr tc)
+ppr_tc tc@(IfaceTc ext_nm) = parenSymOcc (getOccName ext_nm) (ppr tc)
ppr_tc tc = ppr tc
-------------------
@@ -309,7 +249,7 @@ instance Outputable IfacePredType where
-- Print without parens
ppr (IfaceEqPred ty1 ty2)= hsep [ppr ty1, ptext SLIT(":=:"), ppr ty2]
ppr (IfaceIParam ip ty) = hsep [ppr ip, dcolon, ppr ty]
- ppr (IfaceClassP cls ts) = parenSymOcc (ifaceExtOcc cls) (ppr cls)
+ ppr (IfaceClassP cls ts) = parenSymOcc (getOccName cls) (ppr cls)
<+> sep (map pprParendIfaceType ts)
instance Outputable IfaceTyCon where
@@ -338,26 +278,32 @@ pabrackets p = ptext SLIT("[:") <> p <> ptext SLIT(":]")
\begin{code}
----------------
toIfaceTvBndr tyvar = (occNameFS (getOccName tyvar), toIfaceKind (tyVarKind tyvar))
-toIfaceIdBndr ext id = (occNameFS (getOccName id), toIfaceType ext (idType id))
+toIfaceIdBndr id = (occNameFS (getOccName id), toIfaceType (idType id))
toIfaceTvBndrs tyvars = map toIfaceTvBndr tyvars
-toIfaceBndr ext var
- | isId var = IfaceIdBndr (toIfaceIdBndr ext var)
+toIfaceBndr var
+ | isId var = IfaceIdBndr (toIfaceIdBndr var)
| otherwise = IfaceTvBndr (toIfaceTvBndr var)
--- we had better not have to use ext for kinds
-toIfaceKind = toIfaceType (\name -> pprPanic "toIfaceKind ext used on:" (ppr name))
+toIfaceKind = toIfaceType
---------------------
-toIfaceType :: (Name -> IfaceExtName) -> Type -> IfaceType
+toIfaceType :: Type -> IfaceType
-- Synonyms are retained in the interface type
-toIfaceType ext (TyVarTy tv) = IfaceTyVar (occNameFS (getOccName tv))
-toIfaceType ext (AppTy t1 t2) = IfaceAppTy (toIfaceType ext t1) (toIfaceType ext t2)
-toIfaceType ext (FunTy t1 t2) = IfaceFunTy (toIfaceType ext t1) (toIfaceType ext t2)
-toIfaceType ext (TyConApp tc tys) = IfaceTyConApp (toIfaceTyCon ext tc) (toIfaceTypes ext tys)
-toIfaceType ext (ForAllTy tv t) = IfaceForAllTy (toIfaceTvBndr tv) (toIfaceType ext t)
-toIfaceType ext (PredTy st) = IfacePredTy (toIfacePred ext st)
-toIfaceType ext (NoteTy other_note ty) = toIfaceType ext ty
+toIfaceType (TyVarTy tv) =
+ IfaceTyVar (occNameFS (getOccName tv))
+toIfaceType (AppTy t1 t2) =
+ IfaceAppTy (toIfaceType t1) (toIfaceType t2)
+toIfaceType (FunTy t1 t2) =
+ IfaceFunTy (toIfaceType t1) (toIfaceType t2)
+toIfaceType (TyConApp tc tys) =
+ IfaceTyConApp (toIfaceTyCon tc) (toIfaceTypes tys)
+toIfaceType (ForAllTy tv t) =
+ IfaceForAllTy (toIfaceTvBndr tv) (toIfaceType t)
+toIfaceType (PredTy st) =
+ IfacePredTy (toIfacePred st)
+toIfaceType (NoteTy other_note ty) =
+ toIfaceType ty
----------------
-- A little bit of (perhaps optional) trickiness here. When
@@ -367,20 +313,20 @@ toIfaceType ext (NoteTy other_note ty) = toIfaceType ext ty
-- Hence a tuple tycon may 'miss' in toIfaceTyCon, but then
-- toIfaceTyCon_name will still catch it.
-toIfaceTyCon :: (Name -> IfaceExtName) -> TyCon -> IfaceTyCon
-toIfaceTyCon ext tc
+toIfaceTyCon :: TyCon -> IfaceTyCon
+toIfaceTyCon tc
| isTupleTyCon tc = IfaceTupTc (tupleTyConBoxity tc) (tyConArity tc)
- | otherwise = toIfaceTyCon_name ext (tyConName tc)
+ | otherwise = toIfaceTyCon_name (tyConName tc)
-toIfaceTyCon_name :: (Name -> IfaceExtName) -> Name -> IfaceTyCon
-toIfaceTyCon_name ext nm
+toIfaceTyCon_name :: Name -> IfaceTyCon
+toIfaceTyCon_name nm
| Just (ATyCon tc) <- wiredInNameTyThing_maybe nm
- = toIfaceWiredInTyCon ext tc nm
+ = toIfaceWiredInTyCon tc nm
| otherwise
- = IfaceTc (ext nm)
+ = IfaceTc nm
-toIfaceWiredInTyCon :: (Name -> IfaceExtName) -> TyCon -> Name -> IfaceTyCon
-toIfaceWiredInTyCon ext tc nm
+toIfaceWiredInTyCon :: TyCon -> Name -> IfaceTyCon
+toIfaceWiredInTyCon tc nm
| isTupleTyCon tc = IfaceTupTc (tupleTyConBoxity tc) (tyConArity tc)
| nm == intTyConName = IfaceIntTc
| nm == boolTyConName = IfaceBoolTc
@@ -392,18 +338,21 @@ toIfaceWiredInTyCon ext tc nm
| nm == openTypeKindTyConName = IfaceOpenTypeKindTc
| nm == argTypeKindTyConName = IfaceArgTypeKindTc
| nm == ubxTupleKindTyConName = IfaceUbxTupleKindTc
- | otherwise = IfaceTc (ext nm)
+ | otherwise = IfaceTc nm
----------------
-toIfaceTypes ext ts = map (toIfaceType ext) ts
+toIfaceTypes ts = map toIfaceType ts
----------------
-toIfacePred ext (ClassP cls ts) = IfaceClassP (ext (getName cls)) (toIfaceTypes ext ts)
-toIfacePred ext (IParam ip t) = IfaceIParam (mapIPName getOccName ip) (toIfaceType ext t)
-toIfacePred ext (EqPred ty1 ty2) = IfaceEqPred (toIfaceType ext ty1) (toIfaceType ext ty2)
+toIfacePred (ClassP cls ts) =
+ IfaceClassP (getName cls) (toIfaceTypes ts)
+toIfacePred (IParam ip t) =
+ IfaceIParam (mapIPName getOccName ip) (toIfaceType t)
+toIfacePred (EqPred ty1 ty2) =
+ IfaceEqPred (toIfaceType ty1) (toIfaceType ty2)
----------------
-toIfaceContext :: (Name -> IfaceExtName) -> ThetaType -> IfaceContext
-toIfaceContext ext cs = map (toIfacePred ext) cs
+toIfaceContext :: ThetaType -> IfaceContext
+toIfaceContext cs = map toIfacePred cs
\end{code}
diff --git a/compiler/iface/LoadIface.lhs b/compiler/iface/LoadIface.lhs
index e322276dea..5b19c894fa 100644
--- a/compiler/iface/LoadIface.lhs
+++ b/compiler/iface/LoadIface.lhs
@@ -11,7 +11,7 @@ module LoadIface (
loadDecls, -- Should move to TcIface and be renamed
initExternalPackageState,
- ifaceStats, pprModIface, showIface -- Print the iface in Foo.hi
+ ifaceStats, pprModIface, showIface
) where
#include "HsVersions.h"
@@ -20,9 +20,8 @@ import {-# SOURCE #-} TcIface( tcIfaceDecl, tcIfaceRules, tcIfaceInst,
tcIfaceFamInst )
import DynFlags ( DynFlags(..), DynFlag( Opt_IgnoreInterfacePragmas ) )
-import IfaceSyn ( IfaceDecl(..), IfaceConDecl(..), IfaceClassOp(..),
- IfaceConDecls(..), IfaceFamInst(..) )
-import IfaceEnv ( newGlobalBinder, lookupIfaceTc )
+import IfaceSyn
+import IfaceEnv ( newGlobalBinder )
import HscTypes ( ModIface(..), TyThing, IfaceExport, Usage(..),
Deprecs(..), Dependencies(..),
emptyModIface, EpsStats(..), GenAvailInfo(..),
@@ -62,8 +61,8 @@ import UniqFM
import StaticFlags ( opt_HiVersion )
import Outputable
import BinIface ( readBinIface, v_IgnoreHiWay )
-import Binary ( getBinFileWithDict )
-import Panic ( ghcError, tryMost, showException, GhcException(..) )
+import Binary
+import Panic ( ghcError, showException, GhcException(..) )
import List ( nub )
import Maybe ( isJust )
import DATA_IOREF ( writeIORef )
@@ -306,12 +305,9 @@ loadDecl :: Bool -- Don't load pragmas into the decl pool
loadDecl ignore_prags mod (_version, decl)
= do { -- Populate the name cache with final versions of all
-- the names associated with the decl
- main_name <- mk_new_bndr mod Nothing (ifName decl)
- ; parent_name <- case ifFamily decl of -- make family the parent
- Just famTyCon -> lookupIfaceTc famTyCon
- _ -> return main_name
- ; implicit_names <- mapM (mk_new_bndr mod (Just parent_name))
- (ifaceDeclSubBndrs decl)
+ main_name <- mk_new_bndr mod (ifName decl)
+ ; traceIf (text "Loading decl for " <> ppr main_name)
+ ; implicit_names <- mapM (mk_new_bndr mod) (ifaceDeclSubBndrs decl)
-- Typecheck the thing, lazily
-- NB. Firstly, the laziness is there in case we never need the
@@ -341,8 +337,8 @@ loadDecl ignore_prags mod (_version, decl)
-- * parent
-- * location
-- imported name, to fix the module correctly in the cache
- mk_new_bndr mod mb_parent occ
- = newGlobalBinder mod occ mb_parent
+ mk_new_bndr mod occ
+ = newGlobalBinder mod occ
(importedSrcLoc (showSDoc (ppr (moduleName mod))))
-- ToDo: qualify with the package name if necessary
@@ -357,70 +353,6 @@ bumpDeclStats name
; updateEps_ (\eps -> let stats = eps_stats eps
in eps { eps_stats = stats { n_decls_out = n_decls_out stats + 1 } })
}
-
------------------
-ifaceDeclSubBndrs :: IfaceDecl -> [OccName]
--- *Excludes* the 'main' name, but *includes* the implicitly-bound names
--- Deeply revolting, because it has to predict what gets bound,
--- especially the question of whether there's a wrapper for a datacon
---
--- If you change this, make sure you change HscTypes.implicitTyThings in sync
-
-ifaceDeclSubBndrs (IfaceClass {ifCtxt = sc_ctxt, ifName = cls_occ,
- ifSigs = sigs, ifATs = ats })
- = co_occs ++
- [tc_occ, dc_occ, dcww_occ] ++
- [op | IfaceClassOp op _ _ <- sigs] ++
- [ifName at | at <- ats ] ++
- [mkSuperDictSelOcc n cls_occ | n <- [1..n_ctxt]]
- where
- n_ctxt = length sc_ctxt
- n_sigs = length sigs
- tc_occ = mkClassTyConOcc cls_occ
- dc_occ = mkClassDataConOcc cls_occ
- co_occs | is_newtype = [mkNewTyCoOcc tc_occ]
- | otherwise = []
- dcww_occ -- | is_newtype = mkDataConWrapperOcc dc_occ -- Newtypes have wrapper but no worker
- | otherwise = mkDataConWorkerOcc dc_occ -- Otherwise worker but no wrapper
- is_newtype = n_sigs + n_ctxt == 1 -- Sigh
-
-ifaceDeclSubBndrs IfaceData {ifCons = IfAbstractTyCon}
- = []
--- Newtype
-ifaceDeclSubBndrs (IfaceData {ifName = tc_occ,
- ifCons = IfNewTyCon (
- IfCon { ifConOcc = con_occ,
- ifConFields = fields
- }),
- ifFamInst = famInst})
- = fields ++ [con_occ, mkDataConWorkerOcc con_occ, mkNewTyCoOcc tc_occ]
- ++ famInstCo famInst tc_occ
-
-ifaceDeclSubBndrs (IfaceData {ifName = tc_occ,
- ifCons = IfDataTyCon cons,
- ifFamInst = famInst})
- = nub (concatMap ifConFields cons) -- Eliminate duplicate fields
- ++ concatMap dc_occs cons
- ++ famInstCo famInst tc_occ
- where
- dc_occs con_decl
- | has_wrapper = [con_occ, work_occ, wrap_occ]
- | otherwise = [con_occ, work_occ]
- where
- con_occ = ifConOcc con_decl
- strs = ifConStricts con_decl
- wrap_occ = mkDataConWrapperOcc con_occ
- work_occ = mkDataConWorkerOcc con_occ
- has_wrapper = any isMarkedStrict strs -- See MkId.mkDataConIds (sigh)
- || not (null . ifConEqSpec $ con_decl)
- || isJust famInst
- -- ToDo: may miss strictness in existential dicts
-
-ifaceDeclSubBndrs _other = []
-
--- coercion for data/newtype family instances
-famInstCo Nothing baseOcc = []
-famInstCo (Just _) baseOcc = [mkInstTyCoOcc baseOcc]
\end{code}
@@ -504,8 +436,7 @@ readIface :: Module -> FilePath -> IsBootInterface
readIface wanted_mod file_path is_hi_boot_file
= do { dflags <- getDOpts
- ; ioToIOEnv $ do
- { res <- tryMost (readBinIface file_path)
+ ; res <- tryMostM $ readBinIface file_path
; case res of
Right iface
| wanted_mod == actual_mod -> return (Succeeded iface)
@@ -515,7 +446,7 @@ readIface wanted_mod file_path is_hi_boot_file
err = hiModuleNameMismatchWarn wanted_mod actual_mod
Left exn -> return (Failed (text (showException exn)))
- }}
+ }
\end{code}
@@ -594,18 +525,16 @@ ifaceStats eps
%************************************************************************
\begin{code}
-showIface :: FilePath -> IO ()
--- Read binary interface, and print it out
-showIface filename = do
+-- | Read binary interface, and print it out
+showIface :: HscEnv -> FilePath -> IO ()
+showIface hsc_env filename = do
-- skip the version check; we don't want to worry about profiled vs.
-- non-profiled interfaces, for example.
writeIORef v_IgnoreHiWay True
- iface <- Binary.getBinFileWithDict filename
+ iface <- initTcRnIf 's' hsc_env () () $ readBinIface filename
printDump (pprModIface iface)
- where
\end{code}
-
\begin{code}
pprModIface :: ModIface -> SDoc
-- Show a ModIface
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index 11235cef2e..e99e8bf038 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -176,8 +176,7 @@ compiled with -O. I think this is the case.]
#include "HsVersions.h"
import IfaceSyn -- All of it
-import IfaceType ( toIfaceTvBndrs, toIfaceType, toIfaceContext,
- ifaceTyConOccName )
+import IfaceType
import LoadIface ( readIface, loadInterface, pprModIface )
import Id ( Id, idName, idType, idInfo, idArity, isDataConWorkId_maybe, isFCallId_maybe )
import IdInfo ( IdInfo, CafInfo(..), WorkerInfo(..),
@@ -209,41 +208,43 @@ import HscTypes ( ModIface(..), ModDetails(..),
ModSummary(..), msHiFilePath,
mkIfaceDepCache, mkIfaceFixCache, mkIfaceVerCache,
typeEnvElts,
- GenAvailInfo(..), availName,
+ GenAvailInfo(..), availName, AvailInfo,
ExternalPackageState(..),
Usage(..), IsBootInterface,
Deprecs(..), IfaceDeprecs, Deprecations,
- lookupIfaceByModule
+ lookupIfaceByModule, isImplicitTyThing
)
import DynFlags ( GhcMode(..), DynFlags(..), DynFlag(..), dopt )
-import Name ( Name, nameModule, nameOccName, nameParent,
- isExternalName, isInternalName, nameParent_maybe, isWiredInName,
- isImplicitName, NamedThing(..) )
+import Name ( Name, nameModule, nameModule_maybe, nameOccName,
+ isExternalName, isInternalName, isWiredInName,
+ NamedThing(..) )
import NameEnv
import NameSet
import OccName ( OccName, OccEnv, mkOccEnv, lookupOccEnv, emptyOccEnv,
extendOccEnv_C,
OccSet, emptyOccSet, elemOccSet, occSetElts,
- extendOccSet, extendOccSetList,
+ extendOccSet, extendOccSetList, mkOccSet,
isEmptyOccSet, intersectOccSet, intersectsOccSet,
+ unionOccSets, unitOccSet,
occNameFS, isTcOcc )
import Module
-import Outputable
-import BasicTypes ( Version, initialVersion, bumpVersion, isAlwaysActive,
- Activation(..), RecFlag(..), boolToRecFlag )
-import Util ( createDirectoryHierarchy, directoryOf, sortLe, seqList, lengthIs )
-import BinIface ( writeBinIface )
+import BinIface ( readBinIface, writeBinIface, v_IgnoreHiWay )
import Unique ( Unique, Uniquable(..) )
import ErrUtils ( dumpIfSet_dyn, showPass )
import Digraph ( stronglyConnComp, SCC(..) )
import SrcLoc ( SrcSpan )
-import UniqFM
import PackageConfig ( PackageId )
+import Outputable
+import BasicTypes hiding ( SuccessFlag(..) )
+import UniqFM
+import Util hiding ( eqListBy )
import FiniteMap
import FastString
+import Data.List ( partition )
+import DATA_IOREF ( writeIORef )
import Monad ( when )
import List ( insert )
import Maybes ( orElse, mapCatMaybes, isNothing, isJust,
@@ -287,24 +288,20 @@ mkIface hsc_env maybe_old_iface
-- to expose in the interface
= do { eps <- hscEPS hsc_env
- ; let { ext_nm_rhs = mkExtNameFn hsc_env eps this_mod
- ; ext_nm_lhs = mkLhsNameFn this_mod
-
- ; decls = [ tyThingToIfaceDecl ext_nm_rhs thing
- | thing <- typeEnvElts type_env,
- let name = getName thing,
- not (isImplicitName name || isWiredInName name) ]
- -- Don't put implicit Ids and class tycons in the interface file
- -- Nor wired-in things; the compiler knows about them anyhow
-
- ; fixities = [ (occ,fix)
- | FixItem occ fix _ <- nameEnvElts fix_env]
- ; deprecs = mkIfaceDeprec src_deprecs
- ; iface_rules = map (coreRuleToIfaceRule
- ext_nm_lhs ext_nm_rhs) rules
- ; iface_insts = map (instanceToIfaceInst ext_nm_lhs) insts
- ; iface_fam_insts = map (famInstToIfaceFamInst ext_nm_lhs)
- fam_insts
+ ; let { entities = typeEnvElts type_env ;
+ decls = [ tyThingToIfaceDecl entity
+ | entity <- entities,
+ not (isImplicitTyThing entity
+ || isWiredInName (getName entity)) ]
+ -- Don't put implicit Ids and class tycons in
+ -- the interface file, Nor wired-in things; the
+ -- compiler knows about them anyhow
+
+ ; fixities = [(occ,fix) | FixItem occ fix _ <- nameEnvElts fix_env]
+ ; deprecs = mkIfaceDeprec src_deprecs
+ ; iface_rules = map coreRuleToIfaceRule rules
+ ; iface_insts = map instanceToIfaceInst insts
+ ; iface_fam_insts = map famInstToIfaceFamInst fam_insts
; intermediate_iface = ModIface {
mi_module = this_mod,
@@ -333,9 +330,11 @@ mkIface hsc_env maybe_old_iface
mi_fix_fn = mkIfaceFixCache fixities }
-- Add version information
+ ; ext_ver_fn = mkParentVerFun hsc_env eps
; (new_iface, no_change_at_all, pp_diffs, pp_orphs)
= _scc_ "versioninfo"
- addVersionInfo maybe_old_iface intermediate_iface decls
+ addVersionInfo ext_ver_fn maybe_old_iface
+ intermediate_iface decls
}
-- Debug printing
@@ -353,87 +352,61 @@ mkIface hsc_env maybe_old_iface
dflags = hsc_dflags hsc_env
deliberatelyOmitted x = panic ("Deliberately omitted: " ++ x)
- ifFamInstTyConOcc = ifaceTyConOccName . ifFamInstTyCon
+ ifFamInstTyConOcc = nameOccName . ifaceTyConName . ifFamInstTyCon
-----------------------------
-writeIfaceFile :: ModLocation -> ModIface -> IO ()
-writeIfaceFile location new_iface
+writeIfaceFile :: DynFlags -> ModLocation -> ModIface -> IO ()
+writeIfaceFile dflags location new_iface
= do createDirectoryHierarchy (directoryOf hi_file_path)
- writeBinIface hi_file_path new_iface
+ writeBinIface dflags hi_file_path new_iface
where hi_file_path = ml_hi_file location
------------------------------
-mkExtNameFn :: HscEnv -> ExternalPackageState -> Module -> Name -> IfaceExtName
-mkExtNameFn hsc_env eps this_mod
- = ext_nm
- where
- hpt = hsc_HPT hsc_env
- pit = eps_PIT eps
-
- ext_nm name
- | mod == this_mod = case nameParent_maybe name of
- Nothing -> LocalTop occ
- Just par -> LocalTopSub occ (nameOccName par)
- | isWiredInName name = ExtPkg mod occ
- | is_home mod = HomePkg mod_name occ vers
- | otherwise = ExtPkg mod occ
- where
- dflags = hsc_dflags hsc_env
- this_pkg = thisPackage dflags
- is_home mod = modulePackageId mod == this_pkg
-
- mod = nameModule name
- mod_name = moduleName mod
- occ = nameOccName name
- par_occ = nameOccName (nameParent name)
- -- The version of the *parent* is the one want
- vers = lookupVersion mod par_occ occ
-
- lookupVersion :: Module -> OccName -> OccName -> Version
- -- Even though we're looking up a home-package thing, in
- -- one-shot mode the imported interfaces may be in the PIT
- lookupVersion mod par_occ occ
- = mi_ver_fn iface par_occ `orElse`
- pprPanic "lookupVers1" (ppr mod <+> ppr par_occ <+> ppr occ)
- where
- iface = lookupIfaceByModule (hsc_dflags hsc_env) hpt pit mod `orElse`
- pprPanic "lookupVers2" (ppr mod <+> ppr par_occ <+> ppr occ)
+-- -----------------------------------------------------------------------------
+-- Look up parents and versions of Names
+-- This is like a global version of the mi_ver_fn field in each ModIface.
+-- Given a Name, it finds the ModIface, and then uses mi_ver_fn to get
+-- the parent and version info.
----------------------
--- mkLhsNameFn ignores versioning info altogether
--- It is used for the LHS of instance decls and rules, where we
--- there's no point in recording version info
-mkLhsNameFn :: Module -> Name -> IfaceExtName
-mkLhsNameFn this_mod name
- | isInternalName name = pprTrace "mkLhsNameFn: unexpected internal" (ppr name) $
- LocalTop occ -- Should not happen
- | mod == this_mod = LocalTop occ
- | otherwise = ExtPkg mod occ
+mkParentVerFun
+ :: HscEnv -- needed to look up versions
+ -> ExternalPackageState -- ditto
+ -> (Name -> (OccName,Version))
+mkParentVerFun hsc_env eps
+ = \name ->
+ let
+ mod = nameModule name
+ occ = nameOccName name
+ iface = lookupIfaceByModule (hsc_dflags hsc_env) hpt pit mod `orElse`
+ pprPanic "lookupVers2" (ppr mod <+> ppr occ)
+ in
+ mi_ver_fn iface occ `orElse`
+ pprPanic "lookupVers1" (ppr mod <+> ppr occ)
where
- mod = nameModule name
- occ = nameOccName name
-
+ hpt = hsc_HPT hsc_env
+ pit = eps_PIT eps
------------------------------
+-----------------------------------------------------------------------------
-- Compute version numbers for local decls
-addVersionInfo :: Maybe ModIface -- The old interface, read from M.hi
- -> ModIface -- The new interface decls (lacking decls)
- -> [IfaceDecl] -- The new decls
- -> (ModIface,
- Bool, -- True <=> no changes at all; no need to write new Iface
- SDoc, -- Differences
- Maybe SDoc) -- Warnings about orphans
-
-addVersionInfo Nothing new_iface new_decls
+addVersionInfo
+ :: (Name -> (OccName,Version)) -- lookup parents and versions of names
+ -> Maybe ModIface -- The old interface, read from M.hi
+ -> ModIface -- The new interface (lacking decls)
+ -> [IfaceDecl] -- The new decls
+ -> (ModIface, -- Updated interface
+ Bool, -- True <=> no changes at all; no need to write Iface
+ SDoc, -- Differences
+ Maybe SDoc) -- Warnings about orphans
+
+addVersionInfo ver_fn Nothing new_iface new_decls
-- No old interface, so definitely write a new one!
= (new_iface { mi_orphan = anyNothing ifInstOrph (mi_insts new_iface)
- || anyNothing ifRuleOrph (mi_rules new_iface),
- mi_decls = [(initialVersion, decl) | decl <- new_decls],
- mi_ver_fn = \n -> Just initialVersion },
+ || anyNothing ifRuleOrph (mi_rules new_iface),
+ mi_decls = [(initialVersion, decl) | decl <- new_decls],
+ mi_ver_fn = mkIfaceVerCache (zip (repeat initialVersion) new_decls)},
False,
ptext SLIT("No old interface file"),
pprOrphans orph_insts orph_rules)
@@ -441,7 +414,8 @@ addVersionInfo Nothing new_iface new_decls
orph_insts = filter (isNothing . ifInstOrph) (mi_insts new_iface)
orph_rules = filter (isNothing . ifRuleOrph) (mi_rules new_iface)
-addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
+addVersionInfo ver_fn (Just old_iface@(ModIface {
+ mi_mod_vers = old_mod_vers,
mi_exp_vers = old_exp_vers,
mi_rule_vers = old_rule_vers,
mi_decls = old_decls,
@@ -449,29 +423,35 @@ addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
mi_fix_fn = old_fixities }))
new_iface@(ModIface { mi_fix_fn = new_fixities })
new_decls
-
- | no_change_at_all = (old_iface, True, ptext SLIT("Interface file unchanged"), pp_orphs)
- | otherwise = (final_iface, False, vcat [ptext SLIT("Interface file has changed"),
- nest 2 pp_diffs], pp_orphs)
- where
- final_iface = new_iface { mi_mod_vers = bump_unless no_output_change old_mod_vers,
- mi_exp_vers = bump_unless no_export_change old_exp_vers,
- mi_rule_vers = bump_unless no_rule_change old_rule_vers,
- mi_orphan = not (null new_orph_rules && null new_orph_insts),
- mi_decls = decls_w_vers,
- mi_ver_fn = mkIfaceVerCache decls_w_vers }
+ | no_change_at_all
+ = (old_iface, True, ptext SLIT("Interface file unchanged"), pp_orphs)
+ | otherwise
+ = (final_iface, False, vcat [ptext SLIT("Interface file has changed"),
+ nest 2 pp_diffs], pp_orphs)
+ where
+ final_iface = new_iface {
+ mi_mod_vers = bump_unless no_output_change old_mod_vers,
+ mi_exp_vers = bump_unless no_export_change old_exp_vers,
+ mi_rule_vers = bump_unless no_rule_change old_rule_vers,
+ mi_orphan = not (null new_orph_rules && null new_orph_insts),
+ mi_decls = decls_w_vers,
+ mi_ver_fn = mkIfaceVerCache decls_w_vers }
decls_w_vers = [(add_vers decl, decl) | decl <- new_decls]
-------------------
- (old_non_orph_insts, old_orph_insts) = mkOrphMap ifInstOrph (mi_insts old_iface)
- (new_non_orph_insts, new_orph_insts) = mkOrphMap ifInstOrph (mi_insts new_iface)
+ (old_non_orph_insts, old_orph_insts) =
+ mkOrphMap ifInstOrph (mi_insts old_iface)
+ (new_non_orph_insts, new_orph_insts) =
+ mkOrphMap ifInstOrph (mi_insts new_iface)
same_insts occ = eqMaybeBy (eqListBy eqIfInst)
(lookupOccEnv old_non_orph_insts occ)
(lookupOccEnv new_non_orph_insts occ)
- (old_non_orph_rules, old_orph_rules) = mkOrphMap ifRuleOrph (mi_rules old_iface)
- (new_non_orph_rules, new_orph_rules) = mkOrphMap ifRuleOrph (mi_rules new_iface)
+ (old_non_orph_rules, old_orph_rules) =
+ mkOrphMap ifRuleOrph (mi_rules old_iface)
+ (new_non_orph_rules, new_orph_rules) =
+ mkOrphMap ifRuleOrph (mi_rules new_iface)
same_rules occ = eqMaybeBy (eqListBy eqIfRule)
(lookupOccEnv old_non_orph_rules occ)
(lookupOccEnv new_non_orph_rules occ)
@@ -479,10 +459,11 @@ addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
-- Computing what changed
no_output_change = no_decl_change && no_rule_change &&
no_export_change && no_deprec_change
- no_export_change = mi_exports new_iface == mi_exports old_iface -- Kept sorted
+ no_export_change = mi_exports new_iface == mi_exports old_iface
+ -- Kept sorted
no_decl_change = isEmptyOccSet changed_occs
- no_rule_change = not (changedWrt changed_occs (eqListBy eqIfRule old_orph_rules new_orph_rules)
- || changedWrt changed_occs (eqListBy eqIfInst old_orph_insts new_orph_insts))
+ no_rule_change = not (changedWrtNames changed_occs (eqListBy eqIfRule old_orph_rules new_orph_rules)
+ || changedWrtNames changed_occs (eqListBy eqIfInst old_orph_insts new_orph_insts))
no_deprec_change = mi_deprecs new_iface == mi_deprecs old_iface
-- If the usages havn't changed either, we don't need to write the interface file
@@ -506,28 +487,32 @@ addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
-------------------
-- Adding version info
- new_version = bumpVersion old_mod_vers -- Start from the old module version, not from zero
- -- so that if you remove f, and then add it again,
- -- you don't thereby reduce f's version number
+ new_version = bumpVersion old_mod_vers
+ -- Start from the old module version, not from
+ -- zero so that if you remove f, and then add
+ -- it again, you don't thereby reduce f's
+ -- version number
+
add_vers decl | occ `elemOccSet` changed_occs = new_version
- | otherwise = expectJust "add_vers" (old_decl_vers occ)
+ | otherwise = snd (expectJust "add_vers" (old_decl_vers occ))
-- If it's unchanged, there jolly well
where -- should be an old version number
occ = ifName decl
-------------------
- changed_occs :: OccSet
- changed_occs = computeChangedOccs eq_info
-
+ -- Deciding which declarations have changed
+
+ -- For each local decl, the IfaceEq gives the list of things that
+ -- must be unchanged for the declaration as a whole to be unchanged.
eq_info :: [(OccName, IfaceEq)]
eq_info = map check_eq new_decls
- check_eq new_decl | Just old_decl <- lookupOccEnv old_decl_env occ
- = (occ, new_decl `eqIfDecl` old_decl &&&
- eq_indirects new_decl)
- | otherwise {- No corresponding old decl -}
- = (occ, NotEqual)
- where
- occ = ifName new_decl
+ check_eq new_decl
+ | Just old_decl <- lookupOccEnv old_decl_env occ
+ = (occ, new_decl `eqIfDecl` old_decl &&& eq_indirects new_decl)
+ | otherwise {- No corresponding old decl -}
+ = (occ, NotEqual)
+ where
+ occ = ifName new_decl
eq_indirects :: IfaceDecl -> IfaceEq
-- When seeing if two decls are the same, remember to
@@ -544,7 +529,12 @@ addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
eq_ind_occ :: OccName -> IfaceEq -- For class ops and Ids; check fixity and rules
eq_ind_occ occ = same_fixity occ &&& same_rules occ
eq_ind_occs = foldr ((&&&) . eq_ind_occ) Equal
-
+
+ -- The Occs of declarations that changed.
+ changed_occs :: OccSet
+ changed_occs = computeChangedOccs ver_fn (mi_module new_iface)
+ (mi_usages old_iface) eq_info
+
-------------------
-- Diffs
pp_decl_diffs :: SDoc -- Nothing => no changes
@@ -564,9 +554,10 @@ addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
where
occ = ifName new_decl
why = case lookupOccEnv eq_env occ of
- Just (EqBut occs) -> sep [ppr occ <> colon, ptext SLIT("Free vars (only) changed:"),
+ Just (EqBut names) -> sep [ppr occ <> colon, ptext SLIT("Free vars (only) changed:"),
nest 2 (braces (fsep (map ppr (occSetElts
(occs `intersectOccSet` changed_occs)))))]
+ where occs = mkOccSet (map nameOccName (nameSetToList names))
Just NotEqual
| Just old_decl <- lookupOccEnv old_decl_env occ
-> vcat [ptext SLIT("Old:") <+> ppr old_decl,
@@ -577,6 +568,7 @@ addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
pp_orphs = pprOrphans new_orph_insts new_orph_rules
+
pprOrphans insts rules
| null insts && null rules = Nothing
| otherwise
@@ -589,32 +581,82 @@ pprOrphans insts rules
2 (vcat (map ppr rules))
]
-computeChangedOccs :: [(OccName, IfaceEq)] -> OccSet
-computeChangedOccs eq_info
+computeChangedOccs
+ :: (Name -> (OccName,Version)) -- get parents and versions
+ -> Module -- This module
+ -> [Usage] -- Usages from old iface
+ -> [(OccName, IfaceEq)] -- decl names, equality conditions
+ -> OccSet -- set of things that have changed
+computeChangedOccs ver_fn this_module old_usages eq_info
= foldl add_changes emptyOccSet (stronglyConnComp edges)
where
- edges :: [((OccName,IfaceEq), Unique, [Unique])]
+
+ -- return True if an external name has changed
+ name_changed :: Name -> Bool
+ name_changed nm
+ | Just ents <- lookupUFM usg_modmap (moduleName mod)
+ = case lookupUFM ents parent_occ of
+ Nothing -> pprPanic "computeChangedOccs" (ppr nm)
+ Just v -> v < new_version
+ | otherwise = False -- must be in another package
+ where
+ mod = nameModule nm
+ (parent_occ, new_version) = ver_fn nm
+
+ -- Turn the usages from the old ModIface into a mapping
+ usg_modmap = listToUFM [ (usg_mod usg, listToUFM (usg_entities usg))
+ | usg <- old_usages ]
+
+ get_local_eq_info :: GenIfaceEq NameSet -> GenIfaceEq OccSet
+ get_local_eq_info Equal = Equal
+ get_local_eq_info NotEqual = NotEqual
+ get_local_eq_info (EqBut ns) = foldNameSet f Equal ns
+ where f name eq | nameModule name == this_module =
+ EqBut (unitOccSet (nameOccName name)) `and_occifeq` eq
+ | name_changed name = NotEqual
+ | otherwise = eq
+
+ local_eq_infos = mapSnd get_local_eq_info eq_info
+
+ edges :: [((OccName, OccIfaceEq), Unique, [Unique])]
edges = [ (node, getUnique occ, map getUnique occs)
- | node@(occ, iface_eq) <- eq_info
+ | node@(occ, iface_eq) <- local_eq_infos
, let occs = case iface_eq of
EqBut occ_set -> occSetElts occ_set
other -> [] ]
-- Changes in declarations
- add_changes :: OccSet -> SCC (OccName, IfaceEq) -> OccSet
+ add_changes :: OccSet -> SCC (OccName, OccIfaceEq) -> OccSet
add_changes so_far (AcyclicSCC (occ, iface_eq))
- | changedWrt so_far iface_eq -- This one has changed
+ | changedWrt so_far iface_eq -- This one has changed
= extendOccSet so_far occ
add_changes so_far (CyclicSCC pairs)
- | changedWrt so_far (foldr1 (&&&) (map snd pairs)) -- One of this group has changed
- = extendOccSetList so_far (map fst pairs)
+ | changedWrt so_far (foldr1 and_occifeq iface_eqs)
+ -- One of this group has changed
+ = extendOccSetList so_far occs
+ where (occs, iface_eqs) = unzip pairs
add_changes so_far other = so_far
-changedWrt :: OccSet -> IfaceEq -> Bool
+type OccIfaceEq = GenIfaceEq OccSet
+
+changedWrt :: OccSet -> OccIfaceEq -> Bool
changedWrt so_far Equal = False
changedWrt so_far NotEqual = True
changedWrt so_far (EqBut kids) = so_far `intersectsOccSet` kids
+changedWrtNames :: OccSet -> IfaceEq -> Bool
+changedWrtNames so_far Equal = False
+changedWrtNames so_far NotEqual = True
+changedWrtNames so_far (EqBut kids) =
+ so_far `intersectsOccSet` mkOccSet (map nameOccName (nameSetToList kids))
+
+and_occifeq :: OccIfaceEq -> OccIfaceEq -> OccIfaceEq
+Equal `and_occifeq` x = x
+NotEqual `and_occifeq` x = NotEqual
+EqBut nms `and_occifeq` Equal = EqBut nms
+EqBut nms `and_occifeq` NotEqual = NotEqual
+EqBut nms1 `and_occifeq` EqBut nms2 = EqBut (nms1 `unionOccSets` nms2)
+
----------------------
-- mkOrphMap partitions instance decls or rules into
-- (a) an OccEnv for ones that are not orphans,
@@ -672,28 +714,25 @@ mkUsageInfo hsc_env dir_imp_mods dep_mods used_names
-- don't get evaluated for a while and we can end up hanging on to
-- the entire collection of Ifaces.
-mk_usage_info pit hsc_env dir_imp_mods dep_mods proto_used_names
+mk_usage_info pit hsc_env dir_imp_mods dep_mods used_names
= mapCatMaybes mkUsage dep_mods
-- ToDo: do we need to sort into canonical order?
where
hpt = hsc_HPT hsc_env
dflags = hsc_dflags hsc_env
- used_names = mkNameSet $ -- Eliminate duplicates
- [ nameParent n -- Just record usage on the 'main' names
- | n <- nameSetToList proto_used_names
- , not (isWiredInName n) -- Don't record usages for wired-in names
- , isExternalName n -- Ignore internal names
- ]
-
-- ent_map groups together all the things imported and used
-- from a particular module in this package
ent_map :: ModuleEnv [OccName]
ent_map = foldNameSet add_mv emptyModuleEnv used_names
- add_mv name mv_map = extendModuleEnv_C add_item mv_map mod [occ]
+ add_mv name mv_map
+ | isWiredInName name = mv_map -- ignore wired-in names
+ | otherwise
+ = case nameModule_maybe name of
+ Nothing -> mv_map -- ignore internal names
+ Just mod -> extendModuleEnv_C add_item mv_map mod [occ]
where
occ = nameOccName name
- mod = nameModule name
add_item occs _ = occ:occs
depend_on_exports mod = case lookupModuleEnv dir_imp_mods mod of
@@ -718,7 +757,7 @@ mk_usage_info pit hsc_env dir_imp_mods dep_mods proto_used_names
= Just (Usage { usg_name = mod_name,
usg_mod = mod_vers,
usg_exports = export_vers,
- usg_entities = ent_vers,
+ usg_entities = fmToList ent_vers,
usg_rules = rules_vers })
where
maybe_iface = lookupIfaceByModule dflags hpt pit mod
@@ -735,40 +774,48 @@ mk_usage_info pit hsc_env dir_imp_mods dep_mods proto_used_names
export_vers | depend_on_exports mod = Just (mi_exp_vers iface)
| otherwise = Nothing
- -- The sort is to put them into canonical order
used_occs = lookupModuleEnv ent_map mod `orElse` []
- ent_vers :: [(OccName,Version)]
- ent_vers = [ (occ, version_env occ `orElse` initialVersion)
- | occ <- sortLe (<=) used_occs]
+
+ -- Making a FiniteMap here ensures that (a) we remove duplicates
+ -- when we have usages on several subordinates of a single parent,
+ -- and (b) that the usages emerge in a canonical order, which
+ -- is why we use FiniteMap rather than OccEnv: FiniteMap works
+ -- using Ord on the OccNames, which is a lexicographic ordering.
+ ent_vers :: FiniteMap OccName Version
+ ent_vers = listToFM (map lookup_occ used_occs)
+
+ lookup_occ occ =
+ case version_env occ of
+ Nothing -> pprTrace "hmm, strange" (ppr mod <+> ppr occ) $
+ (occ, initialVersion) -- does this ever happen?
+ Just (parent, version) -> (parent, version)
\end{code}
\begin{code}
-mkIfaceExports :: NameSet -> [(Module, [GenAvailInfo OccName])]
+mkIfaceExports :: [AvailInfo]
+ -> [(Module, [GenAvailInfo OccName])]
-- Group by module and sort by occurrence
-- This keeps the list in canonical order
-mkIfaceExports exports
- = [ (mod, eltsUFM avails)
+mkIfaceExports exports
+ = [ (mod, eltsFM avails)
| (mod, avails) <- fmToList groupFM
]
where
- groupFM :: ModuleEnv (UniqFM (GenAvailInfo OccName))
- -- Deliberately use the FastString so we
+ -- Deliberately use FiniteMap rather than UniqFM so we
-- get a canonical ordering
- groupFM = foldl add emptyModuleEnv (nameSetToList exports)
+ groupFM :: ModuleEnv (FiniteMap FastString (GenAvailInfo OccName))
+ groupFM = foldl add emptyModuleEnv exports
- add env name = extendModuleEnv_C add_avail env mod
- (unitUFM avail_fs avail)
+ add env avail
+ = extendModuleEnv_C add_avail env mod (unitFM avail_fs avail_occ)
where
- occ = nameOccName name
- mod = nameModule name
- avail | Just p <- nameParent_maybe name = AvailTC (nameOccName p) [occ]
- | isTcOcc occ = AvailTC occ [occ]
- | otherwise = Avail occ
- avail_fs = occNameFS (availName avail)
- add_avail avail_fm _ = addToUFM_C add_item avail_fm avail_fs avail
-
- add_item (AvailTC p occs) _ = AvailTC p (List.insert occ occs)
- add_item (Avail n) _ = pprPanic "MkIface.addAvail" (ppr n <+> ppr name)
+ avail_occ = availToOccs avail
+ mod = nameModule (availName avail)
+ avail_fs = occNameFS (availName avail_occ)
+ add_avail avail_fm _ = addToFM avail_fm avail_fs avail_occ
+
+ availToOccs (Avail n) = Avail (nameOccName n)
+ availToOccs (AvailTC tc ns) = AvailTC (nameOccName tc) (map nameOccName ns)
\end{code}
@@ -961,7 +1008,7 @@ checkEntityUsage new_vers (name,old_vers)
Nothing -> -- We used it before, but it ain't there now
out_of_date (sep [ptext SLIT("No longer exported:"), ppr name])
- Just new_vers -- It's there, but is it up to date?
+ Just (_, new_vers) -- It's there, but is it up to date?
| new_vers == old_vers -> traceHiDiffs (text " Up to date" <+> ppr name <+> parens (ppr new_vers)) `thenM_`
returnM upToDate
| otherwise -> out_of_date_vers (ptext SLIT(" Out of date:") <+> ppr name)
@@ -990,26 +1037,26 @@ checkList (check:checks) = check `thenM` \ recompile ->
%************************************************************************
\begin{code}
-tyThingToIfaceDecl :: (Name -> IfaceExtName) -> TyThing -> IfaceDecl
+tyThingToIfaceDecl :: TyThing -> IfaceDecl
-- Assumption: the thing is already tidied, so that locally-bound names
-- (lambdas, for-alls) already have non-clashing OccNames
-- Reason: Iface stuff uses OccNames, and the conversion here does
-- not do tidying on the way
-tyThingToIfaceDecl ext (AnId id)
- = IfaceId { ifName = getOccName id,
- ifType = toIfaceType ext (idType id),
+tyThingToIfaceDecl (AnId id)
+ = IfaceId { ifName = getOccName id,
+ ifType = toIfaceType (idType id),
ifIdInfo = info }
where
- info = case toIfaceIdInfo ext (idInfo id) of
+ info = case toIfaceIdInfo (idInfo id) of
[] -> NoInfo
items -> HasInfo items
-tyThingToIfaceDecl ext (AClass clas)
- = IfaceClass { ifCtxt = toIfaceContext ext sc_theta,
+tyThingToIfaceDecl (AClass clas)
+ = IfaceClass { ifCtxt = toIfaceContext sc_theta,
ifName = getOccName clas,
ifTyVars = toIfaceTvBndrs clas_tyvars,
ifFDs = map toIfaceFD clas_fds,
- ifATs = map (tyThingToIfaceDecl ext . ATyCon) clas_ats,
+ ifATs = map (tyThingToIfaceDecl . ATyCon) clas_ats,
ifSigs = map toIfaceClassOp op_stuff,
ifRec = boolToRecFlag (isRecursiveTyCon tycon) }
where
@@ -1019,7 +1066,7 @@ tyThingToIfaceDecl ext (AClass clas)
toIfaceClassOp (sel_id, def_meth)
= ASSERT(sel_tyvars == clas_tyvars)
- IfaceClassOp (getOccName sel_id) def_meth (toIfaceType ext op_ty)
+ IfaceClassOp (getOccName sel_id) def_meth (toIfaceType op_ty)
where
-- Be careful when splitting the type, because of things
-- like class Foo a where
@@ -1029,19 +1076,19 @@ tyThingToIfaceDecl ext (AClass clas)
(sel_tyvars, rho_ty) = splitForAllTys (idType sel_id)
op_ty = funResultTy rho_ty
- toIfaceFD (tvs1, tvs2) = (map (occNameFS.getOccName) tvs1, map (occNameFS.getOccName) tvs2)
+ toIfaceFD (tvs1, tvs2) = (map getFS tvs1, map getFS tvs2)
-tyThingToIfaceDecl ext (ATyCon tycon)
+tyThingToIfaceDecl (ATyCon tycon)
| isSynTyCon tycon
- = IfaceSyn { ifName = getOccName tycon,
- ifTyVars = toIfaceTvBndrs tyvars,
+ = IfaceSyn { ifName = getOccName tycon,
+ ifTyVars = toIfaceTvBndrs tyvars,
ifOpenSyn = syn_isOpen,
- ifSynRhs = toIfaceType ext syn_tyki }
+ ifSynRhs = toIfaceType syn_tyki }
| isAlgTyCon tycon
= IfaceData { ifName = getOccName tycon,
ifTyVars = toIfaceTvBndrs tyvars,
- ifCtxt = toIfaceContext ext (tyConStupidTheta tycon),
+ ifCtxt = toIfaceContext (tyConStupidTheta tycon),
ifCons = ifaceConDecls (algTyConRhs tycon),
ifRec = boolToRecFlag (isRecursiveTyCon tycon),
ifGadtSyntax = isGadtSyntaxTyCon tycon,
@@ -1088,51 +1135,52 @@ tyThingToIfaceDecl ext (ATyCon tycon)
ifConUnivTvs = toIfaceTvBndrs (dataConUnivTyVars data_con),
ifConExTvs = toIfaceTvBndrs (dataConExTyVars data_con),
ifConEqSpec = to_eq_spec (dataConEqSpec data_con),
- ifConCtxt = toIfaceContext ext (dataConTheta data_con),
- ifConArgTys = map (toIfaceType ext)
- (dataConOrigArgTys data_con),
+ ifConCtxt = toIfaceContext (dataConTheta data_con),
+ ifConArgTys = map toIfaceType (dataConOrigArgTys data_con),
ifConFields = map getOccName
(dataConFieldLabels data_con),
ifConStricts = dataConStrictMarks data_con }
- to_eq_spec spec = [(getOccName tv, toIfaceType ext ty) | (tv,ty) <- spec]
+ to_eq_spec spec = [(getOccName tv, toIfaceType ty) | (tv,ty) <- spec]
famInstToIface Nothing = Nothing
famInstToIface (Just (famTyCon, instTys)) =
- Just (toIfaceTyCon ext famTyCon, map (toIfaceType ext) instTys)
+ Just (toIfaceTyCon famTyCon, map toIfaceType instTys)
-tyThingToIfaceDecl ext (ADataCon dc)
+tyThingToIfaceDecl (ADataCon dc)
= pprPanic "toIfaceDecl" (ppr dc) -- Should be trimmed out earlier
+getFS x = occNameFS (getOccName x)
+
--------------------------
-instanceToIfaceInst :: (Name -> IfaceExtName) -> Instance -> IfaceInst
-instanceToIfaceInst ext_lhs ispec@(Instance { is_dfun = dfun_id, is_flag = oflag,
- is_cls = cls, is_tcs = mb_tcs,
- is_orph = orph })
- = IfaceInst { ifDFun = getOccName dfun_id,
+instanceToIfaceInst :: Instance -> IfaceInst
+instanceToIfaceInst ispec@(Instance { is_dfun = dfun_id, is_flag = oflag,
+ is_cls = cls, is_tcs = mb_tcs,
+ is_orph = orph })
+ = IfaceInst { ifDFun = getName dfun_id,
ifOFlag = oflag,
- ifInstCls = ext_lhs cls,
+ ifInstCls = cls,
ifInstTys = map do_rough mb_tcs,
ifInstOrph = orph }
where
do_rough Nothing = Nothing
- do_rough (Just n) = Just (toIfaceTyCon_name ext_lhs n)
+ do_rough (Just n) = Just (toIfaceTyCon_name n)
--------------------------
-famInstToIfaceFamInst :: (Name -> IfaceExtName) -> FamInst -> IfaceFamInst
-famInstToIfaceFamInst ext_lhs fi@(FamInst { fi_tycon = tycon,
+famInstToIfaceFamInst :: FamInst -> IfaceFamInst
+famInstToIfaceFamInst fi@(FamInst { fi_tycon = tycon,
fi_fam = fam, fi_tcs = mb_tcs })
- = IfaceFamInst { ifFamInstTyCon = toIfaceTyCon ext_lhs tycon
- , ifFamInstFam = ext_lhs fam
+ = IfaceFamInst { ifFamInstTyCon = toIfaceTyCon tycon
+ , ifFamInstFam = fam
, ifFamInstTys = map do_rough mb_tcs }
where
do_rough Nothing = Nothing
- do_rough (Just n) = Just (toIfaceTyCon_name ext_lhs n)
+ do_rough (Just n) = Just (toIfaceTyCon_name n)
--------------------------
-toIfaceIdInfo :: (Name -> IfaceExtName) -> IdInfo -> [IfaceInfoItem]
-toIfaceIdInfo ext id_info
+toIfaceIdInfo :: IdInfo -> [IfaceInfoItem]
+toIfaceIdInfo id_info
= catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo,
inline_hsinfo, wrkr_hsinfo, unfold_hsinfo]
where
@@ -1158,7 +1206,7 @@ toIfaceIdInfo ext id_info
has_worker = case work_info of { HasWorker _ _ -> True; other -> False }
wrkr_hsinfo = case work_info of
HasWorker work_id wrap_arity ->
- Just (HsWorker (ext (idName work_id)) wrap_arity)
+ Just (HsWorker ((idName work_id)) wrap_arity)
NoWorker -> Nothing
------------ Unfolding --------------
@@ -1171,7 +1219,7 @@ toIfaceIdInfo ext id_info
-- unconditional NOINLINE, etc. See TidyPgm.addExternal
unfold_hsinfo | no_unfolding = Nothing
| has_worker = Nothing -- Unfolding is implicit
- | otherwise = Just (HsUnfold (toIfaceExpr ext rhs))
+ | otherwise = Just (HsUnfold (toIfaceExpr rhs))
------------ Inline prag --------------
inline_prag = inlinePragInfo id_info
@@ -1182,63 +1230,61 @@ toIfaceIdInfo ext id_info
| otherwise = Just (HsInline inline_prag)
--------------------------
-coreRuleToIfaceRule :: (Name -> IfaceExtName) -- For the LHS names
- -> (Name -> IfaceExtName) -- For the RHS names
- -> CoreRule -> IfaceRule
-coreRuleToIfaceRule ext_lhs ext_rhs (BuiltinRule { ru_fn = fn})
+coreRuleToIfaceRule :: CoreRule -> IfaceRule
+coreRuleToIfaceRule (BuiltinRule { ru_fn = fn})
= pprTrace "toHsRule: builtin" (ppr fn) $
- bogusIfaceRule (mkIfaceExtName fn)
+ bogusIfaceRule fn
-coreRuleToIfaceRule ext_lhs ext_rhs
- (Rule { ru_name = name, ru_fn = fn, ru_act = act, ru_bndrs = bndrs,
- ru_args = args, ru_rhs = rhs, ru_orph = orph })
+coreRuleToIfaceRule (Rule { ru_name = name, ru_fn = fn,
+ ru_act = act, ru_bndrs = bndrs,
+ ru_args = args, ru_rhs = rhs, ru_orph = orph })
= IfaceRule { ifRuleName = name, ifActivation = act,
- ifRuleBndrs = map (toIfaceBndr ext_lhs) bndrs,
- ifRuleHead = ext_lhs fn,
+ ifRuleBndrs = map toIfaceBndr bndrs,
+ ifRuleHead = fn,
ifRuleArgs = map do_arg args,
- ifRuleRhs = toIfaceExpr ext_rhs rhs,
+ ifRuleRhs = toIfaceExpr rhs,
ifRuleOrph = orph }
where
-- For type args we must remove synonyms from the outermost
-- level. Reason: so that when we read it back in we'll
-- construct the same ru_rough field as we have right now;
-- see tcIfaceRule
- do_arg (Type ty) = IfaceType (toIfaceType ext_lhs (deNoteType ty))
- do_arg arg = toIfaceExpr ext_lhs arg
+ do_arg (Type ty) = IfaceType (toIfaceType (deNoteType ty))
+ do_arg arg = toIfaceExpr arg
-bogusIfaceRule :: IfaceExtName -> IfaceRule
+bogusIfaceRule :: Name -> IfaceRule
bogusIfaceRule id_name
= IfaceRule { ifRuleName = FSLIT("bogus"), ifActivation = NeverActive,
ifRuleBndrs = [], ifRuleHead = id_name, ifRuleArgs = [],
ifRuleRhs = IfaceExt id_name, ifRuleOrph = Nothing }
---------------------
-toIfaceExpr :: (Name -> IfaceExtName) -> CoreExpr -> IfaceExpr
-toIfaceExpr ext (Var v) = toIfaceVar ext v
-toIfaceExpr ext (Lit l) = IfaceLit l
-toIfaceExpr ext (Type ty) = IfaceType (toIfaceType ext ty)
-toIfaceExpr ext (Lam x b) = IfaceLam (toIfaceBndr ext x) (toIfaceExpr ext b)
-toIfaceExpr ext (App f a) = toIfaceApp ext f [a]
-toIfaceExpr ext (Case s x ty as) = IfaceCase (toIfaceExpr ext s) (occNameFS (getOccName x)) (toIfaceType ext ty) (map (toIfaceAlt ext) as)
-toIfaceExpr ext (Let b e) = IfaceLet (toIfaceBind ext b) (toIfaceExpr ext e)
-toIfaceExpr ext (Cast e co) = IfaceCast (toIfaceExpr ext e) (toIfaceType ext co)
-toIfaceExpr ext (Note n e) = IfaceNote (toIfaceNote ext n) (toIfaceExpr ext e)
+toIfaceExpr :: CoreExpr -> IfaceExpr
+toIfaceExpr (Var v) = toIfaceVar v
+toIfaceExpr (Lit l) = IfaceLit l
+toIfaceExpr (Type ty) = IfaceType (toIfaceType ty)
+toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x) (toIfaceExpr b)
+toIfaceExpr (App f a) = toIfaceApp f [a]
+toIfaceExpr (Case s x ty as) = IfaceCase (toIfaceExpr s) (getFS x) (toIfaceType ty) (map toIfaceAlt as)
+toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e)
+toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceType co)
+toIfaceExpr (Note n e) = IfaceNote (toIfaceNote n) (toIfaceExpr e)
---------------------
-toIfaceNote ext (SCC cc) = IfaceSCC cc
-toIfaceNote ext InlineMe = IfaceInlineMe
-toIfaceNote ext (CoreNote s) = IfaceCoreNote s
+toIfaceNote (SCC cc) = IfaceSCC cc
+toIfaceNote InlineMe = IfaceInlineMe
+toIfaceNote (CoreNote s) = IfaceCoreNote s
---------------------
-toIfaceBind ext (NonRec b r) = IfaceNonRec (toIfaceIdBndr ext b) (toIfaceExpr ext r)
-toIfaceBind ext (Rec prs) = IfaceRec [(toIfaceIdBndr ext b, toIfaceExpr ext r) | (b,r) <- prs]
+toIfaceBind (NonRec b r) = IfaceNonRec (toIfaceIdBndr b) (toIfaceExpr r)
+toIfaceBind (Rec prs) = IfaceRec [(toIfaceIdBndr b, toIfaceExpr r) | (b,r) <- prs]
---------------------
-toIfaceAlt ext (c,bs,r) = (toIfaceCon c, map (occNameFS.getOccName) bs, toIfaceExpr ext r)
+toIfaceAlt (c,bs,r) = (toIfaceCon c, map getFS bs, toIfaceExpr r)
---------------------
toIfaceCon (DataAlt dc) | isTupleTyCon tc = IfaceTupleAlt (tupleTyConBoxity tc)
- | otherwise = IfaceDataAlt (getOccName dc)
+ | otherwise = IfaceDataAlt (getName dc)
where
tc = dataConTyCon dc
@@ -1246,8 +1292,8 @@ toIfaceCon (LitAlt l) = IfaceLitAlt l
toIfaceCon DEFAULT = IfaceDefault
---------------------
-toIfaceApp ext (App f a) as = toIfaceApp ext f (a:as)
-toIfaceApp ext (Var v) as
+toIfaceApp (App f a) as = toIfaceApp f (a:as)
+toIfaceApp (Var v) as
= case isDataConWorkId_maybe v of
-- We convert the *worker* for tuples into IfaceTuples
Just dc | isTupleTyCon tc && saturated
@@ -1255,22 +1301,22 @@ toIfaceApp ext (Var v) as
where
val_args = dropWhile isTypeArg as
saturated = val_args `lengthIs` idArity v
- tup_args = map (toIfaceExpr ext) val_args
+ tup_args = map toIfaceExpr val_args
tc = dataConTyCon dc
- other -> mkIfaceApps ext (toIfaceVar ext v) as
+ other -> mkIfaceApps (toIfaceVar v) as
-toIfaceApp ext e as = mkIfaceApps ext (toIfaceExpr ext e) as
+toIfaceApp e as = mkIfaceApps (toIfaceExpr e) as
-mkIfaceApps ext f as = foldl (\f a -> IfaceApp f (toIfaceExpr ext a)) f as
+mkIfaceApps f as = foldl (\f a -> IfaceApp f (toIfaceExpr a)) f as
---------------------
-toIfaceVar :: (Name -> IfaceExtName) -> Id -> IfaceExpr
-toIfaceVar ext v
- | Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType ext (idType v))
+toIfaceVar :: Id -> IfaceExpr
+toIfaceVar v
+ | Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType (idType v))
-- Foreign calls have special syntax
- | isExternalName name = IfaceExt (ext name)
- | otherwise = IfaceLcl (occNameFS (nameOccName name))
+ | isExternalName name = IfaceExt name
+ | otherwise = IfaceLcl (getFS name)
where
name = idName v
\end{code}
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index fa227e6756..c16846ec28 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -14,9 +14,9 @@ module TcIface (
import IfaceSyn
import LoadIface ( loadInterface, loadWiredInHomeIface, findAndReadIface, loadDecls )
-import IfaceEnv ( lookupIfaceTop, lookupIfaceExt, newGlobalBinder,
+import IfaceEnv ( lookupIfaceTop, newGlobalBinder,
extendIfaceIdEnv, extendIfaceTyVarEnv, newIPName,
- tcIfaceTyVar, tcIfaceLclId, lookupIfaceTc,
+ tcIfaceTyVar, tcIfaceLclId,
newIfaceName, newIfaceNames, ifaceExportNames )
import BuildTyCl ( buildSynTyCon, buildAlgTyCon, buildDataCon,
buildClass,
@@ -511,10 +511,9 @@ tcIfaceInst (IfaceInst { ifDFun = dfun_occ, ifOFlag = oflag,
ifInstCls = cls, ifInstTys = mb_tcs,
ifInstOrph = orph })
= do { dfun <- forkM (ptext SLIT("Dict fun") <+> ppr dfun_occ) $
- tcIfaceExtId (LocalTop dfun_occ)
- ; cls' <- lookupIfaceExt cls
- ; mb_tcs' <- mapM tc_rough mb_tcs
- ; return (mkImportedInstance cls' mb_tcs' orph dfun oflag) }
+ tcIfaceExtId dfun_occ
+ ; let mb_tcs' = map (fmap ifaceTyConName) mb_tcs
+ ; return (mkImportedInstance cls mb_tcs' orph dfun oflag) }
tcIfaceFamInst :: IfaceFamInst -> IfL FamInst
tcIfaceFamInst (IfaceFamInst { ifFamInstTyCon = tycon,
@@ -523,12 +522,8 @@ tcIfaceFamInst (IfaceFamInst { ifFamInstTyCon = tycon,
-- ^^^this line doesn't work, but vvv this does => CPP in Haskell = evil!
= do { tycon' <- forkM (text ("Inst tycon") <+> ppr tycon) $
tcIfaceTyCon tycon
- ; fam' <- lookupIfaceExt fam
- ; mb_tcs' <- mapM tc_rough mb_tcs
- ; return (mkImportedFamInst fam' mb_tcs' tycon') }
-
-tc_rough Nothing = return Nothing
-tc_rough (Just tc) = do { tc' <- lookupIfaceTc tc; return (Just tc') }
+ ; let mb_tcs' = map (fmap ifaceTyConName) mb_tcs
+ ; return (mkImportedFamInst fam mb_tcs' tycon') }
\end{code}
@@ -554,20 +549,21 @@ tcIfaceRule :: IfaceRule -> IfL CoreRule
tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bndrs,
ifRuleHead = fn, ifRuleArgs = args, ifRuleRhs = rhs,
ifRuleOrph = orph })
- = do { fn' <- lookupIfaceExt fn
- ; ~(bndrs', args', rhs') <-
+ = do { ~(bndrs', args', rhs') <-
-- Typecheck the payload lazily, in the hope it'll never be looked at
forkM (ptext SLIT("Rule") <+> ftext name) $
bindIfaceBndrs bndrs $ \ bndrs' ->
do { args' <- mappM tcIfaceExpr args
; rhs' <- tcIfaceExpr rhs
; return (bndrs', args', rhs') }
- ; mb_tcs <- mapM ifTopFreeName args
- ; returnM (Rule { ru_name = name, ru_fn = fn', ru_act = act,
+ ; let mb_tcs = map ifTopFreeName args
+ ; lcl <- getLclEnv
+ ; let this_module = if_mod lcl
+ ; returnM (Rule { ru_name = name, ru_fn = fn, ru_act = act,
ru_bndrs = bndrs', ru_args = args',
ru_rhs = rhs', ru_orph = orph,
ru_rough = mb_tcs,
- ru_local = isLocalIfaceExtName fn }) }
+ ru_local = nameModule fn == this_module }) }
where
-- This function *must* mirror exactly what Rules.topFreeName does
-- We could have stored the ru_rough field in the iface file
@@ -576,14 +572,11 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd
-- type syononyms at the top of a type arg. Since
-- we can't tell at this point, we are careful not
-- to write them out in coreRuleToIfaceRule
- ifTopFreeName :: IfaceExpr -> IfL (Maybe Name)
- ifTopFreeName (IfaceType (IfaceTyConApp tc _ ))
- = do { n <- lookupIfaceTc tc
- ; return (Just n) }
- ifTopFreeName (IfaceApp f a) = ifTopFreeName f
- ifTopFreeName (IfaceExt ext) = do { n <- lookupIfaceExt ext
- ; return (Just n) }
- ifTopFreeName other = return Nothing
+ ifTopFreeName :: IfaceExpr -> Maybe Name
+ ifTopFreeName (IfaceType (IfaceTyConApp tc _ )) = Just (ifaceTyConName tc)
+ ifTopFreeName (IfaceApp f a) = ifTopFreeName f
+ ifTopFreeName (IfaceExt n) = Just n
+ ifTopFreeName other = Nothing
\end{code}
@@ -725,8 +718,7 @@ tcIfaceAlt _ (IfaceLitAlt lit, names, rhs)
-- by the fact that we omit type annotations because we can
-- work them out. True enough, but its not that easy!
tcIfaceAlt (tycon, inst_tys) (IfaceDataAlt data_occ, arg_strs, rhs)
- = do { let tycon_mod = nameModule (tyConName tycon)
- ; con <- tcIfaceDataCon (ExtPkg tycon_mod data_occ)
+ = do { con <- tcIfaceDataCon data_occ
; ASSERT2( con `elem` tyConDataCons tycon,
ppr con $$ ppr tycon $$ ppr (tyConDataCons tycon) )
tcIfaceDataAlt con inst_tys arg_strs rhs }
@@ -931,12 +923,11 @@ tcIfaceTyCon IfaceCharTc = tcWiredInTyCon charTyCon
tcIfaceTyCon IfaceListTc = tcWiredInTyCon listTyCon
tcIfaceTyCon IfacePArrTc = tcWiredInTyCon parrTyCon
tcIfaceTyCon (IfaceTupTc bx ar) = tcWiredInTyCon (tupleTyCon bx ar)
-tcIfaceTyCon (IfaceTc ext_nm) = do { name <- lookupIfaceExt ext_nm
- ; thing <- tcIfaceGlobal name
+tcIfaceTyCon (IfaceTc name) = do { thing <- tcIfaceGlobal name
; return (check_tc (tyThingTyCon thing)) }
where
#ifdef DEBUG
- check_tc tc = case toIfaceTyCon (error "urk") tc of
+ check_tc tc = case toIfaceTyCon tc of
IfaceTc _ -> tc
other -> pprTrace "check_tc" (ppr tc) tc
#else
@@ -956,24 +947,21 @@ tcWiredInTyCon :: TyCon -> IfL TyCon
tcWiredInTyCon tc = do { ifCheckWiredInThing (tyConName tc)
; return tc }
-tcIfaceClass :: IfaceExtName -> IfL Class
-tcIfaceClass rdr_name = do { name <- lookupIfaceExt rdr_name
- ; thing <- tcIfaceGlobal name
- ; return (tyThingClass thing) }
+tcIfaceClass :: Name -> IfL Class
+tcIfaceClass name = do { thing <- tcIfaceGlobal name
+ ; return (tyThingClass thing) }
-tcIfaceDataCon :: IfaceExtName -> IfL DataCon
-tcIfaceDataCon gbl = do { name <- lookupIfaceExt gbl
- ; thing <- tcIfaceGlobal name
- ; case thing of
+tcIfaceDataCon :: Name -> IfL DataCon
+tcIfaceDataCon name = do { thing <- tcIfaceGlobal name
+ ; case thing of
ADataCon dc -> return dc
- other -> pprPanic "tcIfaceExtDC" (ppr gbl $$ ppr name$$ ppr thing) }
+ other -> pprPanic "tcIfaceExtDC" (ppr name$$ ppr thing) }
-tcIfaceExtId :: IfaceExtName -> IfL Id
-tcIfaceExtId gbl = do { name <- lookupIfaceExt gbl
- ; thing <- tcIfaceGlobal name
- ; case thing of
+tcIfaceExtId :: Name -> IfL Id
+tcIfaceExtId name = do { thing <- tcIfaceGlobal name
+ ; case thing of
AnId id -> return id
- other -> pprPanic "tcIfaceExtId" (ppr gbl $$ ppr name$$ ppr thing) }
+ other -> pprPanic "tcIfaceExtId" (ppr name$$ ppr thing) }
\end{code}
%************************************************************************
@@ -1018,7 +1006,7 @@ bindIfaceIds bndrs thing_inside
newExtCoreBndr :: IfaceIdBndr -> IfL Id
newExtCoreBndr (var, ty)
= do { mod <- getIfModule
- ; name <- newGlobalBinder mod (mkVarOccFS var) Nothing noSrcLoc
+ ; name <- newGlobalBinder mod (mkVarOccFS var) noSrcLoc
; ty' <- tcIfaceType ty
; return (mkLocalId name ty') }