X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fiface%2FMkIface.lhs;h=cca8ab57d71f06a1892712994df91a1c5a4168a2;hp=0d4d163ad9fd8859ab8cd4500625ec12d37c2180;hb=6777144f7522d8db5935737e12fa451ca3211e6d;hpb=c8bee21ecc0952200e43ce353e6a660334a6f756 diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs index 0d4d163..cca8ab5 100644 --- a/compiler/iface/MkIface.lhs +++ b/compiler/iface/MkIface.lhs @@ -183,6 +183,7 @@ import Id import IdInfo import NewDemand import CoreSyn +import CoreFVs import Class import TyCon import DataCon @@ -194,6 +195,8 @@ import TcRnMonad import HscTypes import DynFlags +import VarEnv +import Var import Name import NameEnv import NameSet @@ -241,10 +244,11 @@ mkIface hsc_env maybe_old_iface mg_deps = deps, mg_rdr_env = rdr_env, mg_fix_env = fix_env, - mg_deprecs = src_deprecs }) + mg_deprecs = src_deprecs}) (ModDetails{ md_insts = insts, md_fam_insts = fam_insts, md_rules = rules, + md_vect_info = vect_info, md_types = type_env, md_exports = exports }) @@ -267,9 +271,10 @@ mkIface hsc_env maybe_old_iface ; fixities = [(occ,fix) | FixItem occ fix _ <- nameEnvElts fix_env] ; deprecs = mkIfaceDeprec src_deprecs - ; iface_rules = map coreRuleToIfaceRule rules + ; iface_rules = map (coreRuleToIfaceRule this_mod) rules ; iface_insts = map instanceToIfaceInst insts ; iface_fam_insts = map famInstToIfaceFamInst fam_insts + ; iface_vect_info = flattenVectInfo vect_info ; intermediate_iface = ModIface { mi_module = this_mod, @@ -284,6 +289,8 @@ mkIface hsc_env maybe_old_iface mi_fam_insts= sortLe le_fam_inst iface_fam_insts, mi_rules = sortLe le_rule iface_rules, + mi_vect_info = iface_vect_info, + mi_fixities = fixities, mi_deprecs = deprecs, mi_globals = Just rdr_env, @@ -332,6 +339,9 @@ mkIface hsc_env maybe_old_iface deliberatelyOmitted x = panic ("Deliberately omitted: " ++ x) ifFamInstTcName = ifaceTyConName . ifFamInstTyCon + flattenVectInfo (VectInfo ccVar) = + IfaceVectInfo [Var.varName v | (v, _) <- varEnvElts ccVar] + ----------------------------- writeIfaceFile :: DynFlags -> ModLocation -> ModIface -> IO () writeIfaceFile dflags location new_iface @@ -380,8 +390,7 @@ addVersionInfo addVersionInfo ver_fn Nothing new_iface new_decls -- No old interface, so definitely write a new one! - = (new_iface { mi_orphan = anyNothing ifInstOrph (mi_insts new_iface) - || anyNothing ifRuleOrph (mi_rules new_iface) + = (new_iface { mi_orphan = not (null orph_insts && null orph_rules) , mi_finsts = not . null $ mi_fam_insts new_iface , mi_decls = [(initialVersion, decl) | decl <- new_decls] , mi_ver_fn = mkIfaceVerCache (zip (repeat initialVersion) @@ -660,10 +669,6 @@ mkOrphMap get_key decls = (extendOccEnv_C (\ ds _ -> d:ds) non_orphs occ [d], orphs) | otherwise = (non_orphs, d:orphs) -anyNothing :: (a -> Maybe b) -> [a] -> Bool -anyNothing p [] = False -anyNothing p (x:xs) = isNothing (p x) || anyNothing p xs - ---------------------- mkIfaceDeprec :: Deprecations -> IfaceDeprecs mkIfaceDeprec NoDeprecs = NoDeprecs @@ -836,9 +841,8 @@ check_old_iface hsc_env mod_summary source_unchanged maybe_iface -- If the source has changed and we're in interactive mode, avoid reading -- an interface; just return the one we might have been supplied with. - ; ghc_mode <- getGhcMode - ; if (ghc_mode == Interactive || ghc_mode == JustTypecheck) - && not source_unchanged then + ; let dflags = hsc_dflags hsc_env + ; if not (isObjectTarget (hscTarget dflags)) && not source_unchanged then return (outOfDate, maybe_iface) else case maybe_iface of { @@ -1089,16 +1093,15 @@ tyThingToIfaceDecl (ATyCon tycon) where tyvars = tyConTyVars tycon (syn_isOpen, syn_tyki) = case synTyConRhs tycon of - OpenSynTyCon ki -> (True , ki) - SynonymTyCon ty -> (False, ty) + OpenSynTyCon ki _ -> (True , ki) + SynonymTyCon ty -> (False, ty) - ifaceConDecls (NewTyCon { data_con = con }) = + ifaceConDecls (NewTyCon { data_con = con }) = IfNewTyCon (ifaceConDecl con) - ifaceConDecls (DataTyCon { data_cons = cons }) = + ifaceConDecls (DataTyCon { data_cons = cons }) = IfDataTyCon (map ifaceConDecl cons) - ifaceConDecls OpenDataTyCon = IfOpenDataTyCon - ifaceConDecls OpenNewTyCon = IfOpenNewTyCon - ifaceConDecls AbstractTyCon = IfAbstractTyCon + ifaceConDecls OpenTyCon {} = IfOpenDataTyCon + ifaceConDecls AbstractTyCon = IfAbstractTyCon -- The last case happens when a TyCon has been trimmed during tidying -- Furthermore, tyThingToIfaceDecl is also used -- in TcRnDriver for GHCi, when browsing a module, in which case the @@ -1131,17 +1134,42 @@ getFS x = occNameFS (getOccName x) -------------------------- instanceToIfaceInst :: Instance -> IfaceInst instanceToIfaceInst ispec@(Instance { is_dfun = dfun_id, is_flag = oflag, - is_cls = cls, is_tcs = mb_tcs, - is_orph = orph }) - = IfaceInst { ifDFun = getName dfun_id, + is_cls = cls_name, is_tcs = mb_tcs }) + = ASSERT( cls_name == className cls ) + IfaceInst { ifDFun = dfun_name, ifOFlag = oflag, - ifInstCls = cls, + ifInstCls = cls_name, ifInstTys = map do_rough mb_tcs, ifInstOrph = orph } where do_rough Nothing = Nothing do_rough (Just n) = Just (toIfaceTyCon_name n) + dfun_name = idName dfun_id + mod = nameModule dfun_name + is_local name = nameIsLocalOrFrom mod name + + -- Compute orphanhood. See Note [Orphans] in IfaceSyn + (_, _, cls, tys) = tcSplitDFunTy (idType dfun_id) + -- Slightly awkward: we need the Class to get the fundeps + (tvs, fds) = classTvsFds cls + arg_names = [filterNameSet is_local (tyClsNamesOfType ty) | ty <- tys] + orph | is_local cls_name = Just (nameOccName cls_name) + | all isJust mb_ns = head mb_ns + | otherwise = Nothing + + mb_ns :: [Maybe OccName] -- One for each fundep; a locally-defined name + -- that is not in the "determined" arguments + mb_ns | null fds = [choose_one arg_names] + | otherwise = map do_one fds + do_one (ltvs,rtvs) = choose_one [ns | (tv,ns) <- tvs `zip` arg_names + , not (tv `elem` rtvs)] + + choose_one :: [NameSet] -> Maybe OccName + choose_one nss = case nameSetToList (unionManyNameSets nss) of + [] -> Nothing + (n:ns) -> Just (nameOccName n) + -------------------------- famInstToIfaceFamInst :: FamInst -> IfaceFamInst famInstToIfaceFamInst fi@(FamInst { fi_tycon = tycon, @@ -1154,6 +1182,22 @@ famInstToIfaceFamInst fi@(FamInst { fi_tycon = tycon, do_rough (Just n) = Just (toIfaceTyCon_name n) -------------------------- +toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) + (toIfaceType (idType id)) + prag_info + where + -- Stripped-down version of tcIfaceIdInfo + -- Change this if you want to export more IdInfo for + -- non-top-level Ids. Don't forget to change + -- CoreTidy.tidyLetBndr too! + -- + -- See Note [IdInfo on nested let-bindings] in IfaceSyn + id_info = idInfo id + inline_prag = inlinePragInfo id_info + prag_info | isAlwaysActive inline_prag = NoInfo + | otherwise = HasInfo [HsInline inline_prag] + +-------------------------- toIfaceIdInfo :: IdInfo -> [IfaceInfoItem] toIfaceIdInfo id_info = catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo, @@ -1205,14 +1249,14 @@ toIfaceIdInfo id_info | otherwise = Just (HsInline inline_prag) -------------------------- -coreRuleToIfaceRule :: CoreRule -> IfaceRule -coreRuleToIfaceRule (BuiltinRule { ru_fn = fn}) +coreRuleToIfaceRule :: Module -> CoreRule -> IfaceRule +coreRuleToIfaceRule mod (BuiltinRule { ru_fn = fn}) = pprTrace "toHsRule: builtin" (ppr fn) $ bogusIfaceRule fn -coreRuleToIfaceRule (Rule { ru_name = name, ru_fn = fn, - ru_act = act, ru_bndrs = bndrs, - ru_args = args, ru_rhs = rhs, ru_orph = orph }) +coreRuleToIfaceRule mod (Rule { ru_name = name, ru_fn = fn, + ru_act = act, ru_bndrs = bndrs, + ru_args = args, ru_rhs = rhs }) = IfaceRule { ifRuleName = name, ifActivation = act, ifRuleBndrs = map toIfaceBndr bndrs, ifRuleHead = fn, @@ -1227,6 +1271,17 @@ coreRuleToIfaceRule (Rule { ru_name = name, ru_fn = fn, do_arg (Type ty) = IfaceType (toIfaceType (deNoteType ty)) do_arg arg = toIfaceExpr arg + -- Compute orphanhood. See Note [Orphans] in IfaceSyn + -- A rule is an orphan only if none of the variables + -- mentioned on its left-hand side are locally defined + lhs_names = fn : nameSetToList (exprsFreeNames args) + -- No need to delete bndrs, because + -- exprsFreeNames finds only External names + + orph = case filter (nameIsLocalOrFrom mod) lhs_names of + (n:ns) -> Just (nameOccName n) + [] -> Nothing + bogusIfaceRule :: Name -> IfaceRule bogusIfaceRule id_name = IfaceRule { ifRuleName = FSLIT("bogus"), ifActivation = NeverActive, @@ -1251,8 +1306,8 @@ toIfaceNote InlineMe = IfaceInlineMe toIfaceNote (CoreNote s) = IfaceCoreNote s --------------------- -toIfaceBind (NonRec b r) = IfaceNonRec (toIfaceIdBndr b) (toIfaceExpr r) -toIfaceBind (Rec prs) = IfaceRec [(toIfaceIdBndr b, toIfaceExpr r) | (b,r) <- prs] +toIfaceBind (NonRec b r) = IfaceNonRec (toIfaceLetBndr b) (toIfaceExpr r) +toIfaceBind (Rec prs) = IfaceRec [(toIfaceLetBndr b, toIfaceExpr r) | (b,r) <- prs] --------------------- toIfaceAlt (c,bs,r) = (toIfaceCon c, map getFS bs, toIfaceExpr r)