exprSomeFreeVars, exprsSomeFreeVars,
idRuleVars, idFreeVars, idFreeTyVars,
- ruleSomeFreeVars, ruleRhsFreeVars,
- ruleLhsFreeNames, ruleLhsFreeIds,
+ ruleRhsFreeVars, ruleLhsFreeNames, ruleLhsFreeIds,
CoreExprWithFVs, -- = AnnExpr Id VarSet
CoreBindWithFVs, -- = AnnBind Id VarSet
where
rule_fvs = addBndrs tpl_vars (expr_fvs rhs)
-ruleSomeFreeVars :: InterestingVarFun -> CoreRule -> VarSet
-ruleSomeFreeVars interesting (BuiltinRule _ _) = noFVs
-ruleSomeFreeVars interesting (Rule _ _ tpl_vars tpl_args rhs)
- = rule_fvs interesting emptyVarSet
- where
- rule_fvs = addBndrs tpl_vars $
- foldr (union . expr_fvs) (expr_fvs rhs) tpl_args
-
ruleLhsFreeIds :: CoreRule -> VarSet
-- This finds all the free Ids on the LHS of the rule
-- *including* imported ids
import CmdLineOpts ( DynFlags, DynFlag(..), opt_OmitInterfacePragmas )
import CoreSyn
import CoreUnfold ( noUnfolding, mkTopUnfolding, okToUnfoldInHiFile )
-import CoreFVs ( ruleSomeFreeVars, exprSomeFreeVars )
+import CoreFVs ( ruleLhsFreeIds, ruleRhsFreeVars, exprSomeFreeVars )
import PprCore ( pprIdCoreRule )
import CoreLint ( showPass, endPass )
import CoreUtils ( exprArity )
; let ext_ids = findExternalSet binds_in orphans_in
; let ext_rules = findExternalRules binds_in orphans_in ext_ids
+ -- findExternalRules filters ext_rules to avoid binders that
+ -- aren't externally visible; but the externally-visible binders
+ -- are computed (by findExternalSet) assuming that all orphan
+ -- rules are exported. So in fact we may export more than we
+ -- need. (It's a sort of mutual recursion.)
-- We also make sure to avoid any exported binders. Consider
-- f{-u1-} = 1 -- Local decl
findExternalRules binds orphan_rules ext_ids
| opt_OmitInterfacePragmas = []
| otherwise
- = orphan_rules ++ local_rules
+ = filter needed_rule (orphan_rules ++ local_rules)
where
local_rules = [ (id, rule)
| id <- bindersOfBinds binds,
id `elemVarEnv` ext_ids,
- rule <- rulesRules (idSpecialisation id),
- not (isBuiltinRule rule)
- -- We can't print builtin rules in interface files
- -- Since they are built in, an importing module
- -- will have access to them anyway
+ rule <- rulesRules (idSpecialisation id)
]
+ needed_rule (id, rule)
+ = not (isBuiltinRule rule)
+ -- We can't print builtin rules in interface files
+ -- Since they are built in, an importing module
+ -- will have access to them anyway
+
+ && not (any internal_id (varSetElems (ruleLhsFreeIds rule)))
+ -- Don't export a rule whose LHS mentions an Id that
+ -- is completely internal (i.e. not visible to an
+ -- importing module)
+
+ internal_id id = isLocalId id && not (id `elemVarEnv` ext_ids)
\end{code}
%************************************************************************
= foldr find init_needed binds
where
orphan_rule_ids :: IdSet
- orphan_rule_ids = unionVarSets [ ruleSomeFreeVars isLocalId rule
+ orphan_rule_ids = unionVarSets [ ruleRhsFreeVars rule
| (_, rule) <- orphan_rules]
init_needed :: IdEnv Bool
init_needed = mapUFM (\_ -> False) orphan_rule_ids