From c6713d35dd3ed4de580a513bf4bd46f70d8cfe5d Mon Sep 17 00:00:00 2001 From: simonpj Date: Tue, 25 May 2004 08:09:42 +0000 Subject: [PATCH] [project @ 2004-05-25 08:09:37 by simonpj] ----------------------------------------------- Improve location info on unused-import warnings ----------------------------------------------- Improving the location involves plumbing the location of the import a bit more assiduously -- hence change to imp_mods in TcRnTypes --- ghc/compiler/deSugar/Desugar.lhs | 2 +- ghc/compiler/iface/MkIface.lhs | 4 ++-- ghc/compiler/rename/RnEnv.lhs | 11 +++++----- ghc/compiler/rename/RnNames.lhs | 40 +++++++++++++++------------------- ghc/compiler/typecheck/TcRnTypes.lhs | 2 +- 5 files changed, 28 insertions(+), 31 deletions(-) diff --git a/ghc/compiler/deSugar/Desugar.lhs b/ghc/compiler/deSugar/Desugar.lhs index 5f8192e..e2fe1f3 100644 --- a/ghc/compiler/deSugar/Desugar.lhs +++ b/ghc/compiler/deSugar/Desugar.lhs @@ -112,7 +112,7 @@ deSugar hsc_env mg_exports = exports, mg_deps = deps, mg_usages = usages, - mg_dir_imps = [m | (m,_) <- moduleEnvElts (imp_mods imports)], + mg_dir_imps = [m | (m,_,_) <- moduleEnvElts (imp_mods imports)], mg_rdr_env = rdr_env, mg_fix_env = fix_env, mg_deprecs = deprecs, diff --git a/ghc/compiler/iface/MkIface.lhs b/ghc/compiler/iface/MkIface.lhs index 1d77a03..224617e 100644 --- a/ghc/compiler/iface/MkIface.lhs +++ b/ghc/compiler/iface/MkIface.lhs @@ -702,8 +702,8 @@ mk_usage_info pit hpt dir_imp_mods dep_mods proto_used_names -- ToDo: do we need to sort into canonical order? import_all mod = case lookupModuleEnv dir_imp_mods mod of - Just (_,imp_all) -> isNothing imp_all - Nothing -> False + Just (_,imp_all,_) -> isNothing imp_all + Nothing -> False -- We want to create a Usage for a home module if -- a) we used something from; has something in used_names diff --git a/ghc/compiler/rename/RnEnv.lhs b/ghc/compiler/rename/RnEnv.lhs index 1185fe5..dfd2fda 100644 --- a/ghc/compiler/rename/RnEnv.lhs +++ b/ghc/compiler/rename/RnEnv.lhs @@ -54,7 +54,7 @@ import Module ( Module, ModuleName, moduleName, mkHomeModule ) import PrelNames ( mkUnboundName, rOOT_MAIN_Name, iNTERACTIVE ) import UniqSupply import BasicTypes ( IPName, mapIPName ) -import SrcLoc ( srcSpanStart, Located(..), eqLocated, unLoc, +import SrcLoc ( SrcSpan, srcSpanStart, Located(..), eqLocated, unLoc, srcLocSpan ) import Outputable import ListSetOps ( removeDups ) @@ -658,12 +658,13 @@ mapFvRn f xs = mappM f xs `thenM` \ stuff -> %************************************************************************ \begin{code} -warnUnusedModules :: [ModuleName] -> RnM () +warnUnusedModules :: [(ModuleName,SrcSpan)] -> RnM () warnUnusedModules mods - = ifOptM Opt_WarnUnusedImports (mappM_ (addWarn . unused_mod) mods) + = ifOptM Opt_WarnUnusedImports (mappM_ bleat mods) where - unused_mod m = vcat [ptext SLIT("Module") <+> quotes (ppr m) <+> - text "is imported, but nothing from it is used", + bleat (mod,loc) = addSrcSpan loc $ addWarn (mk_warn mod) + mk_warn m = vcat [ptext SLIT("Module") <+> quotes (ppr m) <+> + text "is imported, but nothing from it is used", parens (ptext SLIT("except perhaps instances visible in") <+> quotes (ppr m))] diff --git a/ghc/compiler/rename/RnNames.lhs b/ghc/compiler/rename/RnNames.lhs index 1604915..f3fe011 100644 --- a/ghc/compiler/rename/RnNames.lhs +++ b/ghc/compiler/rename/RnNames.lhs @@ -50,7 +50,7 @@ import RdrName ( RdrName, rdrNameOcc, setRdrNameSpace, import Outputable import Maybes ( isJust, isNothing, catMaybes, mapCatMaybes, seqMaybe ) import SrcLoc ( noSrcLoc, Located(..), mkGeneralSrcSpan, - unLoc, noLoc, srcLocSpan ) + unLoc, noLoc, srcLocSpan, SrcSpan ) import BasicTypes ( DeprecTxt ) import ListSetOps ( removeDups ) import Util ( sortLt, notNull, isSingleton ) @@ -228,7 +228,7 @@ importsFromImportDecl this_mod imports = ImportAvails { imp_qual = unitModuleEnvByName qual_mod_name avail_env, imp_env = avail_env, - imp_mods = unitModuleEnv imp_mod (imp_mod, import_all), + imp_mods = unitModuleEnv imp_mod (imp_mod, import_all, loc), imp_orphs = orphans, imp_dep_mods = mkModDeps dependent_mods, imp_dep_pkgs = dependent_pkgs } @@ -852,8 +852,7 @@ reportUnusedNames gbl_env -- We've carefully preserved the provenance so that we can -- construct minimal imports that import the name by (one of) -- the same route(s) as the programmer originally did. - add_name (GRE {gre_name = n, - gre_prov = Imported imp_specs _}) acc + add_name (GRE {gre_name = n, gre_prov = Imported imp_specs _}) acc = addToFM_C plusAvailEnv acc (is_mod (head imp_specs)) (unitAvailEnv (mk_avail n (nameParent_maybe n))) add_name other acc @@ -864,38 +863,35 @@ reportUnusedNames gbl_env mk_avail n Nothing | isTcOcc (nameOccName n) = AvailTC n [n] | otherwise = Avail n - add_inst_mod m acc - | m `elemFM` acc = acc -- We import something already - | otherwise = addToFM acc m emptyAvailEnv + add_inst_mod (mod,_,_) acc + | mod_name `elemFM` acc = acc -- We import something already + | otherwise = addToFM acc mod_name emptyAvailEnv + where + mod_name = moduleName mod -- Add an empty collection of imports for a module -- from which we have sucked only instance decls imports = tcg_imports gbl_env - direct_import_mods :: [ModuleName] - direct_import_mods = map (moduleName . fst) - (moduleEnvElts (imp_mods imports)) - - hasEmptyImpList :: ModuleName -> Bool - hasEmptyImpList m = - case lookupModuleEnvByName (imp_mods imports) m of - Just (_,Just x) -> not x - _ -> False + direct_import_mods :: [(Module, Maybe Bool, SrcSpan)] + -- See the type of the imp_mods for this triple + direct_import_mods = moduleEnvElts (imp_mods imports) -- unused_imp_mods are the directly-imported modules -- that are not mentioned in minimal_imports1 -- [Note: not 'minimal_imports', because that includes directly-imported -- modules even if we use nothing from them; see notes above] - unused_imp_mods = [m | m <- direct_import_mods, - isNothing (lookupFM minimal_imports1 m), - m /= pRELUDE_Name, - not (hasEmptyImpList m)] - -- hasEmptyImpList arranges not to complain about + unused_imp_mods = [(mod_name,loc) | (mod,imp,loc) <- direct_import_mods, + let mod_name = moduleName mod, + not (mod_name `elemFM` minimal_imports1), + mod_name /= pRELUDE_Name, + imp /= Just False] + -- The Just False part is not to complain about -- import M (), which is an idiom for importing -- instance declarations module_unused :: ModuleName -> Bool - module_unused mod = mod `elem` unused_imp_mods + module_unused mod = any (((==) mod) . fst) unused_imp_mods --------------------- warnDuplicateImports :: [GlobalRdrElt] -> RnM () diff --git a/ghc/compiler/typecheck/TcRnTypes.lhs b/ghc/compiler/typecheck/TcRnTypes.lhs index e5a8e1c..a915651 100644 --- a/ghc/compiler/typecheck/TcRnTypes.lhs +++ b/ghc/compiler/typecheck/TcRnTypes.lhs @@ -443,7 +443,7 @@ data ImportAvails -- combine stuff coming from different (unqualified) -- imports of the same module - imp_mods :: ModuleEnv (Module, Maybe Bool), + imp_mods :: ModuleEnv (Module, Maybe Bool, SrcSpan), -- Domain is all directly-imported modules -- Maybe value answers the question "is the import restricted?" -- Nothing => unrestricted import (e.g., "import Foo") -- 1.7.10.4