X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fiface%2FMkIface.lhs;h=4ab116171d9034f6cf37bb26bac4b962418d0683;hb=7fc749a43b4b6b85d234fa95d4928648259584f4;hp=99854d44aad356277660f2d4784ea0d79f3cda9e;hpb=daccbd2600f8c5e88291a85fdf81289b2c1fc791;p=ghc-hetmet.git diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs index 99854d4..4ab1161 100644 --- a/compiler/iface/MkIface.lhs +++ b/compiler/iface/MkIface.lhs @@ -4,6 +4,13 @@ % \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module MkIface ( mkUsageInfo, -- Construct the usage info for a module @@ -193,7 +200,7 @@ import InstEnv import FamInstEnv import TcRnMonad import HscTypes - +import Finder import DynFlags import VarEnv import Var @@ -314,7 +321,7 @@ mkIface hsc_env maybe_old_iface -- Add version information ; ext_ver_fn = mkParentVerFun hsc_env eps ; (new_iface, no_change_at_all, pp_diffs, pp_orphs) - = _scc_ "versioninfo" + = {-# SCC "versioninfo" #-} addVersionInfo ext_ver_fn maybe_old_iface intermediate_iface decls } @@ -705,7 +712,7 @@ bump_unless False v = bumpVersion v \begin{code} mkUsageInfo :: HscEnv - -> ModuleEnv (Module, Bool, SrcSpan) + -> ModuleEnv (Module, [(ModuleName, Bool, SrcSpan)]) -> [(ModuleName, IsBootInterface)] -> NameSet -> IO [Usage] mkUsageInfo hsc_env dir_imp_mods dep_mods used_names @@ -717,6 +724,12 @@ mkUsageInfo hsc_env dir_imp_mods dep_mods used_names -- don't get evaluated for a while and we can end up hanging on to -- the entire collection of Ifaces. +mk_usage_info :: PackageIfaceTable + -> HscEnv + -> ModuleEnv (Module, [(ModuleName, Bool, SrcSpan)]) + -> [(ModuleName, IsBootInterface)] + -> NameSet + -> [Usage] mk_usage_info pit hsc_env dir_imp_mods dep_mods used_names = mapCatMaybes mkUsage dep_mods -- ToDo: do we need to sort into canonical order? @@ -739,8 +752,8 @@ mk_usage_info pit hsc_env dir_imp_mods dep_mods used_names add_item occs _ = occ:occs depend_on_exports mod = case lookupModuleEnv dir_imp_mods mod of - Just (_,no_imp,_) -> not no_imp - Nothing -> True + Just (_, xs) -> any (\(_, no_imp, _) -> not no_imp) xs + Nothing -> True -- We want to create a Usage for a home module if -- a) we used something from; has something in used_names @@ -893,7 +906,7 @@ check_old_iface hsc_env mod_summary source_unchanged maybe_iface case maybe_iface of { Just old_iface -> do -- Use the one we already have { traceIf (text "We already have the old interface for" <+> ppr (ms_mod mod_summary)) - ; recomp <- checkVersions hsc_env source_unchanged old_iface + ; recomp <- checkVersions hsc_env source_unchanged mod_summary old_iface ; return (recomp, Just old_iface) } ; Nothing -> do @@ -912,9 +925,10 @@ check_old_iface hsc_env mod_summary source_unchanged maybe_iface -- We have got the old iface; check its versions { traceIf (text "Read the interface file" <+> text iface_path) - ; recomp <- checkVersions hsc_env source_unchanged iface + ; recomp <- checkVersions hsc_env source_unchanged mod_summary iface ; returnM (recomp, Just iface) }}}}} + \end{code} @recompileRequired@ is called from the HscMain. It checks whether @@ -929,15 +943,19 @@ outOfDate = True -- Recompile required checkVersions :: HscEnv -> Bool -- True <=> source unchanged + -> ModSummary -> ModIface -- Old interface -> IfG RecompileRequired -checkVersions hsc_env source_unchanged iface +checkVersions hsc_env source_unchanged mod_summary iface | not source_unchanged = returnM outOfDate | otherwise = do { traceHiDiffs (text "Considering whether compilation is required for" <+> ppr (mi_module iface) <> colon) + ; recomp <- checkDependencies hsc_env mod_summary iface + ; if recomp then return outOfDate else do { + -- Source code unchanged and no errors yet... carry on -- First put the dependent-module info, read from the old interface, into the envt, @@ -950,16 +968,63 @@ checkVersions hsc_env source_unchanged iface -- We do this regardless of compilation mode, although in --make mode -- all the dependent modules should be in the HPT already, so it's -- quite redundant - ; updateEps_ $ \eps -> eps { eps_is_boot = mod_deps } + updateEps_ $ \eps -> eps { eps_is_boot = mod_deps } ; let this_pkg = thisPackage (hsc_dflags hsc_env) ; checkList [checkModUsage this_pkg u | u <- mi_usages iface] - } + }} where -- This is a bit of a hack really mod_deps :: ModuleNameEnv (ModuleName, IsBootInterface) mod_deps = mkModDeps (dep_mods (mi_deps iface)) + +-- If the direct imports of this module are resolved to targets that +-- are not among the dependencies of the previous interface file, +-- then we definitely need to recompile. This catches cases like +-- - an exposed package has been upgraded +-- - we are compiling with different package flags +-- - a home module that was shadowing a package module has been removed +-- - a new home module has been added that shadows a package module +-- See bug #1372. +-- +-- Returns True if recompilation is required. +checkDependencies :: HscEnv -> ModSummary -> ModIface -> IfG RecompileRequired +checkDependencies hsc_env summary iface + = orM (map dep_missing (ms_imps summary ++ ms_srcimps summary)) + where + prev_dep_mods = dep_mods (mi_deps iface) + prev_dep_pkgs = dep_pkgs (mi_deps iface) + + this_pkg = thisPackage (hsc_dflags hsc_env) + + orM = foldr f (return False) + where f m rest = do b <- m; if b then return True else rest + + dep_missing (L _ mod) = do + find_res <- ioToIOEnv $ findImportedModule hsc_env mod Nothing + case find_res of + Found _ mod + | pkg == this_pkg + -> if moduleName mod `notElem` map fst prev_dep_mods + then do traceHiDiffs $ + text "imported module " <> quotes (ppr mod) <> + text " not among previous dependencies" + return outOfDate + else + return upToDate + | otherwise + -> if pkg `notElem` prev_dep_pkgs + then do traceHiDiffs $ + text "imported module " <> quotes (ppr mod) <> + text " is from package " <> quotes (ppr pkg) <> + text ", which is not among previous dependencies" + return outOfDate + else + return upToDate + where pkg = modulePackageId mod + _otherwise -> return outOfDate + checkModUsage :: PackageId ->Usage -> IfG RecompileRequired -- Given the usage information extracted from the old -- M.hi file for the module being compiled, figure out @@ -1160,7 +1225,7 @@ tyThingToIfaceDecl (ATyCon tycon) ifConUnivTvs = toIfaceTvBndrs (dataConUnivTyVars data_con), ifConExTvs = toIfaceTvBndrs (dataConExTyVars data_con), ifConEqSpec = to_eq_spec (dataConEqSpec data_con), - ifConCtxt = toIfaceContext (dataConTheta data_con), + ifConCtxt = toIfaceContext (dataConEqTheta data_con ++ dataConDictTheta data_con), ifConArgTys = map toIfaceType (dataConOrigArgTys data_con), ifConFields = map getOccName (dataConFieldLabels data_con),