+%************************************************************************
+%* *
+\subsection{Grabbing the old interface file and checking versions}
+%* *
+%************************************************************************
+
+\begin{code}
+checkOldIface :: GhciMode
+ -> DynFlags
+ -> HomeIfaceTable -> HomeSymbolTable
+ -> PersistentCompilerState
+ -> FilePath
+ -> Bool -- Source unchanged
+ -> Maybe ModIface -- Old interface from compilation manager, if any
+ -> IO (PersistentCompilerState, Bool, (RecompileRequired, Maybe ModIface))
+ -- True <=> errors happened
+
+checkOldIface ghci_mode dflags hit hst pcs iface_path source_unchanged maybe_iface
+ = runRn dflags hit hst pcs (panic "Bogus module") $
+
+ -- CHECK WHETHER THE SOURCE HAS CHANGED
+ ( if not source_unchanged then
+ traceHiDiffsRn (nest 4 (text "Source file changed or recompilation check turned off"))
+ else returnRn () ) `thenRn_`
+
+ -- If the source has changed and we're in interactive mode, avoid reading
+ -- an interface; just return the one we might have been supplied with.
+ if ghci_mode == Interactive && not source_unchanged then
+ returnRn (outOfDate, maybe_iface)
+ else
+
+ case maybe_iface of
+ Just old_iface -> -- Use the one we already have
+ setModuleRn (mi_module old_iface) (check_versions old_iface)
+
+ Nothing -- try and read it from a file
+ -> readIface iface_path `thenRn` \ read_result ->
+ case read_result of
+ Left err -> -- Old interface file not found, or garbled; give up
+ traceRn (text "Bad old interface file" $$ nest 4 err) `thenRn_`
+ returnRn (outOfDate, Nothing)
+
+ Right parsed_iface
+ -> setModuleRn (pi_mod parsed_iface) $
+ loadOldIface parsed_iface `thenRn` \ m_iface ->
+ check_versions m_iface
+ where
+ check_versions :: ModIface -> RnMG (RecompileRequired, Maybe ModIface)
+ check_versions iface
+ | not source_unchanged
+ = returnRn (outOfDate, Just iface)
+ | otherwise
+ = -- Check versions
+ recompileRequired iface_path iface `thenRn` \ recompile ->
+ returnRn (recompile, Just iface)
+\end{code}
+
+I think the following function should now have a more representative name,
+but what?
+
+\begin{code}
+loadOldIface :: ParsedIface -> RnMG ModIface
+
+loadOldIface parsed_iface
+ = let iface = parsed_iface
+ mod = pi_mod iface
+ in
+ initIfaceRnMS mod (
+ loadHomeDecls (pi_decls iface) `thenRn` \ decls ->
+ loadHomeRules (pi_rules iface) `thenRn` \ rules ->
+ loadHomeInsts (pi_insts iface) `thenRn` \ insts ->
+ returnRn (decls, rules, insts)
+ )
+ `thenRn` \ ((decls_vers, new_decls), (rule_vers, new_rules), new_insts) ->
+
+ mapRn loadHomeUsage (pi_usages iface) `thenRn` \ usages ->
+ loadExports (pi_exports iface) `thenRn` \ (export_vers, avails) ->
+ loadFixDecls mod (pi_fixity iface) `thenRn` \ fix_env ->
+ loadDeprecs mod (pi_deprecs iface) `thenRn` \ deprec_env ->
+ let
+ version = VersionInfo { vers_module = pi_vers iface,
+ vers_exports = export_vers,
+ vers_rules = rule_vers,
+ vers_decls = decls_vers }
+
+ decls = mkIfaceDecls new_decls new_rules new_insts
+
+ mod_iface = ModIface { mi_module = mod, mi_version = version,
+ mi_exports = avails, mi_usages = usages,
+ mi_boot = False, mi_orphan = pi_orphan iface,
+ mi_fixities = fix_env, mi_deprecs = deprec_env,
+ mi_decls = decls,
+ mi_globals = mkIfaceGlobalRdrEnv avails
+ }
+ in
+ returnRn mod_iface
+\end{code}
+
+\begin{code}
+loadHomeDecls :: [(Version, RdrNameTyClDecl)]
+ -> RnMS (NameEnv Version, [RenamedTyClDecl])
+loadHomeDecls decls = foldlRn loadHomeDecl (emptyNameEnv, []) decls
+
+loadHomeDecl :: (NameEnv Version, [RenamedTyClDecl])
+ -> (Version, RdrNameTyClDecl)
+ -> RnMS (NameEnv Version, [RenamedTyClDecl])
+loadHomeDecl (version_map, decls) (version, decl)
+ = rnTyClDecl decl `thenRn` \ decl' ->
+ returnRn (extendNameEnv version_map (tyClDeclName decl') version, decl':decls)
+
+------------------
+loadHomeRules :: (Version, [RdrNameRuleDecl])
+ -> RnMS (Version, [RenamedRuleDecl])
+loadHomeRules (version, rules)
+ = mapRn rnIfaceRuleDecl rules `thenRn` \ rules' ->
+ returnRn (version, rules')
+
+------------------
+loadHomeInsts :: [RdrNameInstDecl]
+ -> RnMS [RenamedInstDecl]
+loadHomeInsts insts = mapRn rnInstDecl insts
+
+------------------
+loadHomeUsage :: ImportVersion OccName
+ -> RnMG (ImportVersion Name)
+loadHomeUsage (mod_name, orphans, is_boot, whats_imported)
+ = rn_imps whats_imported `thenRn` \ whats_imported' ->
+ returnRn (mod_name, orphans, is_boot, whats_imported')
+ where
+ rn_imps NothingAtAll = returnRn NothingAtAll
+ rn_imps (Everything v) = returnRn (Everything v)
+ rn_imps (Specifically mv ev items rv) = mapRn rn_imp items `thenRn` \ items' ->
+ returnRn (Specifically mv ev items' rv)
+ rn_imp (occ,vers) = newGlobalName mod_name occ `thenRn` \ name ->
+ returnRn (name,vers)
+\end{code}
+
+
+
+%*********************************************************
+%* *
+\subsection{Closing up the interface decls}
+%* *
+%*********************************************************
+
+Suppose we discover we don't need to recompile. Then we start from the
+IfaceDecls in the ModIface, and fluff them up by sucking in all the decls they need.
+
+\begin{code}
+closeIfaceDecls :: DynFlags
+ -> HomeIfaceTable -> HomeSymbolTable
+ -> PersistentCompilerState
+ -> ModIface -- Get the decls from here
+ -> IO (PersistentCompilerState, Bool, [RenamedHsDecl])
+ -- True <=> errors happened
+closeIfaceDecls dflags hit hst pcs
+ mod_iface@(ModIface { mi_module = mod, mi_decls = iface_decls })
+ = runRn dflags hit hst pcs mod $
+
+ let
+ rule_decls = dcl_rules iface_decls
+ inst_decls = dcl_insts iface_decls
+ tycl_decls = dcl_tycl iface_decls
+ decls = map RuleD rule_decls ++
+ map InstD inst_decls ++
+ map TyClD tycl_decls
+ needed = unionManyNameSets (map ruleDeclFVs rule_decls) `unionNameSets`
+ unionManyNameSets (map instDeclFVs inst_decls) `unionNameSets`
+ unionManyNameSets (map tyClDeclFVs tycl_decls)
+ local_names = foldl add emptyNameSet tycl_decls
+ add names decl = addListToNameSet names (map fst (tyClDeclSysNames decl ++ tyClDeclNames decl))
+ in
+
+ recordLocalSlurps local_names `thenRn_`
+
+ -- Do the transitive closure
+ closeDecls decls (needed `plusFV` implicit_fvs) `thenRn` \closed_decls ->
+ rnDump [] closed_decls `thenRn_`
+ returnRn closed_decls
+ where
+ implicit_fvs = ubiquitousNames -- Data type decls with record selectors,
+ -- which may appear in the decls, need unpackCString
+ -- and friends. It's easier to just grab them right now.
+\end{code}
+