+\subsection{Write a new interface file}
+%* *
+%************************************************************************
+
+\begin{code}
+mkFinalTypeEnv :: TypeEnv -- From typechecker
+ -> [Id] -- Final Ids
+ -> TypeEnv
+
+mkFinalTypeEnv type_env final_ids
+ = extendTypeEnvList (filterNameEnv keep_it type_env)
+ (map AnId final_ids)
+ where
+ -- The competed type environment is gotten from
+ -- a) keeping the types and classes
+ -- b) removing all Ids,
+ -- c) adding Ids with correct IdInfo, including unfoldings,
+ -- gotten from the bindings
+ -- From (c) we keep only those Ids with Global names;
+ -- the CoreTidy pass makes sure these are all and only
+ -- the externally-accessible ones
+ -- This truncates the type environment to include only the
+ -- exported Ids and things needed from them, which saves space
+ --
+ -- However, we do keep things like constructors, which should not appear
+ -- in interface files, because they are needed by importing modules when
+ -- using the compilation manager
+
+ -- We keep implicit Ids, because they won't appear
+ -- in the bindings from which final_ids are derived!
+ keep_it (AnId id) = isImplicitId id -- Remove all Ids except implicit ones
+ keep_it other = True -- Keep all TyCons and Classes
+\end{code}
+
+\begin{code}
+findExternalRules :: [CoreBind]
+ -> [IdCoreRule] -- Orphan rules
+ -> IdEnv a -- Ids that are exported, so we need their rules
+ -> [IdCoreRule]
+ -- The complete rules are gotten by combining
+ -- a) the orphan rules
+ -- b) rules embedded in the top-level Ids
+findExternalRules binds orphan_rules ext_ids
+ | opt_OmitInterfacePragmas = []
+ | otherwise
+ = filter needed_rule (orphan_rules ++ local_rules)
+ where
+ local_rules = [ rule
+ | id <- bindersOfBinds binds,
+ id `elemVarEnv` ext_ids,
+ rule <- idCoreRules 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}
+
+%************************************************************************
+%* *