2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
7 mkUsageInfo, -- Construct the usage info for a module
9 mkIface, -- Build a ModIface from a ModGuts,
10 -- including computing version information
12 writeIfaceFile, -- Write the interface file
14 checkOldIface -- See if recompilation is required, by
15 -- comparing version information
19 -----------------------------------------------
20 MkIface.lhs deals with versioning
21 -----------------------------------------------
23 Here's the version-related info in an interface file
25 module Foo 8 -- module-version
26 3 -- export-list-version
28 Usages: -- Version info for what this compilation of Foo imported
29 Baz 3 -- Module version
30 [4] -- The export-list version if Foo depended on it
31 (g,2) -- Function and its version
32 (T,1) -- Type and its version
34 <version> f :: Int -> Int {- Unfolding: \x -> Wib.t[2] x -}
35 -- The [2] says that f's unfolding
36 -- mentions verison 2 of Wib.t
38 -----------------------------------------------
40 -----------------------------------------------
43 * In the mi_usages information in an interface, we record the
44 version number of each free variable of the module
46 * In mkIface, we compute the version number of each exported thing A.f
47 by comparing its A.f's info with its new info, and bumping its
48 version number if it differs. If A.f mentions B.g, and B.g's version
49 number has changed, then we count A.f as having changed too.
51 * In checkOldIface we compare the mi_usages for the module with
52 the actual version info for all each thing recorded in mi_usages
57 We count A.f as changing if its fixity changes
61 If a rule changes, we want to recompile any module that might be
62 affected by that rule. For non-orphan rules, this is relatively easy.
63 If module M defines f, and a rule for f, just arrange that the version
64 number for M.f changes if any of the rules for M.f change. Any module
65 that does not depend on M.f can't be affected by the rule-change
68 Orphan rules (ones whose 'head function' is not defined in M) are
69 harder. Here's what we do.
71 * We have a per-module orphan-rule version number which changes if
72 any orphan rule changes. (It's unaffected by non-orphan rules.)
74 * We record usage info for any orphan module 'below' this one,
75 giving the orphan-rule version number. We recompile if this
78 The net effect is that if an orphan rule changes, we recompile every
79 module above it. That's very conservative, but it's devilishly hard
80 to know what it might affect, so we just have to be conservative.
84 In an iface file we have
86 instance Eq a => Eq [a] = dfun29
89 We have a version number for dfun29, covering its unfolding
90 etc. Suppose we are compiling a module M that imports A only
91 indirectly. If typechecking M uses this instance decl, we record the
92 dependency on A.dfun29 as if it were a free variable of the module
93 (via the tcg_inst_usages accumulator). That means that A will appear
94 in M's usage list. If the shape of the instance declaration changes,
95 then so will dfun29's version, triggering a recompilation.
97 Adding an instance declaration, or changing an instance decl that is
98 not currently used, is more tricky. (This really only makes a
99 difference when we have overlapping instance decls, because then the
100 new instance decl might kick in to override the old one.) We handle
101 this in a very similar way that we handle rules above.
103 * For non-orphan instance decls, identify one locally-defined tycon/class
104 mentioned in the decl. Treat the instance decl as part of the defn of that
105 tycon/class, so that if the shape of the instance decl changes, so does the
106 tycon/class; that in turn will force recompilation of anything that uses
109 * For orphan instance decls, act the same way as for orphan rules.
110 Indeed, we use the same global orphan-rule version number.
114 mkUsageInfo figures out what the ``usage information'' for this
115 moudule is; that is, what it must record in its interface file as the
118 We produce a line for every module B below the module, A, currently being
121 to record the fact that A does import B indirectly. This is used to decide
122 to look to look for B.hi rather than B.hi-boot when compiling a module that
123 imports A. This line says that A imports B, but uses nothing in it.
124 So we'll get an early bale-out when compiling A if B's version changes.
126 The usage information records:
129 \item (a) anything reachable from its body code
130 \item (b) any module exported with a @module Foo@
131 \item (c) anything reachable from an exported item
134 Why (b)? Because if @Foo@ changes then this module's export list
135 will change, so we must recompile this module at least as far as
136 making a new interface file --- but in practice that means complete
139 Why (c)? Consider this:
141 module A( f, g ) where | module B( f ) where
142 import B( f ) | f = h 3
146 Here, @B.f@ isn't used in A. Should we nevertheless record @B.f@ in
147 @A@'s usages? Our idea is that we aren't going to touch A.hi if it is
148 *identical* to what it was before. If anything about @B.f@ changes
149 than anyone who imports @A@ should be recompiled in case they use
150 @B.f@ (they'll get an early exit if they don't). So, if anything
151 about @B.f@ changes we'd better make sure that something in A.hi
152 changes, and the convenient way to do that is to record the version
153 number @B.f@ in A.hi in the usage list. If B.f changes that'll force a
154 complete recompiation of A, which is overkill but it's the only way to
155 write a new, slightly different, A.hi.
157 But the example is tricker. Even if @B.f@ doesn't change at all,
158 @B.h@ may do so, and this change may not be reflected in @f@'s version
159 number. But with -O, a module that imports A must be recompiled if
160 @B.h@ changes! So A must record a dependency on @B.h@. So we treat
161 the occurrence of @B.f@ in the export list *just as if* it were in the
162 code of A, and thereby haul in all the stuff reachable from it.
164 *** Conclusion: if A mentions B.f in its export list,
165 behave just as if A mentioned B.f in its source code,
166 and slurp in B.f and all its transitive closure ***
168 [NB: If B was compiled with -O, but A isn't, we should really *still*
169 haul in all the unfoldings for B, in case the module that imports A *is*
170 compiled with -O. I think this is the case.]
174 #include "HsVersions.h"
176 import IfaceSyn -- All of it
177 import IfaceType ( toIfaceTvBndrs, toIfaceType, toIfaceContext )
178 import LoadIface ( readIface, loadInterface, pprModIface )
179 import Id ( Id, idName, idType, idInfo, idArity, isDataConWorkId_maybe, isFCallId_maybe )
180 import IdInfo ( IdInfo, CafInfo(..), WorkerInfo(..),
181 arityInfo, cafInfo, newStrictnessInfo,
182 workerInfo, unfoldingInfo, inlinePragInfo )
183 import NewDemand ( isTopSig )
185 import Class ( classExtraBigSig, classTyCon )
186 import TyCon ( TyCon, AlgTyConRhs(..), isRecursiveTyCon, isForeignTyCon,
187 isSynTyCon, isAlgTyCon, isPrimTyCon, isFunTyCon,
188 isTupleTyCon, tupleTyConBoxity, tyConStupidTheta,
189 tyConHasGenerics, tyConArgVrcs, synTyConRhs, isGadtSyntaxTyCon,
190 tyConArity, tyConTyVars, algTyConRhs, tyConExtName )
191 import DataCon ( dataConName, dataConFieldLabels, dataConStrictMarks,
192 dataConTyCon, dataConIsInfix, dataConUnivTyVars, dataConExTyVars, dataConEqSpec,
193 dataConTheta, dataConOrigArgTys )
194 import Type ( TyThing(..), splitForAllTys, funResultTy )
195 import TcType ( deNoteType )
196 import TysPrim ( alphaTyVars )
197 import InstEnv ( Instance(..) )
199 import HscTypes ( ModIface(..), ModDetails(..),
200 ModSummary(..), msHiFilePath,
201 mkIfaceDepCache, mkIfaceFixCache, mkIfaceVerCache,
203 GenAvailInfo(..), availName,
204 ExternalPackageState(..),
205 Usage(..), IsBootInterface,
206 Deprecs(..), IfaceDeprecs, Deprecations,
211 import DynFlags ( GhcMode(..), DynFlag(..), dopt )
212 import Name ( Name, nameModule, nameOccName, nameParent,
213 isExternalName, isInternalName, nameParent_maybe, isWiredInName,
214 isImplicitName, NamedThing(..) )
217 import OccName ( OccName, OccEnv, mkOccEnv, lookupOccEnv, emptyOccEnv,
219 OccSet, emptyOccSet, elemOccSet, occSetElts,
220 extendOccSet, extendOccSetList,
221 isEmptyOccSet, intersectOccSet, intersectsOccSet,
225 import BasicTypes ( Version, initialVersion, bumpVersion, isAlwaysActive,
226 Activation(..), RecFlag(..), boolToRecFlag )
228 import Util ( createDirectoryHierarchy, directoryOf, sortLe, seqList, lengthIs )
229 import BinIface ( writeBinIface )
230 import Unique ( Unique, Uniquable(..) )
231 import ErrUtils ( dumpIfSet_dyn, showPass )
232 import Digraph ( stronglyConnComp, SCC(..) )
233 import SrcLoc ( SrcSpan )
235 import PackageConfig ( PackageId )
239 import Monad ( when )
240 import List ( insert )
241 import Maybes ( orElse, mapCatMaybes, isNothing, isJust,
242 expectJust, catMaybes, MaybeErr(..) )
247 %************************************************************************
249 \subsection{Completing an interface}
251 %************************************************************************
255 -> Maybe ModIface -- The old interface, if we have it
256 -> ModGuts -- Usages, deprecations, etc
257 -> ModDetails -- The trimmed, tidied interface
258 -> IO (ModIface, -- The new one, complete with decls and versions
259 Bool) -- True <=> there was an old Iface, and the new one
260 -- is identical, so no need to write it
262 mkIface hsc_env maybe_old_iface
263 (ModGuts{ mg_module = this_mod,
267 mg_rdr_env = rdr_env,
268 mg_fix_env = fix_env,
269 mg_deprecs = src_deprecs })
270 (ModDetails{ md_insts = insts,
273 md_exports = exports })
275 -- NB: notice that mkIface does not look at the bindings
276 -- only at the TypeEnv. The previous Tidy phase has
277 -- put exactly the info into the TypeEnv that we want
278 -- to expose in the interface
280 = do { eps <- hscEPS hsc_env
281 ; let { ext_nm_rhs = mkExtNameFn hsc_env eps this_mod
282 ; ext_nm_lhs = mkLhsNameFn this_mod
284 ; decls = [ tyThingToIfaceDecl ext_nm_rhs thing
285 | thing <- typeEnvElts type_env,
286 let name = getName thing,
287 not (isImplicitName name || isWiredInName name) ]
288 -- Don't put implicit Ids and class tycons in the interface file
289 -- Nor wired-in things; the compiler knows about them anyhow
291 ; fixities = [(occ,fix) | FixItem occ fix _ <- nameEnvElts fix_env]
292 ; deprecs = mkIfaceDeprec src_deprecs
293 ; iface_rules = map (coreRuleToIfaceRule ext_nm_lhs ext_nm_rhs) rules
294 ; iface_insts = map (instanceToIfaceInst ext_nm_lhs) insts
296 ; intermediate_iface = ModIface {
297 mi_module = this_mod,
301 mi_exports = mkIfaceExports exports,
302 mi_insts = sortLe le_inst iface_insts,
303 mi_rules = sortLe le_rule iface_rules,
304 mi_fixities = fixities,
305 mi_deprecs = deprecs,
306 mi_globals = Just rdr_env,
308 -- Left out deliberately: filled in by addVersionInfo
309 mi_mod_vers = initialVersion,
310 mi_exp_vers = initialVersion,
311 mi_rule_vers = initialVersion,
312 mi_orphan = False, -- Always set by addVersionInfo, but
313 -- it's a strict field, so we can't omit it.
314 mi_decls = deliberatelyOmitted "decls",
315 mi_ver_fn = deliberatelyOmitted "ver_fn",
317 -- And build the cached values
318 mi_dep_fn = mkIfaceDepCache deprecs,
319 mi_fix_fn = mkIfaceFixCache fixities }
321 -- Add version information
322 ; (new_iface, no_change_at_all, pp_diffs, pp_orphs)
323 = _scc_ "versioninfo"
324 addVersionInfo maybe_old_iface intermediate_iface decls
328 ; when (isJust pp_orphs && dopt Opt_WarnOrphans dflags)
329 (printDump (expectJust "mkIface" pp_orphs))
330 ; when (dopt Opt_D_dump_hi_diffs dflags) (printDump pp_diffs)
331 ; dumpIfSet_dyn dflags Opt_D_dump_hi "FINAL INTERFACE"
332 (pprModIface new_iface)
334 ; return (new_iface, no_change_at_all) }
336 r1 `le_rule` r2 = ifRuleName r1 <= ifRuleName r2
337 i1 `le_inst` i2 = ifDFun i1 <= ifDFun i2
339 dflags = hsc_dflags hsc_env
340 deliberatelyOmitted x = panic ("Deliberately omitted: " ++ x)
343 -----------------------------
344 writeIfaceFile :: ModLocation -> ModIface -> IO ()
345 writeIfaceFile location new_iface
346 = do createDirectoryHierarchy (directoryOf hi_file_path)
347 writeBinIface hi_file_path new_iface
348 where hi_file_path = ml_hi_file location
351 -----------------------------
352 mkExtNameFn :: HscEnv -> ExternalPackageState -> Module -> Name -> IfaceExtName
353 mkExtNameFn hsc_env eps this_mod
356 hpt = hsc_HPT hsc_env
360 | mod == this_mod = case nameParent_maybe name of
361 Nothing -> LocalTop occ
362 Just par -> LocalTopSub occ (nameOccName par)
363 | isWiredInName name = ExtPkg mod occ
364 | is_home mod = HomePkg mod_name occ vers
365 | otherwise = ExtPkg mod occ
367 dflags = hsc_dflags hsc_env
368 this_pkg = thisPackage dflags
369 is_home mod = modulePackageId mod == this_pkg
371 mod = nameModule name
372 mod_name = moduleName mod
373 occ = nameOccName name
374 par_occ = nameOccName (nameParent name)
375 -- The version of the *parent* is the one want
376 vers = lookupVersion mod par_occ
378 lookupVersion :: Module -> OccName -> Version
379 -- Even though we're looking up a home-package thing, in
380 -- one-shot mode the imported interfaces may be in the PIT
381 lookupVersion mod occ
382 = mi_ver_fn iface occ `orElse`
383 pprPanic "lookupVers1" (ppr mod <+> ppr occ)
385 iface = lookupIfaceByModule (hsc_dflags hsc_env) hpt pit mod `orElse`
386 pprPanic "lookupVers2" (ppr mod <+> ppr occ)
389 ---------------------
390 -- mkLhsNameFn ignores versioning info altogether
391 -- It is used for the LHS of instance decls and rules, where we
392 -- there's no point in recording version info
393 mkLhsNameFn :: Module -> Name -> IfaceExtName
394 mkLhsNameFn this_mod name
395 | isInternalName name = pprTrace "mkLhsNameFn: unexpected internal" (ppr name) $
396 LocalTop occ -- Should not happen
397 | mod == this_mod = LocalTop occ
398 | otherwise = ExtPkg mod occ
400 mod = nameModule name
401 occ = nameOccName name
404 -----------------------------
405 -- Compute version numbers for local decls
407 addVersionInfo :: Maybe ModIface -- The old interface, read from M.hi
408 -> ModIface -- The new interface decls (lacking decls)
409 -> [IfaceDecl] -- The new decls
411 Bool, -- True <=> no changes at all; no need to write new Iface
413 Maybe SDoc) -- Warnings about orphans
415 addVersionInfo Nothing new_iface new_decls
416 -- No old interface, so definitely write a new one!
417 = (new_iface { mi_orphan = anyNothing ifInstOrph (mi_insts new_iface)
418 || anyNothing ifRuleOrph (mi_rules new_iface),
419 mi_decls = [(initialVersion, decl) | decl <- new_decls],
420 mi_ver_fn = \n -> Just initialVersion },
422 ptext SLIT("No old interface file"),
423 pprOrphans orph_insts orph_rules)
425 orph_insts = filter (isNothing . ifInstOrph) (mi_insts new_iface)
426 orph_rules = filter (isNothing . ifRuleOrph) (mi_rules new_iface)
428 addVersionInfo (Just old_iface@(ModIface { mi_mod_vers = old_mod_vers,
429 mi_exp_vers = old_exp_vers,
430 mi_rule_vers = old_rule_vers,
431 mi_decls = old_decls,
432 mi_ver_fn = old_decl_vers,
433 mi_fix_fn = old_fixities }))
434 new_iface@(ModIface { mi_fix_fn = new_fixities })
437 | no_change_at_all = (old_iface, True, ptext SLIT("Interface file unchanged"), pp_orphs)
438 | otherwise = (final_iface, False, vcat [ptext SLIT("Interface file has changed"),
439 nest 2 pp_diffs], pp_orphs)
441 final_iface = new_iface { mi_mod_vers = bump_unless no_output_change old_mod_vers,
442 mi_exp_vers = bump_unless no_export_change old_exp_vers,
443 mi_rule_vers = bump_unless no_rule_change old_rule_vers,
444 mi_orphan = not (null new_orph_rules && null new_orph_insts),
445 mi_decls = decls_w_vers,
446 mi_ver_fn = mkIfaceVerCache decls_w_vers }
448 decls_w_vers = [(add_vers decl, decl) | decl <- new_decls]
451 (old_non_orph_insts, old_orph_insts) = mkOrphMap ifInstOrph (mi_insts old_iface)
452 (new_non_orph_insts, new_orph_insts) = mkOrphMap ifInstOrph (mi_insts new_iface)
453 same_insts occ = eqMaybeBy (eqListBy eqIfInst)
454 (lookupOccEnv old_non_orph_insts occ)
455 (lookupOccEnv new_non_orph_insts occ)
457 (old_non_orph_rules, old_orph_rules) = mkOrphMap ifRuleOrph (mi_rules old_iface)
458 (new_non_orph_rules, new_orph_rules) = mkOrphMap ifRuleOrph (mi_rules new_iface)
459 same_rules occ = eqMaybeBy (eqListBy eqIfRule)
460 (lookupOccEnv old_non_orph_rules occ)
461 (lookupOccEnv new_non_orph_rules occ)
463 -- Computing what changed
464 no_output_change = no_decl_change && no_rule_change &&
465 no_export_change && no_deprec_change
466 no_export_change = mi_exports new_iface == mi_exports old_iface -- Kept sorted
467 no_decl_change = isEmptyOccSet changed_occs
468 no_rule_change = not (changedWrt changed_occs (eqListBy eqIfRule old_orph_rules new_orph_rules)
469 || changedWrt changed_occs (eqListBy eqIfInst old_orph_insts new_orph_insts))
470 no_deprec_change = mi_deprecs new_iface == mi_deprecs old_iface
472 -- If the usages havn't changed either, we don't need to write the interface file
473 no_other_changes = mi_usages new_iface == mi_usages old_iface &&
474 mi_deps new_iface == mi_deps old_iface
475 no_change_at_all = no_output_change && no_other_changes
477 pp_diffs = vcat [pp_change no_export_change "Export list"
478 (ppr old_exp_vers <+> arrow <+> ppr (mi_exp_vers final_iface)),
479 pp_change no_rule_change "Rules"
480 (ppr old_rule_vers <+> arrow <+> ppr (mi_rule_vers final_iface)),
481 pp_change no_deprec_change "Deprecations" empty,
482 pp_change no_other_changes "Usages" empty,
484 pp_change True what info = empty
485 pp_change False what info = text what <+> ptext SLIT("changed") <+> info
488 old_decl_env = mkOccEnv [(ifName decl, decl) | (_,decl) <- old_decls]
489 same_fixity n = bool (old_fixities n == new_fixities n)
492 -- Adding version info
493 new_version = bumpVersion old_mod_vers -- Start from the old module version, not from zero
494 -- so that if you remove f, and then add it again,
495 -- you don't thereby reduce f's version number
496 add_vers decl | occ `elemOccSet` changed_occs = new_version
497 | otherwise = expectJust "add_vers" (old_decl_vers occ)
498 -- If it's unchanged, there jolly well
499 where -- should be an old version number
503 changed_occs :: OccSet
504 changed_occs = computeChangedOccs eq_info
506 eq_info :: [(OccName, IfaceEq)]
507 eq_info = map check_eq new_decls
508 check_eq new_decl | Just old_decl <- lookupOccEnv old_decl_env occ
509 = (occ, new_decl `eqIfDecl` old_decl &&&
510 eq_indirects new_decl)
511 | otherwise {- No corresponding old decl -}
514 occ = ifName new_decl
516 eq_indirects :: IfaceDecl -> IfaceEq
517 -- When seeing if two decls are the same, remember to
518 -- check whether any relevant fixity or rules have changed
519 eq_indirects (IfaceId {ifName = occ}) = eq_ind_occ occ
520 eq_indirects (IfaceClass {ifName = cls_occ, ifSigs = sigs})
521 = same_insts cls_occ &&&
522 eq_ind_occs [op | IfaceClassOp op _ _ <- sigs]
523 eq_indirects (IfaceData {ifName = tc_occ, ifCons = cons})
524 = same_insts tc_occ &&& same_fixity tc_occ &&& -- The TyCon can have a fixity too
525 eq_ind_occs (map ifConOcc (visibleIfConDecls cons))
526 eq_indirects other = Equal -- Synonyms and foreign declarations
528 eq_ind_occ :: OccName -> IfaceEq -- For class ops and Ids; check fixity and rules
529 eq_ind_occ occ = same_fixity occ &&& same_rules occ
530 eq_ind_occs = foldr ((&&&) . eq_ind_occ) Equal
534 pp_decl_diffs :: SDoc -- Nothing => no changes
536 | isEmptyOccSet changed_occs = empty
538 = vcat [ptext SLIT("Changed occs:") <+> ppr (occSetElts changed_occs),
539 ptext SLIT("Version change for these decls:"),
540 nest 2 (vcat (map show_change new_decls))]
542 eq_env = mkOccEnv eq_info
544 | not (occ `elemOccSet` changed_occs) = empty
546 = vcat [ppr occ <+> ppr (old_decl_vers occ) <+> arrow <+> ppr new_version,
549 occ = ifName new_decl
550 why = case lookupOccEnv eq_env occ of
551 Just (EqBut occs) -> sep [ppr occ <> colon, ptext SLIT("Free vars (only) changed:"),
552 nest 2 (braces (fsep (map ppr (occSetElts
553 (occs `intersectOccSet` changed_occs)))))]
555 | Just old_decl <- lookupOccEnv old_decl_env occ
556 -> vcat [ptext SLIT("Old:") <+> ppr old_decl,
557 ptext SLIT("New:") <+> ppr new_decl]
559 -> ppr occ <+> ptext SLIT("only in new interface")
560 other -> pprPanic "MkIface.show_change" (ppr occ)
562 pp_orphs = pprOrphans new_orph_insts new_orph_rules
564 pprOrphans insts rules
565 | null insts && null rules = Nothing
568 if null insts then empty else
569 hang (ptext SLIT("Warning: orphan instances:"))
570 2 (vcat (map ppr insts)),
571 if null rules then empty else
572 hang (ptext SLIT("Warning: orphan rules:"))
573 2 (vcat (map ppr rules))
576 computeChangedOccs :: [(OccName, IfaceEq)] -> OccSet
577 computeChangedOccs eq_info
578 = foldl add_changes emptyOccSet (stronglyConnComp edges)
580 edges :: [((OccName,IfaceEq), Unique, [Unique])]
581 edges = [ (node, getUnique occ, map getUnique occs)
582 | node@(occ, iface_eq) <- eq_info
583 , let occs = case iface_eq of
584 EqBut occ_set -> occSetElts occ_set
587 -- Changes in declarations
588 add_changes :: OccSet -> SCC (OccName, IfaceEq) -> OccSet
589 add_changes so_far (AcyclicSCC (occ, iface_eq))
590 | changedWrt so_far iface_eq -- This one has changed
591 = extendOccSet so_far occ
592 add_changes so_far (CyclicSCC pairs)
593 | changedWrt so_far (foldr1 (&&&) (map snd pairs)) -- One of this group has changed
594 = extendOccSetList so_far (map fst pairs)
595 add_changes so_far other = so_far
597 changedWrt :: OccSet -> IfaceEq -> Bool
598 changedWrt so_far Equal = False
599 changedWrt so_far NotEqual = True
600 changedWrt so_far (EqBut kids) = so_far `intersectsOccSet` kids
602 ----------------------
603 -- mkOrphMap partitions instance decls or rules into
604 -- (a) an OccEnv for ones that are not orphans,
605 -- mapping the local OccName to a list of its decls
606 -- (b) a list of orphan decls
607 mkOrphMap :: (decl -> Maybe OccName) -- (Just occ) for a non-orphan decl, keyed by occ
608 -- Nothing for an orphan decl
609 -> [decl] -- Sorted into canonical order
610 -> (OccEnv [decl], -- Non-orphan decls associated with their key;
611 -- each sublist in canonical order
612 [decl]) -- Orphan decls; in canonical order
613 mkOrphMap get_key decls
614 = foldl go (emptyOccEnv, []) decls
616 go (non_orphs, orphs) d
617 | Just occ <- get_key d
618 = (extendOccEnv_C (\ ds _ -> d:ds) non_orphs occ [d], orphs)
619 | otherwise = (non_orphs, d:orphs)
621 anyNothing :: (a -> Maybe b) -> [a] -> Bool
622 anyNothing p [] = False
623 anyNothing p (x:xs) = isNothing (p x) || anyNothing p xs
625 ----------------------
626 mkIfaceDeprec :: Deprecations -> IfaceDeprecs
627 mkIfaceDeprec NoDeprecs = NoDeprecs
628 mkIfaceDeprec (DeprecAll t) = DeprecAll t
629 mkIfaceDeprec (DeprecSome env) = DeprecSome (sortLe (<=) (nameEnvElts env))
631 ----------------------
632 bump_unless :: Bool -> Version -> Version
633 bump_unless True v = v -- True <=> no change
634 bump_unless False v = bumpVersion v
638 %*********************************************************
640 \subsection{Keeping track of what we've slurped, and version numbers}
642 %*********************************************************
646 mkUsageInfo :: HscEnv
647 -> ModuleEnv (Module, Bool, SrcSpan)
648 -> [(ModuleName, IsBootInterface)]
649 -> NameSet -> IO [Usage]
650 mkUsageInfo hsc_env dir_imp_mods dep_mods used_names
651 = do { eps <- hscEPS hsc_env
652 ; let usages = mk_usage_info (eps_PIT eps) hsc_env
653 dir_imp_mods dep_mods used_names
654 ; usages `seqList` return usages }
655 -- seq the list of Usages returned: occasionally these
656 -- don't get evaluated for a while and we can end up hanging on to
657 -- the entire collection of Ifaces.
659 mk_usage_info pit hsc_env dir_imp_mods dep_mods proto_used_names
660 = mapCatMaybes mkUsage dep_mods
661 -- ToDo: do we need to sort into canonical order?
663 hpt = hsc_HPT hsc_env
664 dflags = hsc_dflags hsc_env
666 used_names = mkNameSet $ -- Eliminate duplicates
667 [ nameParent n -- Just record usage on the 'main' names
668 | n <- nameSetToList proto_used_names
669 , not (isWiredInName n) -- Don't record usages for wired-in names
670 , isExternalName n -- Ignore internal names
673 -- ent_map groups together all the things imported and used
674 -- from a particular module in this package
675 ent_map :: ModuleEnv [OccName]
676 ent_map = foldNameSet add_mv emptyModuleEnv used_names
677 add_mv name mv_map = extendModuleEnv_C add_item mv_map mod [occ]
679 occ = nameOccName name
680 mod = nameModule name
681 add_item occs _ = occ:occs
683 depend_on_exports mod = case lookupModuleEnv dir_imp_mods mod of
684 Just (_,no_imp,_) -> not no_imp
687 -- We want to create a Usage for a home module if
688 -- a) we used something from; has something in used_names
689 -- b) we imported all of it, even if we used nothing from it
690 -- (need to recompile if its export list changes: export_vers)
691 -- c) is a home-package orphan module (need to recompile if its
692 -- instance decls change: rules_vers)
693 mkUsage :: (ModuleName, IsBootInterface) -> Maybe Usage
694 mkUsage (mod_name, _)
695 | isNothing maybe_iface -- We can't depend on it if we didn't
696 || (null used_occs -- load its interface.
697 && isNothing export_vers
699 = Nothing -- Record no usage info
702 = Just (Usage { usg_name = mod_name,
704 usg_exports = export_vers,
705 usg_entities = ent_vers,
706 usg_rules = rules_vers })
708 maybe_iface = lookupIfaceByModule dflags hpt pit mod
709 -- In one-shot mode, the interfaces for home-package
710 -- modules accumulate in the PIT not HPT. Sigh.
712 mod = mkModule (thisPackage dflags) mod_name
714 Just iface = maybe_iface
715 orphan_mod = mi_orphan iface
716 version_env = mi_ver_fn iface
717 mod_vers = mi_mod_vers iface
718 rules_vers = mi_rule_vers iface
719 export_vers | depend_on_exports mod = Just (mi_exp_vers iface)
720 | otherwise = Nothing
722 -- The sort is to put them into canonical order
723 used_occs = lookupModuleEnv ent_map mod `orElse` []
724 ent_vers :: [(OccName,Version)]
725 ent_vers = [ (occ, version_env occ `orElse` initialVersion)
726 | occ <- sortLe (<=) used_occs]
730 mkIfaceExports :: NameSet -> [(Module, [GenAvailInfo OccName])]
731 -- Group by module and sort by occurrence
732 -- This keeps the list in canonical order
733 mkIfaceExports exports
734 = [ (mod, eltsUFM avails)
735 | (mod, avails) <- fmToList groupFM
738 groupFM :: ModuleEnv (UniqFM (GenAvailInfo OccName))
739 -- Deliberately use the FastString so we
740 -- get a canonical ordering
741 groupFM = foldl add emptyModuleEnv (nameSetToList exports)
743 add env name = extendModuleEnv_C add_avail env mod
744 (unitUFM avail_fs avail)
746 occ = nameOccName name
747 mod = nameModule name
748 avail | Just p <- nameParent_maybe name = AvailTC (nameOccName p) [occ]
749 | isTcOcc occ = AvailTC occ [occ]
750 | otherwise = Avail occ
751 avail_fs = occNameFS (availName avail)
752 add_avail avail_fm _ = addToUFM_C add_item avail_fm avail_fs avail
754 add_item (AvailTC p occs) _ = AvailTC p (List.insert occ occs)
755 add_item (Avail n) _ = pprPanic "MkIface.addAvail" (ppr n <+> ppr name)
759 %************************************************************************
761 Load the old interface file for this module (unless
762 we have it aleady), and check whether it is up to date
765 %************************************************************************
768 checkOldIface :: HscEnv
770 -> Bool -- Source unchanged
771 -> Maybe ModIface -- Old interface from compilation manager, if any
772 -> IO (RecompileRequired, Maybe ModIface)
774 checkOldIface hsc_env mod_summary source_unchanged maybe_iface
775 = do { showPass (hsc_dflags hsc_env)
776 ("Checking old interface for " ++
777 showSDoc (ppr (ms_mod mod_summary))) ;
779 ; initIfaceCheck hsc_env $
780 check_old_iface hsc_env mod_summary source_unchanged maybe_iface
783 check_old_iface hsc_env mod_summary source_unchanged maybe_iface
784 = -- CHECK WHETHER THE SOURCE HAS CHANGED
785 ifM (not source_unchanged)
786 (traceHiDiffs (nest 4 (text "Source file changed or recompilation check turned off")))
789 -- If the source has changed and we're in interactive mode, avoid reading
790 -- an interface; just return the one we might have been supplied with.
791 getGhcMode `thenM` \ ghc_mode ->
792 if (ghc_mode == Interactive || ghc_mode == JustTypecheck)
793 && not source_unchanged then
794 returnM (outOfDate, maybe_iface)
797 case maybe_iface of {
798 Just old_iface -> do -- Use the one we already have
799 recomp <- checkVersions hsc_env source_unchanged old_iface
800 return (recomp, Just old_iface)
804 -- Try and read the old interface for the current module
805 -- from the .hi file left from the last time we compiled it
807 iface_path = msHiFilePath mod_summary
809 readIface (ms_mod mod_summary) iface_path False `thenM` \ read_result ->
810 case read_result of {
811 Failed err -> -- Old interface file not found, or garbled; give up
812 traceIf (text "FYI: cannot read old interface file:"
813 $$ nest 4 err) `thenM_`
814 returnM (outOfDate, Nothing)
818 -- We have got the old iface; check its versions
819 checkVersions hsc_env source_unchanged iface `thenM` \ recomp ->
820 returnM (recomp, Just iface)
824 @recompileRequired@ is called from the HscMain. It checks whether
825 a recompilation is required. It needs access to the persistent state,
826 finder, etc, because it may have to load lots of interface files to
827 check their versions.
830 type RecompileRequired = Bool
831 upToDate = False -- Recompile not required
832 outOfDate = True -- Recompile required
834 checkVersions :: HscEnv
835 -> Bool -- True <=> source unchanged
836 -> ModIface -- Old interface
837 -> IfG RecompileRequired
838 checkVersions hsc_env source_unchanged iface
839 | not source_unchanged
842 = do { traceHiDiffs (text "Considering whether compilation is required for" <+>
843 ppr (mi_module iface) <> colon)
845 -- Source code unchanged and no errors yet... carry on
847 -- First put the dependent-module info, read from the old interface, into the envt,
848 -- so that when we look for interfaces we look for the right one (.hi or .hi-boot)
850 -- It's just temporary because either the usage check will succeed
851 -- (in which case we are done with this module) or it'll fail (in which
852 -- case we'll compile the module from scratch anyhow).
854 -- We do this regardless of compilation mode
855 ; updateEps_ $ \eps -> eps { eps_is_boot = mod_deps }
857 ; let this_pkg = thisPackage (hsc_dflags hsc_env)
858 ; checkList [checkModUsage this_pkg u | u <- mi_usages iface]
861 -- This is a bit of a hack really
862 mod_deps :: ModuleNameEnv (ModuleName, IsBootInterface)
863 mod_deps = mkModDeps (dep_mods (mi_deps iface))
865 checkModUsage :: PackageId ->Usage -> IfG RecompileRequired
866 -- Given the usage information extracted from the old
867 -- M.hi file for the module being compiled, figure out
868 -- whether M needs to be recompiled.
870 checkModUsage this_pkg (Usage { usg_name = mod_name, usg_mod = old_mod_vers,
871 usg_rules = old_rule_vers,
872 usg_exports = maybe_old_export_vers,
873 usg_entities = old_decl_vers })
874 = -- Load the imported interface is possible
876 doc_str = sep [ptext SLIT("need version info for"), ppr mod_name]
878 traceHiDiffs (text "Checking usages for module" <+> ppr mod_name) `thenM_`
881 mod = mkModule this_pkg mod_name
883 loadInterface doc_str mod ImportBySystem `thenM` \ mb_iface ->
884 -- Load the interface, but don't complain on failure;
885 -- Instead, get an Either back which we can test
888 Failed exn -> (out_of_date (sep [ptext SLIT("Can't find version number for module"),
890 -- Couldn't find or parse a module mentioned in the
891 -- old interface file. Don't complain -- it might just be that
892 -- the current module doesn't need that import and it's been deleted
896 new_mod_vers = mi_mod_vers iface
897 new_decl_vers = mi_ver_fn iface
898 new_export_vers = mi_exp_vers iface
899 new_rule_vers = mi_rule_vers iface
902 checkModuleVersion old_mod_vers new_mod_vers `thenM` \ recompile ->
903 if not recompile then
908 if checkExportList maybe_old_export_vers new_export_vers then
909 out_of_date_vers (ptext SLIT(" Export list changed"))
910 (expectJust "checkModUsage" maybe_old_export_vers)
915 if old_rule_vers /= new_rule_vers then
916 out_of_date_vers (ptext SLIT(" Rules changed"))
917 old_rule_vers new_rule_vers
920 -- CHECK ITEMS ONE BY ONE
921 checkList [checkEntityUsage new_decl_vers u | u <- old_decl_vers] `thenM` \ recompile ->
923 returnM outOfDate -- This one failed, so just bail out now
925 up_to_date (ptext SLIT(" Great! The bits I use are up to date"))
928 ------------------------
929 checkModuleVersion old_mod_vers new_mod_vers
930 | new_mod_vers == old_mod_vers
931 = up_to_date (ptext SLIT("Module version unchanged"))
934 = out_of_date_vers (ptext SLIT(" Module version has changed"))
935 old_mod_vers new_mod_vers
937 ------------------------
938 checkExportList Nothing new_vers = upToDate
939 checkExportList (Just v) new_vers = v /= new_vers
941 ------------------------
942 checkEntityUsage new_vers (name,old_vers)
943 = case new_vers name of
945 Nothing -> -- We used it before, but it ain't there now
946 out_of_date (sep [ptext SLIT("No longer exported:"), ppr name])
948 Just new_vers -- It's there, but is it up to date?
949 | new_vers == old_vers -> traceHiDiffs (text " Up to date" <+> ppr name <+> parens (ppr new_vers)) `thenM_`
951 | otherwise -> out_of_date_vers (ptext SLIT(" Out of date:") <+> ppr name)
954 up_to_date msg = traceHiDiffs msg `thenM_` returnM upToDate
955 out_of_date msg = traceHiDiffs msg `thenM_` returnM outOfDate
956 out_of_date_vers msg old_vers new_vers
957 = out_of_date (hsep [msg, ppr old_vers, ptext SLIT("->"), ppr new_vers])
959 ----------------------
960 checkList :: [IfG RecompileRequired] -> IfG RecompileRequired
961 -- This helper is used in two places
962 checkList [] = returnM upToDate
963 checkList (check:checks) = check `thenM` \ recompile ->
970 %************************************************************************
972 Converting things to their Iface equivalents
974 %************************************************************************
977 tyThingToIfaceDecl :: (Name -> IfaceExtName) -> TyThing -> IfaceDecl
978 -- Assumption: the thing is already tidied, so that locally-bound names
979 -- (lambdas, for-alls) already have non-clashing OccNames
980 -- Reason: Iface stuff uses OccNames, and the conversion here does
981 -- not do tidying on the way
982 tyThingToIfaceDecl ext (AnId id)
983 = IfaceId { ifName = getOccName id,
984 ifType = toIfaceType ext (idType id),
987 info = case toIfaceIdInfo ext (idInfo id) of
989 items -> HasInfo items
991 tyThingToIfaceDecl ext (AClass clas)
992 = IfaceClass { ifCtxt = toIfaceContext ext sc_theta,
993 ifName = getOccName clas,
994 ifTyVars = toIfaceTvBndrs clas_tyvars,
995 ifFDs = map toIfaceFD clas_fds,
996 ifSigs = map toIfaceClassOp op_stuff,
997 ifRec = boolToRecFlag (isRecursiveTyCon tycon),
998 ifVrcs = tyConArgVrcs tycon }
1000 (clas_tyvars, clas_fds, sc_theta, _, op_stuff) = classExtraBigSig clas
1001 tycon = classTyCon clas
1003 toIfaceClassOp (sel_id, def_meth)
1004 = ASSERT(sel_tyvars == clas_tyvars)
1005 IfaceClassOp (getOccName sel_id) def_meth (toIfaceType ext op_ty)
1007 -- Be careful when splitting the type, because of things
1008 -- like class Foo a where
1009 -- op :: (?x :: String) => a -> a
1010 -- and class Baz a where
1011 -- op :: (Ord a) => a -> a
1012 (sel_tyvars, rho_ty) = splitForAllTys (idType sel_id)
1013 op_ty = funResultTy rho_ty
1015 toIfaceFD (tvs1, tvs2) = (map getOccName tvs1, map getOccName tvs2)
1017 tyThingToIfaceDecl ext (ATyCon tycon)
1019 = IfaceSyn { ifName = getOccName tycon,
1020 ifTyVars = toIfaceTvBndrs tyvars,
1021 ifVrcs = tyConArgVrcs tycon,
1022 ifSynRhs = toIfaceType ext syn_ty }
1025 = IfaceData { ifName = getOccName tycon,
1026 ifTyVars = toIfaceTvBndrs tyvars,
1027 ifCtxt = toIfaceContext ext (tyConStupidTheta tycon),
1028 ifCons = ifaceConDecls (algTyConRhs tycon),
1029 ifRec = boolToRecFlag (isRecursiveTyCon tycon),
1030 ifGadtSyntax = isGadtSyntaxTyCon tycon,
1031 ifVrcs = tyConArgVrcs tycon,
1032 ifGeneric = tyConHasGenerics tycon }
1034 | isForeignTyCon tycon
1035 = IfaceForeign { ifName = getOccName tycon,
1036 ifExtName = tyConExtName tycon }
1038 | isPrimTyCon tycon || isFunTyCon tycon
1039 -- Needed in GHCi for ':info Int#', for example
1040 = IfaceData { ifName = getOccName tycon,
1041 ifTyVars = toIfaceTvBndrs (take (tyConArity tycon) alphaTyVars),
1043 ifCons = IfAbstractTyCon,
1044 ifGadtSyntax = False,
1046 ifRec = NonRecursive,
1047 ifVrcs = tyConArgVrcs tycon }
1049 | otherwise = pprPanic "toIfaceDecl" (ppr tycon)
1051 tyvars = tyConTyVars tycon
1052 syn_ty = synTyConRhs tycon
1054 ifaceConDecls (NewTyCon { data_con = con }) = IfNewTyCon (ifaceConDecl con)
1055 ifaceConDecls (DataTyCon { data_cons = cons }) = IfDataTyCon (map ifaceConDecl cons)
1056 ifaceConDecls AbstractTyCon = IfAbstractTyCon
1057 -- The last case happens when a TyCon has been trimmed during tidying
1058 -- Furthermore, tyThingToIfaceDecl is also used
1059 -- in TcRnDriver for GHCi, when browsing a module, in which case the
1060 -- AbstractTyCon case is perfectly sensible.
1062 ifaceConDecl data_con
1063 = IfCon { ifConOcc = getOccName (dataConName data_con),
1064 ifConInfix = dataConIsInfix data_con,
1065 ifConUnivTvs = toIfaceTvBndrs (dataConUnivTyVars data_con),
1066 ifConExTvs = toIfaceTvBndrs (dataConExTyVars data_con),
1067 ifConEqSpec = to_eq_spec (dataConEqSpec data_con),
1068 ifConCtxt = toIfaceContext ext (dataConTheta data_con),
1069 ifConArgTys = map (toIfaceType ext) (dataConOrigArgTys data_con),
1070 ifConFields = map getOccName (dataConFieldLabels data_con),
1071 ifConStricts = dataConStrictMarks data_con }
1073 to_eq_spec spec = [(getOccName tv, toIfaceType ext ty) | (tv,ty) <- spec]
1075 tyThingToIfaceDecl ext (ADataCon dc)
1076 = pprPanic "toIfaceDecl" (ppr dc) -- Should be trimmed out earlier
1079 --------------------------
1080 instanceToIfaceInst :: (Name -> IfaceExtName) -> Instance -> IfaceInst
1081 instanceToIfaceInst ext_lhs ispec@(Instance { is_dfun = dfun_id, is_flag = oflag,
1082 is_cls = cls, is_tcs = mb_tcs,
1084 = IfaceInst { ifDFun = getOccName dfun_id,
1086 ifInstCls = ext_lhs cls,
1087 ifInstTys = map do_rough mb_tcs,
1090 do_rough Nothing = Nothing
1091 do_rough (Just n) = Just (toIfaceTyCon_name ext_lhs n)
1093 --------------------------
1094 toIfaceIdInfo :: (Name -> IfaceExtName) -> IdInfo -> [IfaceInfoItem]
1095 toIfaceIdInfo ext id_info
1096 = catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo,
1097 inline_hsinfo, wrkr_hsinfo, unfold_hsinfo]
1099 ------------ Arity --------------
1100 arity_info = arityInfo id_info
1101 arity_hsinfo | arity_info == 0 = Nothing
1102 | otherwise = Just (HsArity arity_info)
1104 ------------ Caf Info --------------
1105 caf_info = cafInfo id_info
1106 caf_hsinfo = case caf_info of
1107 NoCafRefs -> Just HsNoCafRefs
1110 ------------ Strictness --------------
1111 -- No point in explicitly exporting TopSig
1112 strict_hsinfo = case newStrictnessInfo id_info of
1113 Just sig | not (isTopSig sig) -> Just (HsStrictness sig)
1116 ------------ Worker --------------
1117 work_info = workerInfo id_info
1118 has_worker = case work_info of { HasWorker _ _ -> True; other -> False }
1119 wrkr_hsinfo = case work_info of
1120 HasWorker work_id wrap_arity ->
1121 Just (HsWorker (ext (idName work_id)) wrap_arity)
1124 ------------ Unfolding --------------
1125 -- The unfolding is redundant if there is a worker
1126 unfold_info = unfoldingInfo id_info
1127 rhs = unfoldingTemplate unfold_info
1128 no_unfolding = neverUnfold unfold_info
1129 -- The CoreTidy phase retains unfolding info iff
1130 -- we want to expose the unfolding, taking into account
1131 -- unconditional NOINLINE, etc. See TidyPgm.addExternal
1132 unfold_hsinfo | no_unfolding = Nothing
1133 | has_worker = Nothing -- Unfolding is implicit
1134 | otherwise = Just (HsUnfold (toIfaceExpr ext rhs))
1136 ------------ Inline prag --------------
1137 inline_prag = inlinePragInfo id_info
1138 inline_hsinfo | isAlwaysActive inline_prag = Nothing
1139 | no_unfolding && not has_worker = Nothing
1140 -- If the iface file give no unfolding info, we
1141 -- don't need to say when inlining is OK!
1142 | otherwise = Just (HsInline inline_prag)
1144 --------------------------
1145 coreRuleToIfaceRule :: (Name -> IfaceExtName) -- For the LHS names
1146 -> (Name -> IfaceExtName) -- For the RHS names
1147 -> CoreRule -> IfaceRule
1148 coreRuleToIfaceRule ext_lhs ext_rhs (BuiltinRule { ru_fn = fn})
1149 = pprTrace "toHsRule: builtin" (ppr fn) $
1150 bogusIfaceRule (mkIfaceExtName fn)
1152 coreRuleToIfaceRule ext_lhs ext_rhs
1153 (Rule { ru_name = name, ru_fn = fn, ru_act = act, ru_bndrs = bndrs,
1154 ru_args = args, ru_rhs = rhs, ru_orph = orph })
1155 = IfaceRule { ifRuleName = name, ifActivation = act,
1156 ifRuleBndrs = map (toIfaceBndr ext_lhs) bndrs,
1157 ifRuleHead = ext_lhs fn,
1158 ifRuleArgs = map do_arg args,
1159 ifRuleRhs = toIfaceExpr ext_rhs rhs,
1162 -- For type args we must remove synonyms from the outermost
1163 -- level. Reason: so that when we read it back in we'll
1164 -- construct the same ru_rough field as we have right now;
1166 do_arg (Type ty) = IfaceType (toIfaceType ext_lhs (deNoteType ty))
1167 do_arg arg = toIfaceExpr ext_lhs arg
1169 bogusIfaceRule :: IfaceExtName -> IfaceRule
1170 bogusIfaceRule id_name
1171 = IfaceRule { ifRuleName = FSLIT("bogus"), ifActivation = NeverActive,
1172 ifRuleBndrs = [], ifRuleHead = id_name, ifRuleArgs = [],
1173 ifRuleRhs = IfaceExt id_name, ifRuleOrph = Nothing }
1175 ---------------------
1176 toIfaceExpr :: (Name -> IfaceExtName) -> CoreExpr -> IfaceExpr
1177 toIfaceExpr ext (Var v) = toIfaceVar ext v
1178 toIfaceExpr ext (Lit l) = IfaceLit l
1179 toIfaceExpr ext (Type ty) = IfaceType (toIfaceType ext ty)
1180 toIfaceExpr ext (Lam x b) = IfaceLam (toIfaceBndr ext x) (toIfaceExpr ext b)
1181 toIfaceExpr ext (App f a) = toIfaceApp ext f [a]
1182 toIfaceExpr ext (Case s x ty as) = IfaceCase (toIfaceExpr ext s) (getOccName x) (toIfaceType ext ty) (map (toIfaceAlt ext) as)
1183 toIfaceExpr ext (Let b e) = IfaceLet (toIfaceBind ext b) (toIfaceExpr ext e)
1184 toIfaceExpr ext (Cast e co) = IfaceCast (toIfaceExpr ext e) (toIfaceType ext co)
1185 toIfaceExpr ext (Note n e) = IfaceNote (toIfaceNote ext n) (toIfaceExpr ext e)
1187 ---------------------
1188 toIfaceNote ext (SCC cc) = IfaceSCC cc
1189 toIfaceNote ext InlineMe = IfaceInlineMe
1190 toIfaceNote ext (CoreNote s) = IfaceCoreNote s
1192 ---------------------
1193 toIfaceBind ext (NonRec b r) = IfaceNonRec (toIfaceIdBndr ext b) (toIfaceExpr ext r)
1194 toIfaceBind ext (Rec prs) = IfaceRec [(toIfaceIdBndr ext b, toIfaceExpr ext r) | (b,r) <- prs]
1196 ---------------------
1197 toIfaceAlt ext (c,bs,r) = (toIfaceCon c, map getOccName bs, toIfaceExpr ext r)
1199 ---------------------
1200 toIfaceCon (DataAlt dc) | isTupleTyCon tc = IfaceTupleAlt (tupleTyConBoxity tc)
1201 | otherwise = IfaceDataAlt (getOccName dc)
1203 tc = dataConTyCon dc
1205 toIfaceCon (LitAlt l) = IfaceLitAlt l
1206 toIfaceCon DEFAULT = IfaceDefault
1208 ---------------------
1209 toIfaceApp ext (App f a) as = toIfaceApp ext f (a:as)
1210 toIfaceApp ext (Var v) as
1211 = case isDataConWorkId_maybe v of
1212 -- We convert the *worker* for tuples into IfaceTuples
1213 Just dc | isTupleTyCon tc && saturated
1214 -> IfaceTuple (tupleTyConBoxity tc) tup_args
1216 val_args = dropWhile isTypeArg as
1217 saturated = val_args `lengthIs` idArity v
1218 tup_args = map (toIfaceExpr ext) val_args
1219 tc = dataConTyCon dc
1221 other -> mkIfaceApps ext (toIfaceVar ext v) as
1223 toIfaceApp ext e as = mkIfaceApps ext (toIfaceExpr ext e) as
1225 mkIfaceApps ext f as = foldl (\f a -> IfaceApp f (toIfaceExpr ext a)) f as
1227 ---------------------
1228 toIfaceVar :: (Name -> IfaceExtName) -> Id -> IfaceExpr
1230 | Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType ext (idType v))
1231 -- Foreign calls have special syntax
1232 | isExternalName name = IfaceExt (ext name)
1233 | otherwise = IfaceLcl (nameOccName name)