-ifaceBinds :: IdSet -- These Ids are needed already
- -> [Id] -- Ids used at code-gen time; they have better pragma info!
- -> [CoreBind] -- In dependency order, later depend on earlier
- -> (Bag RdrNameHsDecl, IdSet) -- Set of Ids actually spat out
-
-ifaceBinds needed_ids final_ids binds
- = go needed_ids (reverse binds) emptyBag emptyVarSet
- -- Reverse so that later things will
- -- provoke earlier ones to be emitted
- where
- final_id_map = listToUFM [(id,id) | id <- final_ids]
- get_idinfo id = case lookupUFM final_id_map id of
- Just id' -> idInfo id'
- Nothing -> pprTrace "ifaceBinds not found:" (ppr id) $
- idInfo id
-
- -- The 'needed' set contains the Ids that are needed by earlier
- -- interface file emissions. If the Id isn't in this set, and isn't
- -- exported, there's no need to emit anything
- need_id needed_set id = id `elemVarSet` needed_set || isUserExportedId id
-
- go needed [] decls emitted
- | not (isEmptyVarSet needed) = pprTrace "ifaceBinds: free vars:"
- (sep (map ppr (varSetElems needed)))
- (decls, emitted)
- | otherwise = (decls, emitted)
-
- go needed (NonRec id rhs : binds) decls emitted
- | need_id needed id
- = if omitIfaceSigForId id then
- go (needed `delVarSet` id) binds decls (emitted `extendVarSet` id)
- else
- go ((needed `unionVarSet` extras) `delVarSet` id)
- binds
- (decl `consBag` decls)
- (emitted `extendVarSet` id)
- | otherwise
- = go needed binds decls emitted
- where
- (decl, extras) = ifaceId get_idinfo False id rhs
-
- -- Recursive groups are a bit more of a pain. We may only need one to
- -- start with, but it may call out the next one, and so on. So we
- -- have to look for a fixed point. We don't want necessarily them all,
- -- because without -O we may only need the first one (if we don't emit
- -- its unfolding)
- go needed (Rec pairs : binds) decls emitted
- = go needed' binds decls' emitted'
- where
- (new_decls, new_emitted, extras) = go_rec needed pairs
- decls' = new_decls `unionBags` decls
- needed' = (needed `unionVarSet` extras) `minusVarSet` mkVarSet (map fst pairs)
- emitted' = emitted `unionVarSet` new_emitted
-
- go_rec :: IdSet -> [(Id,CoreExpr)] -> (Bag RdrNameHsDecl, IdSet, IdSet)
- go_rec needed pairs
- | null decls = (emptyBag, emptyVarSet, emptyVarSet)
- | otherwise = (more_decls `unionBags` listToBag decls,
- more_emitted `unionVarSet` mkVarSet (map fst needed_prs),
- more_extras `unionVarSet` extras)
- where
- (needed_prs,leftover_prs) = partition is_needed pairs
- (decls, extras_s) = unzip [ifaceId get_idinfo True id rhs
- | (id,rhs) <- needed_prs, not (omitIfaceSigForId id)]
- extras = unionVarSets extras_s
- (more_decls, more_emitted, more_extras) = go_rec extras leftover_prs
- is_needed (id,_) = need_id needed id
-\end{code}
+addVersionInfo :: Maybe ModIface -- The old interface, read from M.hi
+ -> ModIface -- The new interface decls
+ -> (ModIface, Maybe SDoc) -- Nothing => no change; no need to write new Iface
+ -- Just mi => Here is the new interface to write
+ -- with correct version numbers
+
+-- NB: the fixities, declarations, rules are all assumed
+-- to be sorted by increasing order of hsDeclName, so that
+-- we can compare for equality