Keep track of family instance modules
[ghc-hetmet.git] / compiler / iface / MkIface.lhs
index e99e8bf..2f17fe7 100644 (file)
@@ -1,4 +1,5 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
 %
 
@@ -175,80 +176,46 @@ compiled with -O.  I think this is the case.]
 \begin{code}
 #include "HsVersions.h"
 
-import IfaceSyn                -- All of it
+import IfaceSyn
 import IfaceType
-import LoadIface       ( readIface, loadInterface, pprModIface )
-import Id              ( Id, idName, idType, idInfo, idArity, isDataConWorkId_maybe, isFCallId_maybe )
-import IdInfo          ( IdInfo, CafInfo(..), WorkerInfo(..), 
-                         arityInfo, cafInfo, newStrictnessInfo, 
-                         workerInfo, unfoldingInfo, inlinePragInfo )
-import NewDemand       ( isTopSig )
+import LoadIface
+import Id
+import IdInfo
+import NewDemand
 import CoreSyn
-import Class           ( classExtraBigSig, classTyCon )
-import TyCon           ( TyCon, AlgTyConRhs(..), SynTyConRhs(..),
-                         isRecursiveTyCon, isForeignTyCon, 
-                         isSynTyCon, isAlgTyCon, isPrimTyCon, isFunTyCon,
-                         isTupleTyCon, tupleTyConBoxity, tyConStupidTheta,
-                         tyConHasGenerics, synTyConRhs, isGadtSyntaxTyCon,
-                         tyConArity, tyConTyVars, algTyConRhs, tyConExtName,
-                         tyConFamInst_maybe )
-import DataCon         ( dataConName, dataConFieldLabels, dataConStrictMarks,
-                         dataConTyCon, dataConIsInfix, dataConUnivTyVars,
-                         dataConExTyVars, dataConEqSpec, dataConTheta,
-                         dataConOrigArgTys ) 
-import Type            ( TyThing(..), splitForAllTys, funResultTy )
-import TcType          ( deNoteType )
-import TysPrim         ( alphaTyVars )
-import InstEnv         ( Instance(..) )
-import FamInstEnv      ( FamInst(..) )
+import Class
+import TyCon
+import DataCon
+import Type
+import TcType
+import TysPrim
+import InstEnv
+import FamInstEnv
 import TcRnMonad
-import HscTypes                ( ModIface(..), ModDetails(..), 
-                         ModGuts(..), HscEnv(..), hscEPS, Dependencies(..),
-                         FixItem(..), 
-                         ModSummary(..), msHiFilePath, 
-                         mkIfaceDepCache, mkIfaceFixCache, mkIfaceVerCache,
-                         typeEnvElts,
-                         GenAvailInfo(..), availName, AvailInfo,
-                         ExternalPackageState(..),
-                         Usage(..), IsBootInterface,
-                         Deprecs(..), IfaceDeprecs, Deprecations,
-                         lookupIfaceByModule, isImplicitTyThing
-                       )
-
-
-import DynFlags                ( GhcMode(..), DynFlags(..), DynFlag(..), dopt )
-import Name            ( Name, nameModule, nameModule_maybe, nameOccName,
-                         isExternalName, isInternalName, isWiredInName,
-                         NamedThing(..) )
+import HscTypes
+
+import DynFlags
+import Name
 import NameEnv
 import NameSet
-import OccName         ( OccName, OccEnv, mkOccEnv, lookupOccEnv, emptyOccEnv,
-                         extendOccEnv_C,
-                         OccSet, emptyOccSet, elemOccSet, occSetElts, 
-                         extendOccSet, extendOccSetList, mkOccSet,
-                         isEmptyOccSet, intersectOccSet, intersectsOccSet,
-                          unionOccSets, unitOccSet,
-                         occNameFS, isTcOcc )
+import OccName
 import Module
-import BinIface                ( readBinIface, writeBinIface, v_IgnoreHiWay )
-import Unique          ( Unique, Uniquable(..) )
-import ErrUtils                ( dumpIfSet_dyn, showPass )
-import Digraph         ( stronglyConnComp, SCC(..) )
-import SrcLoc          ( SrcSpan )
-import PackageConfig   ( PackageId )
+import BinIface
+import Unique
+import ErrUtils
+import Digraph
+import SrcLoc
+import PackageConfig    hiding ( Version )
 import Outputable
 import BasicTypes       hiding ( SuccessFlag(..) )
 import UniqFM
 import Util             hiding ( eqListBy )
 import FiniteMap
 import FastString
+import Maybes
 
-import Data.List        ( partition )
-import DATA_IOREF      ( writeIORef )
-import Monad           ( when )
-import List            ( insert )
-import Maybes          ( orElse, mapCatMaybes, isNothing, isJust, 
-                         expectJust, catMaybes, MaybeErr(..) )
+import Control.Monad
+import Data.List
 \end{code}
 
 
@@ -322,6 +289,7 @@ mkIface hsc_env maybe_old_iface
                        mi_rule_vers = initialVersion,
                        mi_orphan    = False,   -- Always set by addVersionInfo, but
                                                -- it's a strict field, so we can't omit it.
+                        mi_finsts    = False,   -- Ditto
                        mi_decls     = deliberatelyOmitted "decls",
                        mi_ver_fn    = deliberatelyOmitted "ver_fn",
 
@@ -404,9 +372,12 @@ addVersionInfo
 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 = mkIfaceVerCache (zip (repeat initialVersion) new_decls)},
+                                || anyNothing ifRuleOrph (mi_rules new_iface)
+               , mi_finsts = not . null $ mi_fam_insts 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)
@@ -434,6 +405,7 @@ addVersionInfo ver_fn (Just old_iface@(ModIface {
                 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_finsts    = not . null $ mi_fam_insts new_iface,
                 mi_decls     = decls_w_vers,
                 mi_ver_fn    = mkIfaceVerCache decls_w_vers }
 
@@ -444,6 +416,8 @@ addVersionInfo ver_fn (Just old_iface@(ModIface {
         mkOrphMap ifInstOrph (mi_insts old_iface)
     (new_non_orph_insts, new_orph_insts) = 
         mkOrphMap ifInstOrph (mi_insts new_iface)
+    old_fam_insts = mi_fam_insts old_iface
+    new_fam_insts = mi_fam_insts new_iface
     same_insts occ = eqMaybeBy (eqListBy eqIfInst) 
                                (lookupOccEnv old_non_orph_insts occ)
                                (lookupOccEnv new_non_orph_insts occ)
@@ -463,7 +437,8 @@ addVersionInfo ver_fn (Just old_iface@(ModIface {
                                 -- Kept sorted
     no_decl_change   = isEmptyOccSet changed_occs
     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))
+                        || changedWrtNames changed_occs (eqListBy eqIfInst old_orph_insts new_orph_insts)
+                        || changedWrtNames changed_occs (eqListBy eqIfFamInst old_fam_insts new_fam_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
@@ -743,14 +718,15 @@ mk_usage_info pit hsc_env dir_imp_mods dep_mods used_names
     -- a) we used something from; has something in used_names
     -- b) we imported all of it, even if we used nothing from it
     --         (need to recompile if its export list changes: export_vers)
-    -- c) is a home-package orphan module (need to recompile if its
-    --         instance decls change: rules_vers)
+    -- c) is a home-package orphan or family-instance module (need to
+    --         recompile if its instance decls change: rules_vers)
     mkUsage :: (ModuleName, IsBootInterface) -> Maybe Usage
     mkUsage (mod_name, _)
       |  isNothing maybe_iface         -- We can't depend on it if we didn't
       || (null used_occs               -- load its interface.
          && isNothing export_vers
-         && not orphan_mod)
+         && not orphan_mod
+         && not finsts_mod)
       = Nothing                        -- Record no usage info
     
       | otherwise      
@@ -768,6 +744,7 @@ mk_usage_info pit hsc_env dir_imp_mods dep_mods used_names
 
         Just iface   = maybe_iface
        orphan_mod   = mi_orphan    iface
+       finsts_mod   = mi_finsts    iface
         version_env  = mi_ver_fn    iface
         mod_vers     = mi_mod_vers  iface
         rules_vers   = mi_rule_vers iface