+ = initIfaceTc iface $ \ tc_env_var -> do
+ -- The tc_env_var is freshly allocated, private to
+ -- type-checking this particular interface
+ { -- Get the right set of decls and rules. If we are compiling without -O
+ -- we discard pragmas before typechecking, so that we don't "see"
+ -- information that we shouldn't. From a versioning point of view
+ -- It's not actually *wrong* to do so, but in fact GHCi is unable
+ -- to handle unboxed tuples, so it must not see unfoldings.
+ ignore_prags <- doptM Opt_IgnoreInterfacePragmas
+
+ -- Load & typecheck the decls
+ ; decl_things <- loadDecls ignore_prags (mi_decls iface)
+
+ ; let type_env = mkNameEnv decl_things
+ ; writeMutVar tc_env_var type_env
+
+ -- Now do those rules and instances
+ ; let { rules | ignore_prags = []
+ | otherwise = mi_rules iface
+ ; dfuns = mi_insts iface
+ }
+ ; dfuns <- mapM tcIfaceInst dfuns
+ ; rules <- mapM tcIfaceRule rules
+
+ -- Exports
+ ; exports <- ifaceExportNames (mi_exports iface)
+
+ -- Finished
+ ; return (ModDetails { md_types = type_env,
+ md_insts = dfuns,
+ md_rules = rules,
+ md_exports = exports })
+ }
+\end{code}
+
+
+%************************************************************************
+%* *
+ Type and class declarations
+%* *
+%************************************************************************
+
+\begin{code}
+tcHiBootIface :: Module -> TcRn ModDetails
+-- Load the hi-boot iface for the module being compiled,
+-- if it indeed exists in the transitive closure of imports
+-- Return the ModDetails, empty if no hi-boot iface
+tcHiBootIface mod
+ = do { traceIf (text "loadHiBootInterface" <+> ppr mod)
+
+ ; mode <- getGhciMode
+ ; if not (isOneShot mode)
+ -- In --make and interactive mode, if this module has an hs-boot file
+ -- we'll have compiled it already, and it'll be in the HPT
+ --
+ -- We check wheher the interface is a *boot* interface.
+ -- It can happen (when using GHC from Visual Studio) that we
+ -- compile a module in TypecheckOnly mode, with a stable,
+ -- fully-populated HPT. In that case the boot interface isn't there
+ -- (it's been replaced by the mother module) so we can't check it.
+ -- And that's fine, because if M's ModInfo is in the HPT, then
+ -- it's been compiled once, and we don't need to check the boot iface
+ then do { hpt <- getHpt
+ ; case lookupModuleEnv hpt mod of
+ Just info | mi_boot (hm_iface info)
+ -> return (hm_details info)
+ other -> return emptyModDetails }
+ else do
+
+ -- OK, so we're in one-shot mode.
+ -- In that case, we're read all the direct imports by now,
+ -- so eps_is_boot will record if any of our imports mention us by
+ -- way of hi-boot file
+ { eps <- getEps
+ ; case lookupModuleEnv (eps_is_boot eps) mod of {
+ Nothing -> return emptyModDetails ; -- The typical case
+
+ Just (_, False) -> failWithTc moduleLoop ;
+ -- Someone below us imported us!
+ -- This is a loop with no hi-boot in the way
+
+ Just (mod, True) -> -- There's a hi-boot interface below us
+
+ do { read_result <- findAndReadIface
+ True -- Explicit import?
+ need mod
+ True -- Hi-boot file
+
+ ; case read_result of
+ Failed err -> failWithTc (elaborate err)
+ Succeeded (iface, _path) -> typecheckIface iface
+ }}}}
+ where
+ need = ptext SLIT("Need the hi-boot interface for") <+> ppr mod
+ <+> ptext SLIT("to compare against the Real Thing")
+
+ moduleLoop = ptext SLIT("Circular imports: module") <+> quotes (ppr mod)
+ <+> ptext SLIT("depends on itself")
+
+ elaborate err = hang (ptext SLIT("Could not find hi-boot interface for") <+>
+ quotes (ppr mod) <> colon) 4 err