From 3932b76369acda843a6c998449bf953a7cb2f5fc Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Fri, 6 Oct 2006 16:14:03 +0000 Subject: [PATCH] Comments and an import-trim --- compiler/coreSyn/CoreSyn.lhs | 2 +- compiler/deSugar/Desugar.lhs | 3 ++ compiler/rename/RnNames.lhs | 2 +- compiler/types/InstEnv.lhs | 119 ++++++++++++++++++++++-------------------- 4 files changed, 67 insertions(+), 59 deletions(-) diff --git a/compiler/coreSyn/CoreSyn.lhs b/compiler/coreSyn/CoreSyn.lhs index 65a1b40..f5627e7 100644 --- a/compiler/coreSyn/CoreSyn.lhs +++ b/compiler/coreSyn/CoreSyn.lhs @@ -201,7 +201,7 @@ data CoreRule ru_local :: Bool, -- The fn at the head of the rule is -- defined in the same module as the rule - -- Orphan-hood; see comments is InstEnv.Instance( is_orph ) + -- Orphan-hood; see Note [Orphans] in InstEnv ru_orph :: Maybe OccName } | BuiltinRule { -- Built-in rules are used for constant folding diff --git a/compiler/deSugar/Desugar.lhs b/compiler/deSugar/Desugar.lhs index dc0e124..c2ee0a5 100644 --- a/compiler/deSugar/Desugar.lhs +++ b/compiler/deSugar/Desugar.lhs @@ -270,6 +270,9 @@ dsRule mod in_scope (L loc (HsRule name act vars lhs tv_lhs rhs fv_rhs)) lhs_names = fn_name : nameSetToList (exprsFreeNames args) -- No need to delete bndrs, because -- exprsFreeNames finds only External names + + -- A rule is an orphan only if none of the variables + -- mentioned on its left-hand side are locally defined orph = case filter (nameIsLocalOrFrom mod) lhs_names of (n:ns) -> Just (nameOccName n) [] -> Nothing diff --git a/compiler/rename/RnNames.lhs b/compiler/rename/RnNames.lhs index a6b021d..4bca4fc 100644 --- a/compiler/rename/RnNames.lhs +++ b/compiler/rename/RnNames.lhs @@ -59,7 +59,7 @@ import DriverPhases ( isHsBoot ) import Util ( notNull ) import List ( partition ) import IO ( openFile, IOMode(..) ) -import Monad ( liftM, when ) +import Monad ( when ) \end{code} diff --git a/compiler/types/InstEnv.lhs b/compiler/types/InstEnv.lhs index f4559e7..d8f549d 100644 --- a/compiler/types/InstEnv.lhs +++ b/compiler/types/InstEnv.lhs @@ -67,65 +67,70 @@ data Instance -- the decl of BasicTypes.OverlapFlag , is_orph :: Maybe OccName } +\end{code} --- The "rough-match" fields --- ~~~~~~~~~~~~~~~~~~~~~~~~~ --- The is_cls, is_args fields allow a "rough match" to be done --- without poking inside the DFunId. Poking the DFunId forces --- us to suck in all the type constructors etc it involves, --- which is a total waste of time if it has no chance of matching --- So the Name, [Maybe Name] fields allow us to say "definitely --- does not match", based only on the Name. --- --- In is_tcs, --- Nothing means that this type arg is a type variable --- --- (Just n) means that this type arg is a --- TyConApp with a type constructor of n. --- This is always a real tycon, never a synonym! --- (Two different synonyms might match, but two --- different real tycons can't.) --- NB: newtypes are not transparent, though! --- --- The "proper-match" fields --- ~~~~~~~~~~~~~~~~~~~~~~~~~ --- The is_tvs, is_tys fields are simply cahced values, pulled --- out (lazily) from the dfun id. They are cached here simply so --- that we don't need to decompose the DFunId each time we want --- to match it. The hope is that the fast-match fields mean --- that we often never poke th proper-match fields --- --- However, note that: --- * is_tvs must be a superset of the free vars of is_tys --- --- * The is_dfun must itself be quantified over exactly is_tvs --- (This is so that we can use the matching substitution to --- instantiate the dfun's context.) --- --- The "orphan" field --- ~~~~~~~~~~~~~~~~~~ --- An instance is an orphan if its head (after the =>) mentions --- nothing defined in this module. --- --- Just n The head mentions n, which is defined in this module --- This is used for versioning; the instance decl is --- considered part of the defn of n when computing versions --- --- Nothing The head mentions nothing defined in this module --- --- If a module contains any orphans, then its interface file is read --- regardless, so that its instances are not missed. --- --- Functional dependencies worsen the situation a bit. Consider --- class C a b | a -> b --- In some other module we might have --- module M where --- data T = ... --- instance C Int T where ... --- This isn't considered an orphan, so we will only read M's interface --- if something from M is used (e.g. T). So there's a risk we'll --- miss the improvement from the instance. Workaround: import M. +The "rough-match" fields +~~~~~~~~~~~~~~~~~~~~~~~~~ +The is_cls, is_args fields allow a "rough match" to be done +without poking inside the DFunId. Poking the DFunId forces +us to suck in all the type constructors etc it involves, +which is a total waste of time if it has no chance of matching +So the Name, [Maybe Name] fields allow us to say "definitely +does not match", based only on the Name. + +In is_tcs, + Nothing means that this type arg is a type variable + + (Just n) means that this type arg is a + TyConApp with a type constructor of n. + This is always a real tycon, never a synonym! + (Two different synonyms might match, but two + different real tycons can't.) + NB: newtypes are not transparent, though! + +The "proper-match" fields +~~~~~~~~~~~~~~~~~~~~~~~~~ +The is_tvs, is_tys fields are simply cahced values, pulled +out (lazily) from the dfun id. They are cached here simply so +that we don't need to decompose the DFunId each time we want +to match it. The hope is that the fast-match fields mean +that we often never poke th proper-match fields + +However, note that: + * is_tvs must be a superset of the free vars of is_tys + + * The is_dfun must itself be quantified over exactly is_tvs + (This is so that we can use the matching substitution to + instantiate the dfun's context.) + + +Note [Orphans]: the "is_orph" field +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +An instance is an orphan if its head (after the =>) mentions +nothing defined in this module. + + Just n The head mentions n, which is defined in this module + This is used for versioning; the instance decl is + considered part of the defn of n when computing versions + + Nothing The head mentions nothing defined in this module + +If a module contains any orphans, then its interface file is read +regardless, so that its instances are not missed. + +Functional dependencies worsen the situation a bit. Consider + class C a b | a -> b +In some other module we might have + module M where + data T = ... + instance C Int T where ... +This isn't considered an orphan, so we will only read M's interface +if something from M is used (e.g. T). So there's a risk we'll +miss the improvement from the instance. Workaround: import M. + +Rules are orphans and versioned in much the same way. +\begin{code} instanceDFunId :: Instance -> DFunId instanceDFunId = is_dfun -- 1.7.10.4