[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