[commit: ghc] master: Comments about orphans (34ab89a)

Simon Peyton Jones simonpj at microsoft.com
Tue Dec 13 14:37:47 CET 2011


Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/34ab89a9f86a33b225a7d8743302db8808127b64

>---------------------------------------------------------------

commit 34ab89a9f86a33b225a7d8743302db8808127b64
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Mon Dec 12 08:10:43 2011 +0000

    Comments about orphans

>---------------------------------------------------------------

 compiler/iface/IfaceSyn.lhs |   36 ++++++++++++++++++++++++++++++++----
 compiler/iface/MkIface.lhs  |    3 +++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/compiler/iface/IfaceSyn.lhs b/compiler/iface/IfaceSyn.lhs
index 92fb0d9..9f25078 100644
--- a/compiler/iface/IfaceSyn.lhs
+++ b/compiler/iface/IfaceSyn.lhs
@@ -298,8 +298,32 @@ that is what is seen by importing module with --make
 
 Note [Orphans]: the ifInstOrph and ifRuleOrph fields
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If a module contains any "orphans", then its interface file is read
-regardless, so that its instances are not missed. 
+Class instances, rules, and family instances are divided into orphans
+and non-orphans.  Roughly speaking, an instance/rule is an orphan if
+its left hand side mentions nothing defined in this module.  Orphan-hood
+has two major consequences
+
+ * A non-orphan is not finger-printerd separately.  Instead, for
+   fingerprinting purposes it is treated as part of the entity it
+   mentions on the LHS.  For example
+      data T = T1 | T2
+      instance Eq T where ....
+   The instance (Eq T) is incorprated as part of T's fingerprint.
+
+   In constrast, orphans are all fingerprinted together in the 
+   mi_orph_hash field of the ModIface. 
+  
+   See MkIface.addFingerprints.
+
+ * A module that contains orphans is called an "orphan module".  If
+   the module being compiled depends (transitively) on an oprhan
+   module M, then M.hi is read in regardless of whether M is oherwise
+   needed. This is to ensure that we don't miss any instance decls in
+   M.  But it's painful, because it means we need to keep track of all
+   the orphan modules below us.
+
+Orphan-hood is computed when we generate an IfaceInst, IfaceRule, or
+IfaceFamInst respectively: 
 
  - If an instance is an orphan its ifInstOprh field is Nothing
    Otherwise ifInstOrph is (Just n) where n is the Name of a
@@ -309,9 +333,13 @@ regardless, so that its instances are not missed.
  - Similarly for ifRuleOrph
    The computation is done by MkIface.coreRuleToIfaceRule
 
+Note [When exactly is an instance decl an orphan?]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  (see MkIface.instanceToIfaceInst, which implements this)
 Roughly speaking, an instance is an orphan if its head (after the =>)
-mentions nothing defined in this module.  Functional dependencies
-complicate the situation though. Consider
+mentions nothing defined in this module.  
+
+Functional dependencies complicate the situation though. Consider
 
   module M where { class C a b | a -> b }
 
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index 3edf1d6..2125181 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -633,6 +633,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
     this_pkg = thisPackage dflags
     (non_orph_insts, orph_insts) = mkOrphMap ifInstOrph (mi_insts iface0)
     (non_orph_rules, orph_rules) = mkOrphMap ifRuleOrph (mi_rules iface0)
+        -- See Note [Orphans] in IfaceSyn
         -- ToDo: shouldn't we be splitting fam_insts into orphans and
         -- non-orphans?
     fam_insts = mi_fam_insts iface0
@@ -1548,6 +1549,8 @@ instanceToIfaceInst (Instance { is_dfun = dfun_id, is_flag = oflag,
                 -- Slightly awkward: we need the Class to get the fundeps
     (tvs, fds) = classTvsFds cls
     arg_names = [filterNameSet is_local (orphNamesOfType ty) | ty <- tys]
+
+    -- See Note [When exactly is an instance decl an orphan?] in IfaceSyn
     orph | is_local cls_name = Just (nameOccName cls_name)
          | all isJust mb_ns  = ASSERT( not (null mb_ns) ) head mb_ns
          | otherwise         = Nothing





More information about the Cvs-ghc mailing list