+\end{code}
+
+\begin{code}
+findExternalRules :: Bool -- Omit pragmas
+ -> [CoreBind]
+ -> [CoreRule] -- Local rules for imported fns
+ -> UnfoldEnv -- Ids that are exported, so we need their rules
+ -> [CoreRule]
+ -- The complete rules are gotten by combining
+ -- a) local rules for imported Ids
+ -- b) rules embedded in the top-level Ids
+findExternalRules omit_prags binds imp_id_rules unfold_env
+ | omit_prags = []
+ | otherwise = filterOut internal_rule (imp_id_rules ++ local_rules)
+ where
+ local_rules = [ rule
+ | id <- bindersOfBinds binds,
+ external_id id,
+ rule <- idCoreRules id
+ ]
+
+ internal_rule rule
+ = any (not . external_id) (varSetElems (ruleLhsFreeIds rule))
+ -- Don't export a rule whose LHS mentions a locally-defined
+ -- Id that is completely internal (i.e. not visible to an
+ -- importing module)
+
+ external_id id
+ | Just (name,_) <- lookupVarEnv unfold_env id = isExternalName name
+ | otherwise = False
+\end{code}
+
+Note [Which rules to expose]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+findExternalRules filters imp_rules to avoid binders that
+aren't externally visible; but the externally-visible binders
+are computed (by findExternalIds) assuming that all orphan
+rules are externalised (see init_ext_ids in function
+'search'). So in fact we may export more than we need.
+(It's a sort of mutual recursion.)
+
+%************************************************************************
+%* *
+\subsection{Step 2: top-level tidying}
+%* *
+%************************************************************************
+
+
+\begin{code}
+-- TopTidyEnv: when tidying we need to know
+-- * nc_var: The NameCache, containing a unique supply and any pre-ordained Names.
+-- These may have arisen because the
+-- renamer read in an interface file mentioning M.$wf, say,
+-- and assigned it unique r77. If, on this compilation, we've
+-- invented an Id whose name is $wf (but with a different unique)
+-- we want to rename it to have unique r77, so that we can do easy
+-- comparisons with stuff from the interface file
+--
+-- * occ_env: The TidyOccEnv, which tells us which local occurrences
+-- are 'used'
+--
+-- * subst_env: A Var->Var mapping that substitutes the new Var for the old
+
+tidyTopBinds :: HscEnv
+ -> UnfoldEnv
+ -> TidyOccEnv
+ -> [CoreBind]
+ -> (TidyEnv, [CoreBind])
+
+tidyTopBinds hsc_env unfold_env init_occ_env binds
+ = tidy init_env binds
+ where
+ init_env = (init_occ_env, emptyVarEnv)
+
+ this_pkg = thisPackage (hsc_dflags hsc_env)
+
+ tidy env [] = (env, [])
+ tidy env (b:bs) = let (env1, b') = tidyTopBind this_pkg unfold_env env b
+ (env2, bs') = tidy env1 bs
+ in
+ (env2, b':bs')
+
+------------------------
+tidyTopBind :: PackageId
+ -> UnfoldEnv
+ -> TidyEnv
+ -> CoreBind
+ -> (TidyEnv, CoreBind)
+
+tidyTopBind this_pkg unfold_env (occ_env,subst1) (NonRec bndr rhs)
+ = (tidy_env2, NonRec bndr' rhs')
+ where
+ Just (name',show_unfold) = lookupVarEnv unfold_env bndr
+ caf_info = hasCafRefs this_pkg subst1 (idArity bndr) rhs
+ (bndr', rhs') = tidyTopPair show_unfold tidy_env2 caf_info name' (bndr, rhs)
+ subst2 = extendVarEnv subst1 bndr bndr'
+ tidy_env2 = (occ_env, subst2)
+
+tidyTopBind this_pkg unfold_env (occ_env,subst1) (Rec prs)
+ = (tidy_env2, Rec prs')
+ where
+ prs' = [ tidyTopPair show_unfold tidy_env2 caf_info name' (id,rhs)
+ | (id,rhs) <- prs,
+ let (name',show_unfold) =
+ expectJust "tidyTopBind" $ lookupVarEnv unfold_env id
+ ]