+\begin{code}
+typecheckIface
+ :: DynFlags
+ -> PersistentCompilerState
+ -> HomeSymbolTable
+ -> ModIface -- Iface for this module (just module & fixities)
+ -> (SyntaxMap, [RenamedHsDecl])
+ -> IO (Maybe (PersistentCompilerState, TypeEnv, [TypecheckedRuleDecl]))
+ -- The new PCS is Augmented with imported information,
+ -- (but not stuff from this module).
+ -- The TcResults returned contains only the environment
+ -- and rules.
+
+
+typecheckIface dflags pcs hst mod_iface (syn_map, decls)
+ = do { maybe_tc_stuff <- typecheck dflags syn_map pcs hst alwaysQualify $
+ tcIfaceImports pcs hst get_fixity this_mod decls
+ ; printIfaceDump dflags maybe_tc_stuff
+ ; return maybe_tc_stuff }
+ where
+ this_mod = mi_module mod_iface
+ fixity_env = mi_fixities mod_iface
+
+ get_fixity :: Name -> Maybe Fixity
+ get_fixity nm = lookupNameEnv fixity_env nm
+
+ tcIfaceImports pcs hst get_fixity this_mod decls
+ = fixTc (\ ~(unf_env, _, _, _, _) ->
+ tcImports unf_env pcs hst get_fixity this_mod decls
+ ) `thenTc` \ (env, new_pcs, local_inst_info,
+ deriv_binds, local_rules) ->
+ ASSERT(nullBinds deriv_binds)
+ let
+ local_things = filter (isLocalThing this_mod)
+ (nameEnvElts (getTcGEnv env))
+ local_type_env :: TypeEnv
+ local_type_env = mkTypeEnv local_things
+ in
+
+ -- throw away local_inst_info
+ returnTc (new_pcs, local_type_env, local_rules)
+
+
+tcImports :: RecTcEnv
+ -> PersistentCompilerState
+ -> HomeSymbolTable
+ -> (Name -> Maybe Fixity)
+ -> Module
+ -> [RenamedHsDecl]
+ -> TcM (TcEnv, PersistentCompilerState, [InstInfo],
+ RenamedHsBinds, [TypecheckedRuleDecl])
+
+-- tcImports is a slight mis-nomer.
+-- It deals with everythign that could be an import:
+-- type and class decls
+-- interface signatures
+-- instance decls
+-- rule decls
+-- These can occur in source code too, of course
+
+tcImports unf_env pcs hst get_fixity this_mod decls
+ -- (unf_env :: RecTcEnv) is used for type-checking interface pragmas
+ -- which is done lazily [ie failure just drops the pragma
+ -- without having any global-failure effect].
+ --
+ -- unf_env is also used to get the pragama info
+ -- for imported dfuns and default methods
+
+ = checkNoErrsTc $
+ -- tcImports recovers internally, but if anything gave rise to
+ -- an error we'd better stop now, to avoid a cascade
+
+ traceTc (text "Tc1") `thenNF_Tc_`
+ tcTyAndClassDecls unf_env tycl_decls `thenTc` \ env ->
+ tcSetEnv env $
+
+ -- Typecheck the instance decls, includes deriving
+ traceTc (text "Tc2") `thenNF_Tc_`
+ tcInstDecls1 (pcs_insts pcs) (pcs_PRS pcs)
+ hst unf_env get_fixity this_mod
+ decls `thenTc` \ (new_pcs_insts, inst_env, local_insts, deriv_binds) ->
+ tcSetInstEnv inst_env $
+
+ -- Interface type signatures
+ -- We tie a knot so that the Ids read out of interfaces are in scope
+ -- when we read their pragmas.
+ -- What we rely on is that pragmas are typechecked lazily; if
+ -- any type errors are found (ie there's an inconsistency)
+ -- we silently discard the pragma
+ traceTc (text "Tc3") `thenNF_Tc_`
+ tcInterfaceSigs unf_env tycl_decls `thenTc` \ sig_ids ->
+ tcExtendGlobalValEnv sig_ids $
+
+
+ tcIfaceRules (pcs_rules pcs) this_mod iface_rules `thenNF_Tc` \ (new_pcs_rules, local_rules) ->
+ -- When relinking this module from its interface-file decls
+ -- we'll have IfaceRules that are in fact local to this module
+ -- That's the reason we we get any local_rules out here
+
+ tcGetEnv `thenTc` \ unf_env ->