Cross-module consistency check for family instances
[ghc-hetmet.git] / compiler / main / HscTypes.lhs
index 7e30d77..c5483b9 100644 (file)
@@ -367,6 +367,7 @@ data ModIface
         mi_mod_vers :: !Version,           -- Module version: changes when anything changes
 
         mi_orphan   :: !WhetherHasOrphans,  -- Whether this module has orphans
         mi_mod_vers :: !Version,           -- Module version: changes when anything changes
 
         mi_orphan   :: !WhetherHasOrphans,  -- Whether this module has orphans
+        mi_finsts   :: !WhetherHasFamInst,  -- Whether module has family insts
        mi_boot     :: !IsBootInterface,    -- Read from an hi-boot file?
 
        mi_deps     :: Dependencies,
        mi_boot     :: !IsBootInterface,    -- Read from an hi-boot file?
 
        mi_deps     :: Dependencies,
@@ -420,7 +421,8 @@ data ModIface
        mi_fam_insts :: [IfaceFamInst],                 -- Sorted
        mi_rules     :: [IfaceRule],                    -- Sorted
        mi_rule_vers :: !Version,       -- Version number for rules and 
        mi_fam_insts :: [IfaceFamInst],                 -- Sorted
        mi_rules     :: [IfaceRule],                    -- Sorted
        mi_rule_vers :: !Version,       -- Version number for rules and 
-                                       -- instances combined
+                                       -- instances (for classes and families)
+                                       -- combined
 
                -- Cached environments for easy lookup
                -- These are computed (lazily) from other fields
 
                -- Cached environments for easy lookup
                -- These are computed (lazily) from other fields
@@ -438,12 +440,12 @@ data ModIface
 -- Should be able to construct ModDetails from mi_decls in ModIface
 data ModDetails
    = ModDetails {
 -- Should be able to construct ModDetails from mi_decls in ModIface
 data ModDetails
    = ModDetails {
-       -- The next three fields are created by the typechecker
-       md_exports  :: [AvailInfo],
-        md_types    :: !TypeEnv,
-        md_fam_insts :: ![FamInst],    -- Cached value extracted from md_types
-        md_insts    :: ![Instance],    -- Dfun-ids for the instances in this module
-        md_rules    :: ![CoreRule]     -- Domain may include Ids from other modules
+       -- The next two fields are created by the typechecker
+       md_exports   :: [AvailInfo],
+        md_types     :: !TypeEnv,
+        md_insts     :: ![Instance],   -- Dfun-ids for the instances in this module
+        md_fam_insts :: ![FamInst],
+        md_rules     :: ![CoreRule]    -- Domain may include Ids from other modules
      }
 
 emptyModDetails = ModDetails { md_types = emptyTypeEnv,
      }
 
 emptyModDetails = ModDetails { md_types = emptyTypeEnv,
@@ -550,6 +552,7 @@ emptyModIface mod
   = ModIface { mi_module   = mod,
               mi_mod_vers = initialVersion,
               mi_orphan   = False,
   = ModIface { mi_module   = mod,
               mi_mod_vers = initialVersion,
               mi_orphan   = False,
+              mi_finsts   = False,
               mi_boot     = False,
               mi_deps     = noDependencies,
               mi_usages   = [],
               mi_boot     = False,
               mi_deps     = noDependencies,
               mi_usages   = [],
@@ -854,11 +857,8 @@ instance Outputable n => Outputable (GenAvailInfo n) where
    ppr = pprAvail
 
 pprAvail :: Outputable n => GenAvailInfo n -> SDoc
    ppr = pprAvail
 
 pprAvail :: Outputable n => GenAvailInfo n -> SDoc
-pprAvail (AvailTC n ns) = ppr n <> case {- filter (/= n) -} ns of
-                                       []  -> empty
-                                       ns' -> braces (hsep (punctuate comma (map ppr ns')))
-
-pprAvail (Avail n) = ppr n
+pprAvail (Avail n)      = ppr n
+pprAvail (AvailTC n ns) = ppr n <> braces (hsep (punctuate comma (map ppr ns)))
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -904,22 +904,32 @@ type WhetherHasOrphans   = Bool
        --      * a transformation rule in a module other than the one defining
        --              the function in the head of the rule.
 
        --      * a transformation rule in a module other than the one defining
        --              the function in the head of the rule.
 
+type WhetherHasFamInst = Bool       -- This module defines family instances?
+
 type IsBootInterface = Bool
 
 -- Dependency info about modules and packages below this one
 -- in the import hierarchy.  See TcRnTypes.ImportAvails for details.
 type IsBootInterface = Bool
 
 -- Dependency info about modules and packages below this one
 -- in the import hierarchy.  See TcRnTypes.ImportAvails for details.
+-- The orphan modules in `dep_orphs' do *not* include family instance orphans,
+-- as they are anyway included in `dep_finsts'.
 --
 -- Invariant: the dependencies of a module M never includes M
 -- Invariant: the lists are unordered, with no duplicates
 data Dependencies
 --
 -- Invariant: the dependencies of a module M never includes M
 -- Invariant: the lists are unordered, with no duplicates
 data Dependencies
-  = Deps { dep_mods  :: [(ModuleName,IsBootInterface)],        -- Home-package module dependencies
-          dep_pkgs  :: [PackageId],                    -- External package dependencies
-          dep_orphs :: [Module] }                      -- Orphan modules (whether home or external pkg)
+  = Deps { dep_mods   :: [(ModuleName,      -- Home-package module dependencies
+                          IsBootInterface)]
+        , dep_pkgs   :: [PackageId]        -- External package dependencies
+        , dep_orphs  :: [Module]           -- Orphan modules (whether home or
+                                           -- external pkg)
+         , dep_finsts :: [Module]          -- Modules that contain family
+                                           -- instances (whether home or
+                                           -- external pkg)
+         }
   deriving( Eq )
        -- Equality used only for old/new comparison in MkIface.addVersionInfo
 
 noDependencies :: Dependencies
   deriving( Eq )
        -- Equality used only for old/new comparison in MkIface.addVersionInfo
 
 noDependencies :: Dependencies
-noDependencies = Deps [] [] []
+noDependencies = Deps [] [] [] []
          
 data Usage
   = Usage { usg_name     :: ModuleName,                        -- Name of the module
          
 data Usage
   = Usage { usg_name     :: ModuleName,                        -- Name of the module
@@ -998,6 +1008,9 @@ data ExternalPackageState
        eps_fam_inst_env :: !PackageFamInstEnv,-- Ditto FamInstEnv
        eps_rule_base    :: !PackageRuleBase,  -- Ditto RuleEnv
 
        eps_fam_inst_env :: !PackageFamInstEnv,-- Ditto FamInstEnv
        eps_rule_base    :: !PackageRuleBase,  -- Ditto RuleEnv
 
+        eps_mod_fam_inst_env :: !(ModuleEnv FamInstEnv), -- identifies family
+                                                      -- instances of each mod
+
        eps_stats :: !EpsStats
   }
 
        eps_stats :: !EpsStats
   }