+-- May 2003:
+-- NOTE 1: careful about the side-effected EPS
+-- in the two tcExtendGlobalValueEnv calls
+-- NOTE 2: no point in tying the knot with fixM; all
+-- the important knot-tying comes via the PCS global variable
+
+tcInterfaceSigs decls =
+ zapEnv (fixM (tc_interface_sigs decls)) `thenM` \ (_,sig_ids) ->
+ -- The zapEnv dramatically trims the environment, solely
+ -- to plug the space leak that would otherwise be caused
+ -- by a rich environment bound into lots of lazy thunks
+ -- The thunks are the lazily-typechecked IdInfo of the
+ -- imported things.
+
+ tcExtendGlobalValEnv sig_ids getGblEnv `thenM` \ gbl_env ->
+ returnM gbl_env
+ -- 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
+ --
+ -- NOTE ALSO: the knot is in two parts:
+ -- * Ids defined in this module are added to the typechecker envt
+ -- which is knot-tied by the fixM.
+ -- * Imported Ids are side-effected into the PCS by the
+ -- tcExtendGlobalValueEnv, so they will be seen there provided
+ -- we don't look them up too early.
+ -- In both cases, we must defer lookups until after the knot is tied
+ --
+ -- We used to have a much bigger loop (in TcRnDriver), so that the
+ -- interface pragmas could mention variables bound in this module
+ -- (by mutual recn), but
+ -- (a) the knot is tiresomely big, and
+ -- (b) it black-holes when we have Template Haskell
+ --
+ -- For (b) consider: f = $(...h....)
+ -- where h is imported, and calls f via an hi-boot file.
+ -- This is bad! But it is not seen as a staging error, because h
+ -- is indeed imported. We don't want the type-checker to black-hole
+ -- when simplifying and compiling the splice!
+ --
+ -- Simple solution: discard any unfolding that mentions a variable
+ -- bound in this module (and hence not yet processed).
+ -- The discarding happens when forkM finds a type error.
+
+tc_interface_sigs decls ~(unf_env, _)
+ = sequenceM [do_one d | d@(IfaceSig {}) <- decls] `thenM` \ sig_ids ->
+ tcExtendGlobalValEnv sig_ids getGblEnv `thenM` \ gbl_env ->
+ returnM (gbl_env, sig_ids)